mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 02:34:11 +01:00 
			
		
		
		
	service_thread: fix deletion
This commit is contained in:
		
							parent
							
								
									dc520a487d
								
							
						
					
					
						commit
						6a0d8b2aa1
					
				| @ -27,16 +27,12 @@ namespace Kernel { | ||||
| 
 | ||||
| SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_, | ||||
|                                              ServiceThreadType thread_type) | ||||
|     : kernel{kernel_} { | ||||
|     if (thread_type == ServiceThreadType::CreateNew) { | ||||
|         service_thread = kernel.CreateServiceThread(service_name_); | ||||
|     } else { | ||||
|         service_thread = kernel.GetDefaultServiceThread(); | ||||
|     } | ||||
| } | ||||
|     : kernel{kernel_}, service_thread{thread_type == ServiceThreadType::CreateNew | ||||
|                                           ? kernel.CreateServiceThread(service_name_) | ||||
|                                           : kernel.GetDefaultServiceThread()} {} | ||||
| 
 | ||||
| SessionRequestHandler::~SessionRequestHandler() { | ||||
|     kernel.ReleaseServiceThread(service_thread.lock()); | ||||
|     kernel.ReleaseServiceThread(service_thread); | ||||
| } | ||||
| 
 | ||||
| void SessionRequestHandler::AcceptSession(KServerPort* server_port) { | ||||
| @ -49,7 +45,7 @@ void SessionRequestHandler::AcceptSession(KServerPort* server_port) { | ||||
| void SessionRequestHandler::RegisterSession(KServerSession* server_session, | ||||
|                                             std::shared_ptr<SessionRequestManager> manager) { | ||||
|     manager->SetSessionHandler(shared_from_this()); | ||||
|     service_thread.lock()->RegisterServerSession(server_session, manager); | ||||
|     service_thread.RegisterServerSession(server_session, manager); | ||||
|     server_session->Close(); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -82,13 +82,13 @@ public: | ||||
|     void RegisterSession(KServerSession* server_session, | ||||
|                          std::shared_ptr<SessionRequestManager> manager); | ||||
| 
 | ||||
|     std::weak_ptr<ServiceThread> GetServiceThread() const { | ||||
|     ServiceThread& GetServiceThread() const { | ||||
|         return service_thread; | ||||
|     } | ||||
| 
 | ||||
| protected: | ||||
|     KernelCore& kernel; | ||||
|     std::weak_ptr<ServiceThread> service_thread; | ||||
|     ServiceThread& service_thread; | ||||
| }; | ||||
| 
 | ||||
| using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; | ||||
| @ -154,7 +154,7 @@ public: | ||||
|         session_handler = std::move(handler); | ||||
|     } | ||||
| 
 | ||||
|     std::weak_ptr<ServiceThread> GetServiceThread() const { | ||||
|     ServiceThread& GetServiceThread() const { | ||||
|         return session_handler->GetServiceThread(); | ||||
|     } | ||||
| 
 | ||||
|  | ||||
| @ -93,7 +93,7 @@ struct KernelCore::Impl { | ||||
| 
 | ||||
|         RegisterHostThread(); | ||||
| 
 | ||||
|         default_service_thread = CreateServiceThread(kernel, "DefaultServiceThread"); | ||||
|         default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread"); | ||||
|     } | ||||
| 
 | ||||
|     void InitializeCores() { | ||||
| @ -779,33 +779,31 @@ struct KernelCore::Impl { | ||||
|         search->second(system.ServiceManager(), server_port); | ||||
|     } | ||||
| 
 | ||||
|     std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(KernelCore& kernel, | ||||
|                                                              const std::string& name) { | ||||
|         auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, name); | ||||
|     Kernel::ServiceThread& CreateServiceThread(KernelCore& kernel, const std::string& name) { | ||||
|         auto* ptr = new ServiceThread(kernel, name); | ||||
| 
 | ||||
|         service_threads_manager.QueueWork( | ||||
|             [this, service_thread]() { service_threads.emplace(service_thread); }); | ||||
|             [this, ptr]() { service_threads.emplace(ptr, std::unique_ptr<ServiceThread>(ptr)); }); | ||||
| 
 | ||||
|         return service_thread; | ||||
|         return *ptr; | ||||
|     } | ||||
| 
 | ||||
|     void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { | ||||
|         if (auto strong_ptr = service_thread.lock()) { | ||||
|             if (strong_ptr == default_service_thread.lock()) { | ||||
|                 // Nothing to do here, the service is using default_service_thread, which will be
 | ||||
|                 // released on shutdown.
 | ||||
|                 return; | ||||
|             } | ||||
|     void ReleaseServiceThread(Kernel::ServiceThread& service_thread) { | ||||
|         auto* ptr = &service_thread; | ||||
| 
 | ||||
|             service_threads_manager.QueueWork( | ||||
|                 [this, strong_ptr{std::move(strong_ptr)}]() { service_threads.erase(strong_ptr); }); | ||||
|         if (ptr == default_service_thread) { | ||||
|             // Nothing to do here, the service is using default_service_thread, which will be
 | ||||
|             // released on shutdown.
 | ||||
|             return; | ||||
|         } | ||||
| 
 | ||||
|         service_threads_manager.QueueWork([this, ptr]() { service_threads.erase(ptr); }); | ||||
|     } | ||||
| 
 | ||||
|     void ClearServiceThreads() { | ||||
|         service_threads_manager.QueueWork([this] { | ||||
|             service_threads.clear(); | ||||
|             default_service_thread.reset(); | ||||
|             default_service_thread = nullptr; | ||||
|             service_thread_barrier.Sync(); | ||||
|         }); | ||||
|         service_thread_barrier.Sync(); | ||||
| @ -881,8 +879,8 @@ struct KernelCore::Impl { | ||||
|     std::unique_ptr<KMemoryLayout> memory_layout; | ||||
| 
 | ||||
|     // Threads used for services
 | ||||
|     std::unordered_set<std::shared_ptr<ServiceThread>> service_threads; | ||||
|     std::weak_ptr<ServiceThread> default_service_thread; | ||||
|     std::unordered_map<ServiceThread*, std::unique_ptr<ServiceThread>> service_threads; | ||||
|     ServiceThread* default_service_thread{}; | ||||
|     Common::ThreadWorker service_threads_manager; | ||||
|     Common::Barrier service_thread_barrier; | ||||
| 
 | ||||
| @ -1239,15 +1237,15 @@ void KernelCore::ExitSVCProfile() { | ||||
|     MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]); | ||||
| } | ||||
| 
 | ||||
| std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) { | ||||
| Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) { | ||||
|     return impl->CreateServiceThread(*this, name); | ||||
| } | ||||
| 
 | ||||
| std::weak_ptr<Kernel::ServiceThread> KernelCore::GetDefaultServiceThread() const { | ||||
|     return impl->default_service_thread; | ||||
| Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const { | ||||
|     return *impl->default_service_thread; | ||||
| } | ||||
| 
 | ||||
| void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { | ||||
| void KernelCore::ReleaseServiceThread(Kernel::ServiceThread& service_thread) { | ||||
|     impl->ReleaseServiceThread(service_thread); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -309,24 +309,24 @@ public: | ||||
|      * See GetDefaultServiceThread. | ||||
|      * @param name String name for the ServerSession creating this thread, used for debug | ||||
|      * purposes. | ||||
|      * @returns The a weak pointer newly created service thread. | ||||
|      * @returns A reference to the newly created service thread. | ||||
|      */ | ||||
|     std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(const std::string& name); | ||||
|     Kernel::ServiceThread& CreateServiceThread(const std::string& name); | ||||
| 
 | ||||
|     /**
 | ||||
|      * Gets the default host service thread, which executes HLE service requests. Unless service | ||||
|      * requests need to block on the host, the default service thread should be used in favor of | ||||
|      * creating a new service thread. | ||||
|      * @returns The a weak pointer for the default service thread. | ||||
|      * @returns A reference to the default service thread. | ||||
|      */ | ||||
|     std::weak_ptr<Kernel::ServiceThread> GetDefaultServiceThread() const; | ||||
|     Kernel::ServiceThread& GetDefaultServiceThread() const; | ||||
| 
 | ||||
|     /**
 | ||||
|      * Releases a HLE service thread, instructing KernelCore to free it. This should be called when | ||||
|      * the ServerSession associated with the thread is destroyed. | ||||
|      * @param service_thread Service thread to release. | ||||
|      */ | ||||
|     void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread); | ||||
|     void ReleaseServiceThread(Kernel::ServiceThread& service_thread); | ||||
| 
 | ||||
|     /// Workaround for single-core mode when preempting threads while idle.
 | ||||
|     bool IsPhantomModeForSingleCore() const; | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user