From 27ce97fd42d758350c5100c4bbcb78de0a6d48b5 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
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<SessionRequestHandler> {
 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<ServiceThread> GetServiceThread() const {
+        return service_thread;
+    }
+
+protected:
+    KernelCore& kernel;
+    std::weak_ptr<ServiceThread> service_thread;
 };
 
 using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
@@ -94,7 +103,8 @@ using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
  */
 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<ServiceThread> GetServiceThread() const {
+        return session_handler->GetServiceThread();
+    }
+
 private:
     bool is_domain{};
     SessionRequestHandlerPtr session_handler;
     std::vector<SessionRequestHandlerPtr> domain_handlers;
+
+private:
+    KernelCore& kernel;
+    std::weak_ptr<ServiceThread> 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<SessionRequestManager> 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<SessionRequestManager> session_manager = nullptr);
 
 private:
     std::atomic<s32> 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<SessionRequestManager>()} {}
+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<SessionRequestManager> manager_) {
     // Set member variables.
     parent = parent_;
     name = std::move(name_);
-    service_thread = kernel.CreateServiceThread(name);
+
+    if (manager_) {
+        manager = manager_;
+    } else {
+        manager = std::make_shared<SessionRequestManager>(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<SessionRequestManager> 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<SessionRequestManager>& GetSessionRequestManager() const {
-        return manager;
-    }
-
-    /// Sets the session request manager, which forwards requests to the underlying service
-    void SetSessionRequestManager(std::shared_ptr<SessionRequestManager> 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<ServiceThread> 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<SessionRequestManager> 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<KSession, KAutoObjectWithList> {
     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<SessionRequestManager> 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<Controller>(system);
 
-    return sm->CreatePort(system.Kernel());
+    return sm->CreatePort();
 }
 
 ResultVal<Kernel::KServerPort*> ServiceManager::RegisterService(std::string name,

From 611983679593d8a666551254bc97490effbb6519 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
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 <atomic>
 #include <string>
 
+#include <boost/intrusive/rbtree.hpp>
+
 #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<u64>(this);
@@ -203,8 +208,6 @@ public:
 
 private:
     friend class KAutoObjectWithListContainer;
-
-    Common::IntrusiveRedBlackTreeNode list_node;
 };
 
 template <typename T>
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 <atomic>
 
+#include <boost/intrusive/rbtree.hpp>
+
 #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<KAutoObjectWithList>;
+    using ListType = boost::intrusive::rbtree<KAutoObjectWithList>;
 
 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<SessionRequestManager> 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<SessionRequestManager> 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 <bunneidev@gmail.com>
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 <bunneidev@gmail.com>
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 <bunneidev@gmail.com>
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<ServiceThread> GetServiceThread() const {
-        return service_thread;
+    std::shared_ptr<ServiceThread> GetServiceThread() const {
+        return service_thread.lock();
     }
 
 protected:
@@ -152,7 +152,7 @@ public:
         session_handler = std::move(handler);
     }
 
-    std::weak_ptr<ServiceThread> GetServiceThread() const {
+    std::shared_ptr<ServiceThread> 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 <bunneidev@gmail.com>
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;