From 27ce97fd42d758350c5100c4bbcb78de0a6d48b5 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 4 Jun 2021 19:26:48 -0700 Subject: hle: kernel: Refactor to allocate a ServiceThread per service handler. - Previously, we would allocate a thread per session, which adds new threads on CloneCurrentObject. - This results in race conditions with N sessions queuing requests to the same service interface. - Fixes Pokken Tournament DX crashes/softlocks, which were regressed by #6347. --- src/core/hle/kernel/k_server_session.cpp | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) (limited to 'src/core/hle/kernel/k_server_session.cpp') diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index dbf03b462..e66a9198a 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -13,8 +13,10 @@ #include "core/hle/kernel/hle_ipc.h" #include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_handle_table.h" +#include "core/hle/kernel/k_port.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/k_server_port.h" #include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/k_session.h" #include "core/hle/kernel/k_thread.h" @@ -23,18 +25,21 @@ namespace Kernel { -KServerSession::KServerSession(KernelCore& kernel_) - : KSynchronizationObject{kernel_}, manager{std::make_shared()} {} +KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} -KServerSession::~KServerSession() { - kernel.ReleaseServiceThread(service_thread); -} +KServerSession::~KServerSession() {} -void KServerSession::Initialize(KSession* parent_, std::string&& name_) { +void KServerSession::Initialize(KSession* parent_, std::string&& name_, + std::shared_ptr manager_) { // Set member variables. parent = parent_; name = std::move(name_); - service_thread = kernel.CreateServiceThread(name); + + if (manager_) { + manager = manager_; + } else { + manager = std::make_shared(kernel); + } } void KServerSession::Destroy() { @@ -114,7 +119,7 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); - if (auto strong_ptr = service_thread.lock()) { + if (auto strong_ptr = manager->GetServiceThread().lock()) { strong_ptr->QueueSyncRequest(*parent, std::move(context)); return ResultSuccess; } -- cgit v1.2.3 From 611983679593d8a666551254bc97490effbb6519 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 15:39:11 -0700 Subject: hle: kernel: KAutoObjectWithListContainer: Use boost::instrusive::rbtree. - Fixes some crashes introduced by our common intrusive red/black tree impl. --- src/core/hle/kernel/k_server_session.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/k_server_session.cpp') diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index e66a9198a..3024395dd 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -29,10 +29,10 @@ KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{ker KServerSession::~KServerSession() {} -void KServerSession::Initialize(KSession* parent_, std::string&& name_, +void KServerSession::Initialize(KSession* parent_session_, std::string&& name_, std::shared_ptr manager_) { // Set member variables. - parent = parent_; + parent = parent_session_; name = std::move(name_); if (manager_) { -- cgit v1.2.3 From 93f93cb8bc4cf25cbddd2918d0edec786ecce15b Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 17:03:36 -0700 Subject: hle: kernel: k_server_session: Ensure service thread is valid before dereference. --- src/core/hle/kernel/k_server_session.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/k_server_session.cpp') diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 3024395dd..96c8d7b0e 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -119,9 +119,11 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); - if (auto strong_ptr = manager->GetServiceThread().lock()) { + if (auto strong_ptr = manager->GetServiceThread().lock(); strong_ptr) { strong_ptr->QueueSyncRequest(*parent, std::move(context)); return ResultSuccess; + } else { + ASSERT(false, "strong_ptr was nullptr!"); } return ResultSuccess; -- cgit v1.2.3 From ada4242c014d791379c02bf4222a39a9e881a692 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 17:54:06 -0700 Subject: hle: kernel: k_server_session: Return service thread by strong pointer. --- src/core/hle/kernel/k_server_session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/k_server_session.cpp') diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 96c8d7b0e..b231f8183 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -119,7 +119,7 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); - if (auto strong_ptr = manager->GetServiceThread().lock(); strong_ptr) { + if (auto strong_ptr = manager->GetServiceThread(); strong_ptr) { strong_ptr->QueueSyncRequest(*parent, std::move(context)); return ResultSuccess; } else { -- cgit v1.2.3 From 9db569b2d946cf9e5969684dc122b62ff09adaef Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 22:09:25 -0700 Subject: hle: kernel: KServerSession: Use ASSERT_MSG where appropriate. --- src/core/hle/kernel/k_server_session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/k_server_session.cpp') diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index b231f8183..528ca8614 100644 --- a/src/core/hle/kernel/k_server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp @@ -123,7 +123,7 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor strong_ptr->QueueSyncRequest(*parent, std::move(context)); return ResultSuccess; } else { - ASSERT(false, "strong_ptr was nullptr!"); + ASSERT_MSG(false, "strong_ptr was nullptr!"); } return ResultSuccess; -- cgit v1.2.3