diff options
author | Mai <mathew1800@gmail.com> | 2022-11-09 03:25:53 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-11-09 03:25:53 +0000 |
commit | ad9e5bc5b7374d87d0b4f47ad7b1a6def78132c8 (patch) | |
tree | 58c88d7ca923789c9a5d5518d2af1e413887f451 /src/core/hle/kernel/kernel.cpp | |
parent | dc520a487d17ac377b26ee531d48f5ed64c42851 (diff) | |
parent | 6a0d8b2aa154921e8328dfab9450510ad8e1b5c8 (diff) |
Merge pull request #9199 from liamwhite/service-oops
service_thread: fix deletion
Diffstat (limited to 'src/core/hle/kernel/kernel.cpp')
-rw-r--r-- | src/core/hle/kernel/kernel.cpp | 42 |
1 files changed, 20 insertions, 22 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 47b760a9cb..abff140794 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -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); } |