Merge pull request #7699 from bunnei/fix-service-thread-race

hle: kernel: Fix service_threads access to be thread safe.
This commit is contained in:
Mai M 2022-01-14 00:46:16 -05:00 committed by GitHub
commit b2d45a4072
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -121,7 +121,7 @@ struct KernelCore::Impl {
object_list_container.Finalize(); object_list_container.Finalize();
// Ensures all service threads gracefully shutdown. // Ensures all service threads gracefully shutdown.
service_threads.clear(); ClearServiceThreads();
next_object_id = 0; next_object_id = 0;
next_kernel_process_id = KProcess::InitialKIPIDMin; next_kernel_process_id = KProcess::InitialKIPIDMin;
@ -704,11 +704,35 @@ struct KernelCore::Impl {
return port; return port;
} }
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);
}
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);
}
}
void ClearServiceThreads() {
std::lock_guard lk(service_threads_lock);
service_threads.clear();
}
std::mutex server_ports_lock; std::mutex server_ports_lock;
std::mutex server_sessions_lock; std::mutex server_sessions_lock;
std::mutex registered_objects_lock; std::mutex registered_objects_lock;
std::mutex registered_in_use_objects_lock; std::mutex registered_in_use_objects_lock;
std::mutex dummy_thread_lock; std::mutex dummy_thread_lock;
std::mutex service_threads_lock;
std::atomic<u32> next_object_id{0}; std::atomic<u32> next_object_id{0};
std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin}; std::atomic<u64> next_kernel_process_id{KProcess::InitialKIPIDMin};
@ -1099,15 +1123,11 @@ void KernelCore::ExitSVCProfile() {
} }
std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) { std::weak_ptr<Kernel::ServiceThread> KernelCore::CreateServiceThread(const std::string& name) {
auto service_thread = std::make_shared<Kernel::ServiceThread>(*this, 1, name); return impl->CreateServiceThread(*this, name);
impl->service_threads.emplace(service_thread);
return service_thread;
} }
void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) { void KernelCore::ReleaseServiceThread(std::weak_ptr<Kernel::ServiceThread> service_thread) {
if (auto strong_ptr = service_thread.lock()) { impl->ReleaseServiceThread(service_thread);
impl->service_threads.erase(strong_ptr);
}
} }
Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() {