diff options
| author | 2022-01-14 00:46:16 -0500 | |
|---|---|---|
| committer | 2022-01-14 00:46:16 -0500 | |
| commit | b2d45a4072cbce22eaba58700982306ba1a7e605 (patch) | |
| tree | 8263584ca2e8e954035dfd45115fac0dd9c7bbfa /src/core/hle/kernel/kernel.cpp | |
| parent | Merge pull request #7698 from bunnei/mem-code-memory-updates (diff) | |
| parent | hle: kernel: Fix service_threads access to be thread safe. (diff) | |
| download | yuzu-b2d45a4072cbce22eaba58700982306ba1a7e605.tar.gz yuzu-b2d45a4072cbce22eaba58700982306ba1a7e605.tar.xz yuzu-b2d45a4072cbce22eaba58700982306ba1a7e605.zip | |
Merge pull request #7699 from bunnei/fix-service-thread-race
hle: kernel: Fix service_threads access to be thread safe.
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 1225e1fba..e1e17db13 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -121,7 +121,7 @@ struct KernelCore::Impl { | |||
| 121 | object_list_container.Finalize(); | 121 | object_list_container.Finalize(); |
| 122 | 122 | ||
| 123 | // Ensures all service threads gracefully shutdown. | 123 | // Ensures all service threads gracefully shutdown. |
| 124 | service_threads.clear(); | 124 | ClearServiceThreads(); |
| 125 | 125 | ||
| 126 | next_object_id = 0; | 126 | next_object_id = 0; |
| 127 | next_kernel_process_id = KProcess::InitialKIPIDMin; | 127 | next_kernel_process_id = KProcess::InitialKIPIDMin; |
| @@ -704,11 +704,35 @@ struct KernelCore::Impl { | |||
| 704 | return port; | 704 | return port; |
| 705 | } | 705 | } |
| 706 | 706 | ||
| 707 | std::weak_ptr<Kernel::ServiceThread> CreateServiceThread(KernelCore& kernel, | ||
| 708 | const std::string& name) { | ||
| 709 | auto service_thread = std::make_shared<Kernel::ServiceThread>(kernel, 1, name); | ||
| 710 | { | ||
| 711 | std::lock_guard lk(service_threads_lock); | ||
| 712 | service_threads.emplace(service_thread); | ||
| 713 | } | ||
| 714 | return service_thread; | ||
| 715 | } | ||
| 716 | |||
| 717 | void ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { | ||
| 718 | auto strong_ptr = service_thread.lock(); | ||
| 719 | { | ||
| 720 | std::lock_guard lk(service_threads_lock); | ||
| 721 | service_threads.erase(strong_ptr); | ||
| 722 | } | ||
| 723 | } | ||
| 724 | |||
| 725 | void ClearServiceThreads() { | ||
| 726 | std::lock_guard lk(service_threads_lock); | ||
| 727 | service_threads.clear(); | ||
| 728 | } | ||
| 729 | |||
| 707 | std::mutex server_ports_lock; | 730 | std::mutex server_ports_lock; |
| 708 | std::mutex server_sessions_lock; | 731 | std::mutex server_sessions_lock; |
| 709 | std::mutex registered_objects_lock; | 732 | std::mutex registered_objects_lock; |
| 710 | std::mutex registered_in_use_objects_lock; | 733 | std::mutex registered_in_use_objects_lock; |
| 711 | std::mutex dummy_thread_lock; | 734 | std::mutex dummy_thread_lock; |
| 735 | std::mutex service_threads_lock; | ||
| 712 | 736 | ||
| 713 | std::atomic<u32> next_object_id{0}; | 737 | std::atomic<u32> next_object_id{0}; |
| 714 | std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; | 738 | std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; |
| @@ -1099,15 +1123,11 @@ void KernelCore::ExitSVCProfile() { | |||
| 1099 | } | 1123 | } |
| 1100 | 1124 | ||
| 1101 | std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) { | 1125 | std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) { |
| 1102 | auto service_thread = std::make_shared<Kernel::ServiceThread>(*this, 1, name); | 1126 | return impl->CreateServiceThread(*this, name); |
| 1103 | impl->service_threads.emplace(service_thread); | ||
| 1104 | return service_thread; | ||
| 1105 | } | 1127 | } |
| 1106 | 1128 | ||
| 1107 | void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { | 1129 | void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { |
| 1108 | if (auto strong_ptr = service_thread.lock()) { | 1130 | impl->ReleaseServiceThread(service_thread); |
| 1109 | impl->service_threads.erase(strong_ptr); | ||
| 1110 | } | ||
| 1111 | } | 1131 | } |
| 1112 | 1132 | ||
| 1113 | Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { | 1133 | Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { |