Merge pull request #7711 from bunnei/fix-service-thread-race-v2
hle: kernel: Fix service_threads access to be thread safe V2.
This commit is contained in:
		| @@ -51,7 +51,8 @@ namespace Kernel { | ||||
|  | ||||
| struct KernelCore::Impl { | ||||
|     explicit Impl(Core::System& system_, KernelCore& kernel_) | ||||
|         : time_manager{system_}, object_list_container{kernel_}, system{system_} {} | ||||
|         : time_manager{system_}, object_list_container{kernel_}, | ||||
|           service_threads_manager{1, "yuzu:ServiceThreadsManager"}, system{system_} {} | ||||
|  | ||||
|     void SetMulticore(bool is_multi) { | ||||
|         is_multicore = is_multi; | ||||
| @@ -707,24 +708,22 @@ struct KernelCore::Impl { | ||||
|     std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(KernelCore& kernel, | ||||
|                                                              const std::string& name) { | ||||
|         auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, 1, name); | ||||
|         { | ||||
|             std::lock_guard lk(service_threads_lock); | ||||
|             service_threads.emplace(service_thread); | ||||
|         } | ||||
|  | ||||
|         service_threads_manager.QueueWork( | ||||
|             [this, service_thread]() { service_threads.emplace(service_thread); }); | ||||
|  | ||||
|         return service_thread; | ||||
|     } | ||||
|  | ||||
|     void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { | ||||
|         auto strong_ptr = service_thread.lock(); | ||||
|         { | ||||
|             std::lock_guard lk(service_threads_lock); | ||||
|             service_threads.erase(strong_ptr); | ||||
|         if (auto strong_ptr = service_thread.lock()) { | ||||
|             service_threads_manager.QueueWork( | ||||
|                 [this, strong_ptr{std::move(strong_ptr)}]() { service_threads.erase(strong_ptr); }); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     void ClearServiceThreads() { | ||||
|         std::lock_guard lk(service_threads_lock); | ||||
|         service_threads.clear(); | ||||
|         service_threads_manager.QueueWork([this]() { service_threads.clear(); }); | ||||
|     } | ||||
|  | ||||
|     std::mutex server_ports_lock; | ||||
| @@ -732,7 +731,6 @@ struct KernelCore::Impl { | ||||
|     std::mutex registered_objects_lock; | ||||
|     std::mutex registered_in_use_objects_lock; | ||||
|     std::mutex dummy_thread_lock; | ||||
|     std::mutex service_threads_lock; | ||||
|  | ||||
|     std::atomic<u32> next_object_id{0}; | ||||
|     std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; | ||||
| @@ -783,6 +781,7 @@ struct KernelCore::Impl { | ||||
|  | ||||
|     // Threads used for services | ||||
|     std::unordered_set<std::shared_ptr<Kernel::ServiceThread>> service_threads; | ||||
|     Common::ThreadWorker service_threads_manager; | ||||
|  | ||||
|     std::array<KThread*, Core::Hardware::NUM_CPU_CORES> suspend_threads; | ||||
|     std::array<Core::CPUInterruptHandler, Core::Hardware::NUM_CPU_CORES> interrupts{}; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 bunnei
					bunnei