From f57be2e62603ddd99fbdb1dea1bfc91ee2d7fc04 Mon Sep 17 00:00:00 2001
From: bunnei <bunneidev@gmail.com>
Date: Tue, 29 Dec 2020 01:06:39 -0800
Subject: [PATCH] hle: kernel: service_thread: Add thread name and take
 weak_ptr of ServerSession.

---
 src/core/hle/kernel/server_session.cpp |  2 +-
 src/core/hle/kernel/service_thread.cpp | 28 +++++++++++++++++---------
 src/core/hle/kernel/service_thread.h   |  3 ++-
 3 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp
index ed42452ff..947f4a133 100644
--- a/src/core/hle/kernel/server_session.cpp
+++ b/src/core/hle/kernel/server_session.cpp
@@ -34,7 +34,7 @@ ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kern
 
     session->name = std::move(name);
     session->parent = std::move(parent);
-    session->service_thread = std::make_unique<ServiceThread>(kernel, 1);
+    session->service_thread = std::make_unique<ServiceThread>(kernel, 1, session->name);
 
     return MakeResult(std::move(session));
 }
diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp
index 4ceb7e56a..1c134777f 100644
--- a/src/core/hle/kernel/service_thread.cpp
+++ b/src/core/hle/kernel/service_thread.cpp
@@ -11,6 +11,7 @@
 
 #include "common/assert.h"
 #include "common/scope_exit.h"
+#include "common/thread.h"
 #include "core/core.h"
 #include "core/hle/kernel/kernel.h"
 #include "core/hle/kernel/server_session.h"
@@ -22,7 +23,7 @@ namespace Kernel {
 
 class ServiceThread::Impl final {
 public:
-    explicit Impl(KernelCore& kernel, std::size_t num_threads);
+    explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name);
     ~Impl();
 
     void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context);
@@ -32,12 +33,16 @@ private:
     std::queue<std::function<void()>> requests;
     std::mutex queue_mutex;
     std::condition_variable condition;
+    const std::string service_name;
     bool stop{};
 };
 
-ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads) {
+ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name)
+    : service_name{name} {
     for (std::size_t i = 0; i < num_threads; ++i)
-        threads.emplace_back([&] {
+        threads.emplace_back([this, &kernel] {
+            Common::SetCurrentThreadName(std::string{"Hle_" + service_name}.c_str());
+
             // Wait for first request before trying to acquire a render context
             {
                 std::unique_lock lock{queue_mutex};
@@ -52,7 +57,7 @@ ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads) {
                 {
                     std::unique_lock lock{queue_mutex};
                     condition.wait(lock, [this] { return stop || !requests.empty(); });
-                    if (stop && requests.empty()) {
+                    if (stop || requests.empty()) {
                         return;
                     }
                     task = std::move(requests.front());
@@ -68,9 +73,14 @@ void ServiceThread::Impl::QueueSyncRequest(ServerSession& session,
                                            std::shared_ptr<HLERequestContext>&& context) {
     {
         std::unique_lock lock{queue_mutex};
-        requests.emplace([session{SharedFrom(&session)}, context{std::move(context)}]() {
-            session->CompleteSyncRequest(*context);
-            return;
+
+        // ServerSession owns the service thread, so we cannot caption a strong pointer here in the
+        // event that the ServerSession is terminated.
+        std::weak_ptr<ServerSession> weak_ptr{SharedFrom(&session)};
+        requests.emplace([weak_ptr, context{std::move(context)}]() {
+            if (auto strong_ptr = weak_ptr.lock()) {
+                strong_ptr->CompleteSyncRequest(*context);
+            }
         });
     }
     condition.notify_one();
@@ -87,8 +97,8 @@ ServiceThread::Impl::~Impl() {
     }
 }
 
-ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads)
-    : impl{std::make_unique<Impl>(kernel, num_threads)} {}
+ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name)
+    : impl{std::make_unique<Impl>(kernel, num_threads, name)} {}
 
 ServiceThread::~ServiceThread() = default;
 
diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h
index 91ad7ae85..025ab8fb5 100644
--- a/src/core/hle/kernel/service_thread.h
+++ b/src/core/hle/kernel/service_thread.h
@@ -5,6 +5,7 @@
 #pragma once
 
 #include <memory>
+#include <string>
 
 namespace Kernel {
 
@@ -14,7 +15,7 @@ class ServerSession;
 
 class ServiceThread final {
 public:
-    explicit ServiceThread(KernelCore& kernel, std::size_t num_threads);
+    explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name);
     ~ServiceThread();
 
     void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context);