From 27ce97fd42d758350c5100c4bbcb78de0a6d48b5 Mon Sep 17 00:00:00 2001 From: bunnei Date: Fri, 4 Jun 2021 19:26:48 -0700 Subject: [PATCH 1/6] 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/hle_ipc.cpp | 11 +++++-- src/core/hle/kernel/hle_ipc.h | 22 ++++++++++++-- src/core/hle/kernel/k_client_port.cpp | 5 ++-- src/core/hle/kernel/k_client_port.h | 4 ++- src/core/hle/kernel/k_server_session.cpp | 21 +++++++++----- src/core/hle/kernel/k_server_session.h | 17 ++--------- src/core/hle/kernel/k_session.cpp | 5 ++-- src/core/hle/kernel/k_session.h | 5 +++- src/core/hle/service/ns/pl_u.cpp | 2 -- src/core/hle/service/service.cpp | 6 ++-- src/core/hle/service/service.h | 5 ++-- src/core/hle/service/sm/controller.cpp | 37 +++++++----------------- src/core/hle/service/sm/sm.cpp | 2 +- 13 files changed, 75 insertions(+), 67 deletions(-) diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 2b5c30f7a4..eee695dd9a 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -30,9 +30,16 @@ namespace Kernel { -SessionRequestHandler::SessionRequestHandler() = default; +SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_) + : kernel{kernel_}, service_thread{kernel.CreateServiceThread(service_name_)} {} -SessionRequestHandler::~SessionRequestHandler() = default; +SessionRequestHandler::~SessionRequestHandler() { + kernel.ReleaseServiceThread(service_thread); +} + +SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {} + +SessionRequestManager::~SessionRequestManager() {} void SessionRequestHandler::ClientConnected(KServerSession* session) { session->SetSessionHandler(shared_from_this()); diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index b47e363cc6..159565203c 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -46,6 +46,7 @@ class KThread; class KReadableEvent; class KSession; class KWritableEvent; +class ServiceThread; enum class ThreadWakeupReason; @@ -56,7 +57,7 @@ enum class ThreadWakeupReason; */ class SessionRequestHandler : public std::enable_shared_from_this { public: - SessionRequestHandler(); + SessionRequestHandler(KernelCore& kernel, const char* service_name_); virtual ~SessionRequestHandler(); /** @@ -83,6 +84,14 @@ public: * @param server_session ServerSession associated with the connection. */ void ClientDisconnected(KServerSession* session); + + std::weak_ptr GetServiceThread() const { + return service_thread; + } + +protected: + KernelCore& kernel; + std::weak_ptr service_thread; }; using SessionRequestHandlerPtr = std::shared_ptr; @@ -94,7 +103,8 @@ using SessionRequestHandlerPtr = std::shared_ptr; */ class SessionRequestManager final { public: - SessionRequestManager() = default; + explicit SessionRequestManager(KernelCore& kernel); + ~SessionRequestManager(); bool IsDomain() const { return is_domain; @@ -142,10 +152,18 @@ public: session_handler = std::move(handler); } + std::weak_ptr GetServiceThread() const { + return session_handler->GetServiceThread(); + } + private: bool is_domain{}; SessionRequestHandlerPtr session_handler; std::vector domain_handlers; + +private: + KernelCore& kernel; + std::weak_ptr service_thread; }; /** diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp index 23d830d1f4..d4a38fb005 100644 --- a/src/core/hle/kernel/k_client_port.cpp +++ b/src/core/hle/kernel/k_client_port.cpp @@ -56,7 +56,8 @@ bool KClientPort::IsSignaled() const { return num_sessions < max_sessions; } -ResultCode KClientPort::CreateSession(KClientSession** out) { +ResultCode KClientPort::CreateSession(KClientSession** out, + std::shared_ptr session_manager) { // Reserve a new session from the resource limit. KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(), LimitableResource::Sessions); @@ -101,7 +102,7 @@ ResultCode KClientPort::CreateSession(KClientSession** out) { } // Initialize the session. - session->Initialize(this, parent->GetName()); + session->Initialize(this, parent->GetName(), session_manager); // Commit the session reservation. session_reservation.Commit(); diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h index f2fff3b018..54bb05e203 100644 --- a/src/core/hle/kernel/k_client_port.h +++ b/src/core/hle/kernel/k_client_port.h @@ -16,6 +16,7 @@ namespace Kernel { class KClientSession; class KernelCore; class KPort; +class SessionRequestManager; class KClientPort final : public KSynchronizationObject { KERNEL_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject); @@ -52,7 +53,8 @@ public: void Destroy() override; bool IsSignaled() const override; - ResultCode CreateSession(KClientSession** out); + ResultCode CreateSession(KClientSession** out, + std::shared_ptr session_manager = nullptr); private: std::atomic num_sessions{}; diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index dbf03b4623..e66a9198ad 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; } diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h index 27b757ad27..0f4b51e37a 100644 --- a/src/core/hle/kernel/k_server_session.h +++ b/src/core/hle/kernel/k_server_session.h @@ -32,6 +32,7 @@ class HLERequestContext; class KernelCore; class KSession; class SessionRequestHandler; +class SessionRequestManager; class KThread; class KServerSession final : public KSynchronizationObject, @@ -46,7 +47,8 @@ public: void Destroy() override; - void Initialize(KSession* parent_, std::string&& name_); + void Initialize(KSession* parent_, std::string&& name_, + std::shared_ptr manager_); KSession* GetParent() { return parent; @@ -104,16 +106,6 @@ public: return manager; } - /// Gets the session request manager, which forwards requests to the underlying service - const std::shared_ptr& GetSessionRequestManager() const { - return manager; - } - - /// Sets the session request manager, which forwards requests to the underlying service - void SetSessionRequestManager(std::shared_ptr manager_) { - manager = std::move(manager_); - } - private: /// Queues a sync request from the emulated application. ResultCode QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory); @@ -131,9 +123,6 @@ private: /// When set to True, converts the session to a domain at the end of the command bool convert_to_domain{}; - /// Thread to dispatch service requests - std::weak_ptr service_thread; - /// KSession that owns this KServerSession KSession* parent{}; }; diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp index 025b8b555e..940878e039 100644 --- a/src/core/hle/kernel/k_session.cpp +++ b/src/core/hle/kernel/k_session.cpp @@ -15,7 +15,8 @@ KSession::KSession(KernelCore& kernel_) : KAutoObjectWithSlabHeapAndContainer{kernel_}, server{kernel_}, client{kernel_} {} KSession::~KSession() = default; -void KSession::Initialize(KClientPort* port_, const std::string& name_) { +void KSession::Initialize(KClientPort* port_, const std::string& name_, + std::shared_ptr manager_) { // Increment reference count. // Because reference count is one on creation, this will result // in a reference count of two. Thus, when both server and client are closed @@ -27,7 +28,7 @@ void KSession::Initialize(KClientPort* port_, const std::string& name_) { KAutoObject::Create(std::addressof(client)); // Initialize our sub sessions. - server.Initialize(this, name_ + ":Server"); + server.Initialize(this, name_ + ":Server", manager_); client.Initialize(this, name_ + ":Client"); // Set state and name. diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h index 4ddd080d28..62c328a685 100644 --- a/src/core/hle/kernel/k_session.h +++ b/src/core/hle/kernel/k_session.h @@ -13,6 +13,8 @@ namespace Kernel { +class SessionRequestManager; + class KSession final : public KAutoObjectWithSlabHeapAndContainer { KERNEL_AUTOOBJECT_TRAITS(KSession, KAutoObject); @@ -20,7 +22,8 @@ public: explicit KSession(KernelCore& kernel_); ~KSession() override; - void Initialize(KClientPort* port_, const std::string& name_); + void Initialize(KClientPort* port_, const std::string& name_, + std::shared_ptr manager_ = nullptr); void Finalize() override; diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index 6e5ba26a3d..74cc45f1ef 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -254,8 +254,6 @@ void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service_NS, "called"); // Create shared font memory object - auto& kernel = system.Kernel(); - std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(), impl->shared_font->size()); diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 7a15eeba0f..4e1541630b 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -93,8 +93,8 @@ namespace Service { ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_, u32 max_sessions_, InvokerFn* handler_invoker_) - : system{system_}, service_name{service_name_}, max_sessions{max_sessions_}, - handler_invoker{handler_invoker_} {} + : SessionRequestHandler(system_.Kernel(), service_name_), system{system_}, + service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {} ServiceFrameworkBase::~ServiceFrameworkBase() { // Wait for other threads to release access before destroying @@ -111,7 +111,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) port_installed = true; } -Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) { +Kernel::KClientPort& ServiceFrameworkBase::CreatePort() { const auto guard = LockService(); ASSERT(!port_installed); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 4c048173b6..ec757753c6 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -23,6 +23,7 @@ namespace Kernel { class HLERequestContext; class KClientPort; class KServerSession; +class ServiceThread; } // namespace Kernel namespace Service { @@ -41,7 +42,7 @@ class ServiceManager; static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters) /// Arbitrary default number of maximum connections to an HLE service. -static const u32 DefaultMaxSessions = 10; +static const u32 DefaultMaxSessions = 64; /** * This is an non-templated base of ServiceFramework to reduce code bloat and compilation times, it @@ -74,7 +75,7 @@ public: void InvokeRequestTipc(Kernel::HLERequestContext& ctx); /// Creates a port pair and registers it on the kernel's global port registry. - Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel); + Kernel::KClientPort& CreatePort(); /// Handles a synchronization request for the service. ResultCode HandleSyncRequest(Kernel::KServerSession& session, diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index 5fa5e05126..8b9418e0fe 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -28,42 +28,25 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { } void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { - // TODO(bunnei): This is just creating a new handle to the same Session. I assume this is wrong - // and that we probably want to actually make an entirely new Session, but we still need to - // verify this on hardware. - LOG_DEBUG(Service, "called"); - auto& kernel = system.Kernel(); - auto* session = ctx.Session()->GetParent(); - auto* port = session->GetParent()->GetParent(); + auto& parent_session = *ctx.Session()->GetParent(); + auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort(); + auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager(); - // Reserve a new session from the process resource limit. - Kernel::KScopedResourceReservation session_reservation( - kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions); - if (!session_reservation.Succeeded()) { + // Create a session. + Kernel::KClientSession* session{}; + const ResultCode result = parent_port.CreateSession(std::addressof(session), session_manager); + if (result.IsError()) { + LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Kernel::ResultLimitReached); + rb.Push(result); } - // Create a new session. - auto* clone = Kernel::KSession::Create(kernel); - clone->Initialize(&port->GetClientPort(), session->GetName()); - - // Commit the session reservation. - session_reservation.Commit(); - - // Enqueue the session with the named port. - port->EnqueueSession(&clone->GetServerSession()); - - // Set the session request manager. - clone->GetServerSession().SetSessionRequestManager( - session->GetServerSession().GetSessionRequestManager()); - // We succeeded. IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(ResultSuccess); - rb.PushMoveObjects(clone->GetClientSession()); + rb.PushMoveObjects(session); } void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index d8b20a3f23..bffa9ffcb9 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -46,7 +46,7 @@ Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core self.sm_interface = sm; self.controller_interface = std::make_unique(system); - return sm->CreatePort(system.Kernel()); + return sm->CreatePort(); } ResultVal ServiceManager::RegisterService(std::string name, From 611983679593d8a666551254bc97490effbb6519 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 15:39:11 -0700 Subject: [PATCH 2/6] hle: kernel: KAutoObjectWithListContainer: Use boost::instrusive::rbtree. - Fixes some crashes introduced by our common intrusive red/black tree impl. --- src/core/hle/kernel/k_auto_object.h | 11 +++++++---- src/core/hle/kernel/k_auto_object_container.cpp | 4 ++-- src/core/hle/kernel/k_auto_object_container.h | 5 +++-- src/core/hle/kernel/k_client_port.cpp | 4 ++-- src/core/hle/kernel/k_client_session.h | 4 ++-- src/core/hle/kernel/k_readable_event.h | 4 ++-- src/core/hle/kernel/k_server_port.cpp | 4 ++-- src/core/hle/kernel/k_server_port.h | 2 +- src/core/hle/kernel/k_server_session.cpp | 4 ++-- src/core/hle/kernel/k_server_session.h | 2 +- src/core/hle/kernel/k_writable_event.cpp | 4 ++-- 11 files changed, 26 insertions(+), 22 deletions(-) diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h index bc18582be0..88a052f658 100644 --- a/src/core/hle/kernel/k_auto_object.h +++ b/src/core/hle/kernel/k_auto_object.h @@ -7,10 +7,11 @@ #include #include +#include + #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" -#include "common/intrusive_red_black_tree.h" #include "core/hle/kernel/k_class_token.h" namespace Kernel { @@ -175,7 +176,7 @@ private: class KAutoObjectWithListContainer; -class KAutoObjectWithList : public KAutoObject { +class KAutoObjectWithList : public KAutoObject, public boost::intrusive::set_base_hook<> { public: explicit KAutoObjectWithList(KernelCore& kernel_) : KAutoObject(kernel_) {} @@ -192,6 +193,10 @@ public: } } + friend bool operator<(const KAutoObjectWithList& left, const KAutoObjectWithList& right) { + return &left < &right; + } + public: virtual u64 GetId() const { return reinterpret_cast(this); @@ -203,8 +208,6 @@ public: private: friend class KAutoObjectWithListContainer; - - Common::IntrusiveRedBlackTreeNode list_node; }; template diff --git a/src/core/hle/kernel/k_auto_object_container.cpp b/src/core/hle/kernel/k_auto_object_container.cpp index fc0c288748..010006bb70 100644 --- a/src/core/hle/kernel/k_auto_object_container.cpp +++ b/src/core/hle/kernel/k_auto_object_container.cpp @@ -9,13 +9,13 @@ namespace Kernel { void KAutoObjectWithListContainer::Register(KAutoObjectWithList* obj) { KScopedLightLock lk(m_lock); - m_object_list.insert(*obj); + m_object_list.insert_unique(*obj); } void KAutoObjectWithListContainer::Unregister(KAutoObjectWithList* obj) { KScopedLightLock lk(m_lock); - m_object_list.erase(m_object_list.iterator_to(*obj)); + m_object_list.erase(*obj); } size_t KAutoObjectWithListContainer::GetOwnedCount(KProcess* owner) { diff --git a/src/core/hle/kernel/k_auto_object_container.h b/src/core/hle/kernel/k_auto_object_container.h index ff40cf5a71..459953450a 100644 --- a/src/core/hle/kernel/k_auto_object_container.h +++ b/src/core/hle/kernel/k_auto_object_container.h @@ -6,6 +6,8 @@ #include +#include + #include "common/assert.h" #include "common/common_funcs.h" #include "common/common_types.h" @@ -23,8 +25,7 @@ class KAutoObjectWithListContainer { YUZU_NON_MOVEABLE(KAutoObjectWithListContainer); public: - using ListType = Common::IntrusiveRedBlackTreeMemberTraits< - &KAutoObjectWithList::list_node>::TreeType; + using ListType = boost::intrusive::rbtree; public: class ListAccessor : public KScopedLightLock { diff --git a/src/core/hle/kernel/k_client_port.cpp b/src/core/hle/kernel/k_client_port.cpp index d4a38fb005..50606bd917 100644 --- a/src/core/hle/kernel/k_client_port.cpp +++ b/src/core/hle/kernel/k_client_port.cpp @@ -16,11 +16,11 @@ namespace Kernel { KClientPort::KClientPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} KClientPort::~KClientPort() = default; -void KClientPort::Initialize(KPort* parent_, s32 max_sessions_, std::string&& name_) { +void KClientPort::Initialize(KPort* parent_port_, s32 max_sessions_, std::string&& name_) { // Set member variables. num_sessions = 0; peak_sessions = 0; - parent = parent_; + parent = parent_port_; max_sessions = max_sessions_; name = std::move(name_); } diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h index b11d5b4e37..230e3b6b81 100644 --- a/src/core/hle/kernel/k_client_session.h +++ b/src/core/hle/kernel/k_client_session.h @@ -36,9 +36,9 @@ public: explicit KClientSession(KernelCore& kernel_); ~KClientSession() override; - void Initialize(KSession* parent_, std::string&& name_) { + void Initialize(KSession* parent_session_, std::string&& name_) { // Set member variables. - parent = parent_; + parent = parent_session_; name = std::move(name_); } diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h index b2850ac7bf..149fa78dda 100644 --- a/src/core/hle/kernel/k_readable_event.h +++ b/src/core/hle/kernel/k_readable_event.h @@ -21,9 +21,9 @@ public: explicit KReadableEvent(KernelCore& kernel_); ~KReadableEvent() override; - void Initialize(KEvent* parent_, std::string&& name_) { + void Initialize(KEvent* parent_event_, std::string&& name_) { is_signaled = false; - parent = parent_; + parent = parent_event_; name = std::move(name_); } diff --git a/src/core/hle/kernel/k_server_port.cpp b/src/core/hle/kernel/k_server_port.cpp index 8cbde177aa..c5dc58387f 100644 --- a/src/core/hle/kernel/k_server_port.cpp +++ b/src/core/hle/kernel/k_server_port.cpp @@ -17,9 +17,9 @@ namespace Kernel { KServerPort::KServerPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} KServerPort::~KServerPort() = default; -void KServerPort::Initialize(KPort* parent_, std::string&& name_) { +void KServerPort::Initialize(KPort* parent_port_, std::string&& name_) { // Set member variables. - parent = parent_; + parent = parent_port_; name = std::move(name_); } diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h index 55481d63f4..67a36da404 100644 --- a/src/core/hle/kernel/k_server_port.h +++ b/src/core/hle/kernel/k_server_port.h @@ -29,7 +29,7 @@ public: explicit KServerPort(KernelCore& kernel_); ~KServerPort() override; - void Initialize(KPort* parent_, std::string&& name_); + void Initialize(KPort* parent_port_, std::string&& name_); /// Whether or not this server port has an HLE handler available. bool HasSessionRequestHandler() const { diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index e66a9198ad..3024395dde 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_) { diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h index 0f4b51e37a..9efd400bc7 100644 --- a/src/core/hle/kernel/k_server_session.h +++ b/src/core/hle/kernel/k_server_session.h @@ -47,7 +47,7 @@ public: void Destroy() override; - void Initialize(KSession* parent_, std::string&& name_, + void Initialize(KSession* parent_session_, std::string&& name_, std::shared_ptr manager_); KSession* GetParent() { diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp index b7b83c1516..bdb1db6d5e 100644 --- a/src/core/hle/kernel/k_writable_event.cpp +++ b/src/core/hle/kernel/k_writable_event.cpp @@ -13,8 +13,8 @@ KWritableEvent::KWritableEvent(KernelCore& kernel_) KWritableEvent::~KWritableEvent() = default; -void KWritableEvent::Initialize(KEvent* parent_, std::string&& name_) { - parent = parent_; +void KWritableEvent::Initialize(KEvent* parent_event_, std::string&& name_) { + parent = parent_event_; name = std::move(name_); parent->GetReadableEvent().Open(); } From 384cbe3829fadab52ac5f53d445fba4a76b8a284 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 15:41:16 -0700 Subject: [PATCH 3/6] hle: kernel: hle_ipc: Use default destructor for SessionRequestManager. --- src/core/hle/kernel/hle_ipc.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index eee695dd9a..260af87e58 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -39,7 +39,7 @@ SessionRequestHandler::~SessionRequestHandler() { SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {} -SessionRequestManager::~SessionRequestManager() {} +SessionRequestManager::~SessionRequestManager() = default; void SessionRequestHandler::ClientConnected(KServerSession* session) { session->SetSessionHandler(shared_from_this()); From 93f93cb8bc4cf25cbddd2918d0edec786ecce15b Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 17:03:36 -0700 Subject: [PATCH 4/6] 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(-) diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 3024395dde..96c8d7b0ee 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; From ada4242c014d791379c02bf4222a39a9e881a692 Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 17:54:06 -0700 Subject: [PATCH 5/6] hle: kernel: k_server_session: Return service thread by strong pointer. --- src/core/hle/kernel/hle_ipc.h | 6 +++--- src/core/hle/kernel/k_server_session.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 159565203c..2aaf93fca4 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -85,8 +85,8 @@ public: */ void ClientDisconnected(KServerSession* session); - std::weak_ptr GetServiceThread() const { - return service_thread; + std::shared_ptr GetServiceThread() const { + return service_thread.lock(); } protected: @@ -152,7 +152,7 @@ public: session_handler = std::move(handler); } - std::weak_ptr GetServiceThread() const { + std::shared_ptr GetServiceThread() const { return session_handler->GetServiceThread(); } diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index 96c8d7b0ee..b231f8183c 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 { From 9db569b2d946cf9e5969684dc122b62ff09adaef Mon Sep 17 00:00:00 2001 From: bunnei Date: Sun, 6 Jun 2021 22:09:25 -0700 Subject: [PATCH 6/6] hle: kernel: KServerSession: Use ASSERT_MSG where appropriate. --- src/core/hle/kernel/k_server_session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index b231f8183c..528ca86146 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;