From 6a0d8b2aa154921e8328dfab9450510ad8e1b5c8 Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 6 Nov 2022 19:43:38 -0500 Subject: service_thread: fix deletion --- src/core/hle/kernel/hle_ipc.cpp | 14 +++++--------- src/core/hle/kernel/hle_ipc.h | 6 +++--- src/core/hle/kernel/kernel.cpp | 42 ++++++++++++++++++++--------------------- src/core/hle/kernel/kernel.h | 10 +++++----- 4 files changed, 33 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index fd354d484..06010b8d1 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -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 manager) { manager->SetSessionHandler(shared_from_this()); - service_thread.lock()->RegisterServerSession(server_session, manager); + service_thread.RegisterServerSession(server_session, manager); server_session->Close(); } diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 67da8e7e1..d87be72d6 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -82,13 +82,13 @@ public: void RegisterSession(KServerSession* server_session, std::shared_ptr manager); - std::weak_ptr GetServiceThread() const { + ServiceThread& GetServiceThread() const { return service_thread; } protected: KernelCore& kernel; - std::weak_ptr service_thread; + ServiceThread& service_thread; }; using SessionRequestHandlerWeakPtr = std::weak_ptr; @@ -154,7 +154,7 @@ public: session_handler = std::move(handler); } - std::weak_ptr GetServiceThread() const { + ServiceThread& GetServiceThread() const { return session_handler->GetServiceThread(); } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 47b760a9c..abff14079 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 CreateServiceThread(KernelCore& kernel, - const std::string& name) { - auto service_thread = std::make_shared(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(ptr)); }); - return service_thread; + return *ptr; } - void ReleaseServiceThread(std::weak_ptr 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 memory_layout; // Threads used for services - std::unordered_set> service_threads; - std::weak_ptr default_service_thread; + std::unordered_map> 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 KernelCore::CreateServiceThread(const std::string& name) { +Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) { return impl->CreateServiceThread(*this, name); } -std::weak_ptr KernelCore::GetDefaultServiceThread() const { - return impl->default_service_thread; +Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const { + return *impl->default_service_thread; } -void KernelCore::ReleaseServiceThread(std::weak_ptr service_thread) { +void KernelCore::ReleaseServiceThread(Kernel::ServiceThread& service_thread) { impl->ReleaseServiceThread(service_thread); } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index caca60586..29617d736 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -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 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 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 service_thread); + void ReleaseServiceThread(Kernel::ServiceThread& service_thread); /// Workaround for single-core mode when preempting threads while idle. bool IsPhantomModeForSingleCore() const; -- cgit v1.2.3