summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2021-06-06 22:52:07 -0700
committerGravatar GitHub2021-06-06 22:52:07 -0700
commit28eb8c83d479403b5da88ae7d3d2a1c6b81a6552 (patch)
tree43b28bb3b8df05e3f19fe4a151571dedd7171255 /src
parentMerge pull request #6400 from ameerj/disable-uniform-simplify (diff)
parenthle: kernel: KServerSession: Use ASSERT_MSG where appropriate. (diff)
downloadyuzu-28eb8c83d479403b5da88ae7d3d2a1c6b81a6552.tar.gz
yuzu-28eb8c83d479403b5da88ae7d3d2a1c6b81a6552.tar.xz
yuzu-28eb8c83d479403b5da88ae7d3d2a1c6b81a6552.zip
Merge pull request #6414 from bunnei/fix-service-threads
hle: kernel: Refactor to allocate a ServiceThread per service handler.
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp11
-rw-r--r--src/core/hle/kernel/hle_ipc.h22
-rw-r--r--src/core/hle/kernel/k_auto_object.h11
-rw-r--r--src/core/hle/kernel/k_auto_object_container.cpp4
-rw-r--r--src/core/hle/kernel/k_auto_object_container.h5
-rw-r--r--src/core/hle/kernel/k_client_port.cpp9
-rw-r--r--src/core/hle/kernel/k_client_port.h4
-rw-r--r--src/core/hle/kernel/k_client_session.h4
-rw-r--r--src/core/hle/kernel/k_readable_event.h4
-rw-r--r--src/core/hle/kernel/k_server_port.cpp4
-rw-r--r--src/core/hle/kernel/k_server_port.h2
-rw-r--r--src/core/hle/kernel/k_server_session.cpp25
-rw-r--r--src/core/hle/kernel/k_server_session.h17
-rw-r--r--src/core/hle/kernel/k_session.cpp5
-rw-r--r--src/core/hle/kernel/k_session.h5
-rw-r--r--src/core/hle/kernel/k_writable_event.cpp4
-rw-r--r--src/core/hle/service/ns/pl_u.cpp2
-rw-r--r--src/core/hle/service/service.cpp6
-rw-r--r--src/core/hle/service/service.h5
-rw-r--r--src/core/hle/service/sm/controller.cpp37
-rw-r--r--src/core/hle/service/sm/sm.cpp2
21 files changed, 101 insertions, 87 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 2b5c30f7a..260af87e5 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -30,9 +30,16 @@
30 30
31namespace Kernel { 31namespace Kernel {
32 32
33SessionRequestHandler::SessionRequestHandler() = default; 33SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_)
34 : kernel{kernel_}, service_thread{kernel.CreateServiceThread(service_name_)} {}
34 35
35SessionRequestHandler::~SessionRequestHandler() = default; 36SessionRequestHandler::~SessionRequestHandler() {
37 kernel.ReleaseServiceThread(service_thread);
38}
39
40SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {}
41
42SessionRequestManager::~SessionRequestManager() = default;
36 43
37void SessionRequestHandler::ClientConnected(KServerSession* session) { 44void SessionRequestHandler::ClientConnected(KServerSession* session) {
38 session->SetSessionHandler(shared_from_this()); 45 session->SetSessionHandler(shared_from_this());
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index b47e363cc..2aaf93fca 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -46,6 +46,7 @@ class KThread;
46class KReadableEvent; 46class KReadableEvent;
47class KSession; 47class KSession;
48class KWritableEvent; 48class KWritableEvent;
49class ServiceThread;
49 50
50enum class ThreadWakeupReason; 51enum class ThreadWakeupReason;
51 52
@@ -56,7 +57,7 @@ enum class ThreadWakeupReason;
56 */ 57 */
57class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> { 58class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> {
58public: 59public:
59 SessionRequestHandler(); 60 SessionRequestHandler(KernelCore& kernel, const char* service_name_);
60 virtual ~SessionRequestHandler(); 61 virtual ~SessionRequestHandler();
61 62
62 /** 63 /**
@@ -83,6 +84,14 @@ public:
83 * @param server_session ServerSession associated with the connection. 84 * @param server_session ServerSession associated with the connection.
84 */ 85 */
85 void ClientDisconnected(KServerSession* session); 86 void ClientDisconnected(KServerSession* session);
87
88 std::shared_ptr<ServiceThread> GetServiceThread() const {
89 return service_thread.lock();
90 }
91
92protected:
93 KernelCore& kernel;
94 std::weak_ptr<ServiceThread> service_thread;
86}; 95};
87 96
88using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>; 97using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
@@ -94,7 +103,8 @@ using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
94 */ 103 */
95class SessionRequestManager final { 104class SessionRequestManager final {
96public: 105public:
97 SessionRequestManager() = default; 106 explicit SessionRequestManager(KernelCore& kernel);
107 ~SessionRequestManager();
98 108
99 bool IsDomain() const { 109 bool IsDomain() const {
100 return is_domain; 110 return is_domain;
@@ -142,10 +152,18 @@ public:
142 session_handler = std::move(handler); 152 session_handler = std::move(handler);
143 } 153 }
144 154
155 std::shared_ptr<ServiceThread> GetServiceThread() const {
156 return session_handler->GetServiceThread();
157 }
158
145private: 159private:
146 bool is_domain{}; 160 bool is_domain{};
147 SessionRequestHandlerPtr session_handler; 161 SessionRequestHandlerPtr session_handler;
148 std::vector<SessionRequestHandlerPtr> domain_handlers; 162 std::vector<SessionRequestHandlerPtr> domain_handlers;
163
164private:
165 KernelCore& kernel;
166 std::weak_ptr<ServiceThread> service_thread;
149}; 167};
150 168
151/** 169/**
diff --git a/src/core/hle/kernel/k_auto_object.h b/src/core/hle/kernel/k_auto_object.h
index bc18582be..88a052f65 100644
--- a/src/core/hle/kernel/k_auto_object.h
+++ b/src/core/hle/kernel/k_auto_object.h
@@ -7,10 +7,11 @@
7#include <atomic> 7#include <atomic>
8#include <string> 8#include <string>
9 9
10#include <boost/intrusive/rbtree.hpp>
11
10#include "common/assert.h" 12#include "common/assert.h"
11#include "common/common_funcs.h" 13#include "common/common_funcs.h"
12#include "common/common_types.h" 14#include "common/common_types.h"
13#include "common/intrusive_red_black_tree.h"
14#include "core/hle/kernel/k_class_token.h" 15#include "core/hle/kernel/k_class_token.h"
15 16
16namespace Kernel { 17namespace Kernel {
@@ -175,7 +176,7 @@ private:
175 176
176class KAutoObjectWithListContainer; 177class KAutoObjectWithListContainer;
177 178
178class KAutoObjectWithList : public KAutoObject { 179class KAutoObjectWithList : public KAutoObject, public boost::intrusive::set_base_hook<> {
179public: 180public:
180 explicit KAutoObjectWithList(KernelCore& kernel_) : KAutoObject(kernel_) {} 181 explicit KAutoObjectWithList(KernelCore& kernel_) : KAutoObject(kernel_) {}
181 182
@@ -192,6 +193,10 @@ public:
192 } 193 }
193 } 194 }
194 195
196 friend bool operator<(const KAutoObjectWithList& left, const KAutoObjectWithList& right) {
197 return &left < &right;
198 }
199
195public: 200public:
196 virtual u64 GetId() const { 201 virtual u64 GetId() const {
197 return reinterpret_cast<u64>(this); 202 return reinterpret_cast<u64>(this);
@@ -203,8 +208,6 @@ public:
203 208
204private: 209private:
205 friend class KAutoObjectWithListContainer; 210 friend class KAutoObjectWithListContainer;
206
207 Common::IntrusiveRedBlackTreeNode list_node;
208}; 211};
209 212
210template <typename T> 213template <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 fc0c28874..010006bb7 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 {
9void KAutoObjectWithListContainer::Register(KAutoObjectWithList* obj) { 9void KAutoObjectWithListContainer::Register(KAutoObjectWithList* obj) {
10 KScopedLightLock lk(m_lock); 10 KScopedLightLock lk(m_lock);
11 11
12 m_object_list.insert(*obj); 12 m_object_list.insert_unique(*obj);
13} 13}
14 14
15void KAutoObjectWithListContainer::Unregister(KAutoObjectWithList* obj) { 15void KAutoObjectWithListContainer::Unregister(KAutoObjectWithList* obj) {
16 KScopedLightLock lk(m_lock); 16 KScopedLightLock lk(m_lock);
17 17
18 m_object_list.erase(m_object_list.iterator_to(*obj)); 18 m_object_list.erase(*obj);
19} 19}
20 20
21size_t KAutoObjectWithListContainer::GetOwnedCount(KProcess* owner) { 21size_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 ff40cf5a7..459953450 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 @@
6 6
7#include <atomic> 7#include <atomic>
8 8
9#include <boost/intrusive/rbtree.hpp>
10
9#include "common/assert.h" 11#include "common/assert.h"
10#include "common/common_funcs.h" 12#include "common/common_funcs.h"
11#include "common/common_types.h" 13#include "common/common_types.h"
@@ -23,8 +25,7 @@ class KAutoObjectWithListContainer {
23 YUZU_NON_MOVEABLE(KAutoObjectWithListContainer); 25 YUZU_NON_MOVEABLE(KAutoObjectWithListContainer);
24 26
25public: 27public:
26 using ListType = Common::IntrusiveRedBlackTreeMemberTraits< 28 using ListType = boost::intrusive::rbtree<KAutoObjectWithList>;
27 &KAutoObjectWithList::list_node>::TreeType<KAutoObjectWithList>;
28 29
29public: 30public:
30 class ListAccessor : public KScopedLightLock { 31 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 23d830d1f..50606bd91 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 {
16KClientPort::KClientPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} 16KClientPort::KClientPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
17KClientPort::~KClientPort() = default; 17KClientPort::~KClientPort() = default;
18 18
19void KClientPort::Initialize(KPort* parent_, s32 max_sessions_, std::string&& name_) { 19void KClientPort::Initialize(KPort* parent_port_, s32 max_sessions_, std::string&& name_) {
20 // Set member variables. 20 // Set member variables.
21 num_sessions = 0; 21 num_sessions = 0;
22 peak_sessions = 0; 22 peak_sessions = 0;
23 parent = parent_; 23 parent = parent_port_;
24 max_sessions = max_sessions_; 24 max_sessions = max_sessions_;
25 name = std::move(name_); 25 name = std::move(name_);
26} 26}
@@ -56,7 +56,8 @@ bool KClientPort::IsSignaled() const {
56 return num_sessions < max_sessions; 56 return num_sessions < max_sessions;
57} 57}
58 58
59ResultCode KClientPort::CreateSession(KClientSession** out) { 59ResultCode KClientPort::CreateSession(KClientSession** out,
60 std::shared_ptr<SessionRequestManager> session_manager) {
60 // Reserve a new session from the resource limit. 61 // Reserve a new session from the resource limit.
61 KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(), 62 KScopedResourceReservation session_reservation(kernel.CurrentProcess()->GetResourceLimit(),
62 LimitableResource::Sessions); 63 LimitableResource::Sessions);
@@ -101,7 +102,7 @@ ResultCode KClientPort::CreateSession(KClientSession** out) {
101 } 102 }
102 103
103 // Initialize the session. 104 // Initialize the session.
104 session->Initialize(this, parent->GetName()); 105 session->Initialize(this, parent->GetName(), session_manager);
105 106
106 // Commit the session reservation. 107 // Commit the session reservation.
107 session_reservation.Commit(); 108 session_reservation.Commit();
diff --git a/src/core/hle/kernel/k_client_port.h b/src/core/hle/kernel/k_client_port.h
index f2fff3b01..54bb05e20 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 {
16class KClientSession; 16class KClientSession;
17class KernelCore; 17class KernelCore;
18class KPort; 18class KPort;
19class SessionRequestManager;
19 20
20class KClientPort final : public KSynchronizationObject { 21class KClientPort final : public KSynchronizationObject {
21 KERNEL_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject); 22 KERNEL_AUTOOBJECT_TRAITS(KClientPort, KSynchronizationObject);
@@ -52,7 +53,8 @@ public:
52 void Destroy() override; 53 void Destroy() override;
53 bool IsSignaled() const override; 54 bool IsSignaled() const override;
54 55
55 ResultCode CreateSession(KClientSession** out); 56 ResultCode CreateSession(KClientSession** out,
57 std::shared_ptr<SessionRequestManager> session_manager = nullptr);
56 58
57private: 59private:
58 std::atomic<s32> num_sessions{}; 60 std::atomic<s32> num_sessions{};
diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h
index b11d5b4e3..230e3b6b8 100644
--- a/src/core/hle/kernel/k_client_session.h
+++ b/src/core/hle/kernel/k_client_session.h
@@ -36,9 +36,9 @@ public:
36 explicit KClientSession(KernelCore& kernel_); 36 explicit KClientSession(KernelCore& kernel_);
37 ~KClientSession() override; 37 ~KClientSession() override;
38 38
39 void Initialize(KSession* parent_, std::string&& name_) { 39 void Initialize(KSession* parent_session_, std::string&& name_) {
40 // Set member variables. 40 // Set member variables.
41 parent = parent_; 41 parent = parent_session_;
42 name = std::move(name_); 42 name = std::move(name_);
43 } 43 }
44 44
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h
index b2850ac7b..149fa78dd 100644
--- a/src/core/hle/kernel/k_readable_event.h
+++ b/src/core/hle/kernel/k_readable_event.h
@@ -21,9 +21,9 @@ public:
21 explicit KReadableEvent(KernelCore& kernel_); 21 explicit KReadableEvent(KernelCore& kernel_);
22 ~KReadableEvent() override; 22 ~KReadableEvent() override;
23 23
24 void Initialize(KEvent* parent_, std::string&& name_) { 24 void Initialize(KEvent* parent_event_, std::string&& name_) {
25 is_signaled = false; 25 is_signaled = false;
26 parent = parent_; 26 parent = parent_event_;
27 name = std::move(name_); 27 name = std::move(name_);
28 } 28 }
29 29
diff --git a/src/core/hle/kernel/k_server_port.cpp b/src/core/hle/kernel/k_server_port.cpp
index 8cbde177a..c5dc58387 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 {
17KServerPort::KServerPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} 17KServerPort::KServerPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
18KServerPort::~KServerPort() = default; 18KServerPort::~KServerPort() = default;
19 19
20void KServerPort::Initialize(KPort* parent_, std::string&& name_) { 20void KServerPort::Initialize(KPort* parent_port_, std::string&& name_) {
21 // Set member variables. 21 // Set member variables.
22 parent = parent_; 22 parent = parent_port_;
23 name = std::move(name_); 23 name = std::move(name_);
24} 24}
25 25
diff --git a/src/core/hle/kernel/k_server_port.h b/src/core/hle/kernel/k_server_port.h
index 55481d63f..67a36da40 100644
--- a/src/core/hle/kernel/k_server_port.h
+++ b/src/core/hle/kernel/k_server_port.h
@@ -29,7 +29,7 @@ public:
29 explicit KServerPort(KernelCore& kernel_); 29 explicit KServerPort(KernelCore& kernel_);
30 ~KServerPort() override; 30 ~KServerPort() override;
31 31
32 void Initialize(KPort* parent_, std::string&& name_); 32 void Initialize(KPort* parent_port_, std::string&& name_);
33 33
34 /// Whether or not this server port has an HLE handler available. 34 /// Whether or not this server port has an HLE handler available.
35 bool HasSessionRequestHandler() const { 35 bool HasSessionRequestHandler() const {
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index dbf03b462..528ca8614 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -13,8 +13,10 @@
13#include "core/hle/kernel/hle_ipc.h" 13#include "core/hle/kernel/hle_ipc.h"
14#include "core/hle/kernel/k_client_port.h" 14#include "core/hle/kernel/k_client_port.h"
15#include "core/hle/kernel/k_handle_table.h" 15#include "core/hle/kernel/k_handle_table.h"
16#include "core/hle/kernel/k_port.h"
16#include "core/hle/kernel/k_process.h" 17#include "core/hle/kernel/k_process.h"
17#include "core/hle/kernel/k_scheduler.h" 18#include "core/hle/kernel/k_scheduler.h"
19#include "core/hle/kernel/k_server_port.h"
18#include "core/hle/kernel/k_server_session.h" 20#include "core/hle/kernel/k_server_session.h"
19#include "core/hle/kernel/k_session.h" 21#include "core/hle/kernel/k_session.h"
20#include "core/hle/kernel/k_thread.h" 22#include "core/hle/kernel/k_thread.h"
@@ -23,18 +25,21 @@
23 25
24namespace Kernel { 26namespace Kernel {
25 27
26KServerSession::KServerSession(KernelCore& kernel_) 28KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {}
27 : KSynchronizationObject{kernel_}, manager{std::make_shared<SessionRequestManager>()} {}
28 29
29KServerSession::~KServerSession() { 30KServerSession::~KServerSession() {}
30 kernel.ReleaseServiceThread(service_thread);
31}
32 31
33void KServerSession::Initialize(KSession* parent_, std::string&& name_) { 32void KServerSession::Initialize(KSession* parent_session_, std::string&& name_,
33 std::shared_ptr<SessionRequestManager> manager_) {
34 // Set member variables. 34 // Set member variables.
35 parent = parent_; 35 parent = parent_session_;
36 name = std::move(name_); 36 name = std::move(name_);
37 service_thread = kernel.CreateServiceThread(name); 37
38 if (manager_) {
39 manager = manager_;
40 } else {
41 manager = std::make_shared<SessionRequestManager>(kernel);
42 }
38} 43}
39 44
40void KServerSession::Destroy() { 45void KServerSession::Destroy() {
@@ -114,9 +119,11 @@ ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memor
114 119
115 context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); 120 context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
116 121
117 if (auto strong_ptr = service_thread.lock()) { 122 if (auto strong_ptr = manager->GetServiceThread(); strong_ptr) {
118 strong_ptr->QueueSyncRequest(*parent, std::move(context)); 123 strong_ptr->QueueSyncRequest(*parent, std::move(context));
119 return ResultSuccess; 124 return ResultSuccess;
125 } else {
126 ASSERT_MSG(false, "strong_ptr was nullptr!");
120 } 127 }
121 128
122 return ResultSuccess; 129 return ResultSuccess;
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h
index 27b757ad2..9efd400bc 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;
32class KernelCore; 32class KernelCore;
33class KSession; 33class KSession;
34class SessionRequestHandler; 34class SessionRequestHandler;
35class SessionRequestManager;
35class KThread; 36class KThread;
36 37
37class KServerSession final : public KSynchronizationObject, 38class KServerSession final : public KSynchronizationObject,
@@ -46,7 +47,8 @@ public:
46 47
47 void Destroy() override; 48 void Destroy() override;
48 49
49 void Initialize(KSession* parent_, std::string&& name_); 50 void Initialize(KSession* parent_session_, std::string&& name_,
51 std::shared_ptr<SessionRequestManager> manager_);
50 52
51 KSession* GetParent() { 53 KSession* GetParent() {
52 return parent; 54 return parent;
@@ -104,16 +106,6 @@ public:
104 return manager; 106 return manager;
105 } 107 }
106 108
107 /// Gets the session request manager, which forwards requests to the underlying service
108 const std::shared_ptr<SessionRequestManager>& GetSessionRequestManager() const {
109 return manager;
110 }
111
112 /// Sets the session request manager, which forwards requests to the underlying service
113 void SetSessionRequestManager(std::shared_ptr<SessionRequestManager> manager_) {
114 manager = std::move(manager_);
115 }
116
117private: 109private:
118 /// Queues a sync request from the emulated application. 110 /// Queues a sync request from the emulated application.
119 ResultCode QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory); 111 ResultCode QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory);
@@ -131,9 +123,6 @@ private:
131 /// When set to True, converts the session to a domain at the end of the command 123 /// When set to True, converts the session to a domain at the end of the command
132 bool convert_to_domain{}; 124 bool convert_to_domain{};
133 125
134 /// Thread to dispatch service requests
135 std::weak_ptr<ServiceThread> service_thread;
136
137 /// KSession that owns this KServerSession 126 /// KSession that owns this KServerSession
138 KSession* parent{}; 127 KSession* parent{};
139}; 128};
diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp
index 025b8b555..940878e03 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_)
15 : KAutoObjectWithSlabHeapAndContainer{kernel_}, server{kernel_}, client{kernel_} {} 15 : KAutoObjectWithSlabHeapAndContainer{kernel_}, server{kernel_}, client{kernel_} {}
16KSession::~KSession() = default; 16KSession::~KSession() = default;
17 17
18void KSession::Initialize(KClientPort* port_, const std::string& name_) { 18void KSession::Initialize(KClientPort* port_, const std::string& name_,
19 std::shared_ptr<SessionRequestManager> manager_) {
19 // Increment reference count. 20 // Increment reference count.
20 // Because reference count is one on creation, this will result 21 // Because reference count is one on creation, this will result
21 // in a reference count of two. Thus, when both server and client are closed 22 // 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_) {
27 KAutoObject::Create(std::addressof(client)); 28 KAutoObject::Create(std::addressof(client));
28 29
29 // Initialize our sub sessions. 30 // Initialize our sub sessions.
30 server.Initialize(this, name_ + ":Server"); 31 server.Initialize(this, name_ + ":Server", manager_);
31 client.Initialize(this, name_ + ":Client"); 32 client.Initialize(this, name_ + ":Client");
32 33
33 // Set state and name. 34 // Set state and name.
diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h
index 4ddd080d2..62c328a68 100644
--- a/src/core/hle/kernel/k_session.h
+++ b/src/core/hle/kernel/k_session.h
@@ -13,6 +13,8 @@
13 13
14namespace Kernel { 14namespace Kernel {
15 15
16class SessionRequestManager;
17
16class KSession final : public KAutoObjectWithSlabHeapAndContainer<KSession, KAutoObjectWithList> { 18class KSession final : public KAutoObjectWithSlabHeapAndContainer<KSession, KAutoObjectWithList> {
17 KERNEL_AUTOOBJECT_TRAITS(KSession, KAutoObject); 19 KERNEL_AUTOOBJECT_TRAITS(KSession, KAutoObject);
18 20
@@ -20,7 +22,8 @@ public:
20 explicit KSession(KernelCore& kernel_); 22 explicit KSession(KernelCore& kernel_);
21 ~KSession() override; 23 ~KSession() override;
22 24
23 void Initialize(KClientPort* port_, const std::string& name_); 25 void Initialize(KClientPort* port_, const std::string& name_,
26 std::shared_ptr<SessionRequestManager> manager_ = nullptr);
24 27
25 void Finalize() override; 28 void Finalize() override;
26 29
diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp
index b7b83c151..bdb1db6d5 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_)
13 13
14KWritableEvent::~KWritableEvent() = default; 14KWritableEvent::~KWritableEvent() = default;
15 15
16void KWritableEvent::Initialize(KEvent* parent_, std::string&& name_) { 16void KWritableEvent::Initialize(KEvent* parent_event_, std::string&& name_) {
17 parent = parent_; 17 parent = parent_event_;
18 name = std::move(name_); 18 name = std::move(name_);
19 parent->GetReadableEvent().Open(); 19 parent->GetReadableEvent().Open();
20} 20}
diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp
index 6e5ba26a3..74cc45f1e 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) {
254 LOG_DEBUG(Service_NS, "called"); 254 LOG_DEBUG(Service_NS, "called");
255 255
256 // Create shared font memory object 256 // Create shared font memory object
257 auto& kernel = system.Kernel();
258
259 std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(), 257 std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font->data(),
260 impl->shared_font->size()); 258 impl->shared_font->size());
261 259
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp
index 7a15eeba0..4e1541630 100644
--- a/src/core/hle/service/service.cpp
+++ b/src/core/hle/service/service.cpp
@@ -93,8 +93,8 @@ namespace Service {
93 93
94ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_, 94ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_,
95 u32 max_sessions_, InvokerFn* handler_invoker_) 95 u32 max_sessions_, InvokerFn* handler_invoker_)
96 : system{system_}, service_name{service_name_}, max_sessions{max_sessions_}, 96 : SessionRequestHandler(system_.Kernel(), service_name_), system{system_},
97 handler_invoker{handler_invoker_} {} 97 service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {}
98 98
99ServiceFrameworkBase::~ServiceFrameworkBase() { 99ServiceFrameworkBase::~ServiceFrameworkBase() {
100 // Wait for other threads to release access before destroying 100 // Wait for other threads to release access before destroying
@@ -111,7 +111,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
111 port_installed = true; 111 port_installed = true;
112} 112}
113 113
114Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) { 114Kernel::KClientPort& ServiceFrameworkBase::CreatePort() {
115 const auto guard = LockService(); 115 const auto guard = LockService();
116 116
117 ASSERT(!port_installed); 117 ASSERT(!port_installed);
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h
index 4c048173b..ec757753c 100644
--- a/src/core/hle/service/service.h
+++ b/src/core/hle/service/service.h
@@ -23,6 +23,7 @@ namespace Kernel {
23class HLERequestContext; 23class HLERequestContext;
24class KClientPort; 24class KClientPort;
25class KServerSession; 25class KServerSession;
26class ServiceThread;
26} // namespace Kernel 27} // namespace Kernel
27 28
28namespace Service { 29namespace Service {
@@ -41,7 +42,7 @@ class ServiceManager;
41 42
42static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters) 43static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters)
43/// Arbitrary default number of maximum connections to an HLE service. 44/// Arbitrary default number of maximum connections to an HLE service.
44static const u32 DefaultMaxSessions = 10; 45static const u32 DefaultMaxSessions = 64;
45 46
46/** 47/**
47 * This is an non-templated base of ServiceFramework to reduce code bloat and compilation times, it 48 * This is an non-templated base of ServiceFramework to reduce code bloat and compilation times, it
@@ -74,7 +75,7 @@ public:
74 void InvokeRequestTipc(Kernel::HLERequestContext& ctx); 75 void InvokeRequestTipc(Kernel::HLERequestContext& ctx);
75 76
76 /// Creates a port pair and registers it on the kernel's global port registry. 77 /// Creates a port pair and registers it on the kernel's global port registry.
77 Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel); 78 Kernel::KClientPort& CreatePort();
78 79
79 /// Handles a synchronization request for the service. 80 /// Handles a synchronization request for the service.
80 ResultCode HandleSyncRequest(Kernel::KServerSession& session, 81 ResultCode HandleSyncRequest(Kernel::KServerSession& session,
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp
index 5fa5e0512..8b9418e0f 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) {
28} 28}
29 29
30void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { 30void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
31 // TODO(bunnei): This is just creating a new handle to the same Session. I assume this is wrong
32 // and that we probably want to actually make an entirely new Session, but we still need to
33 // verify this on hardware.
34
35 LOG_DEBUG(Service, "called"); 31 LOG_DEBUG(Service, "called");
36 32
37 auto& kernel = system.Kernel(); 33 auto& parent_session = *ctx.Session()->GetParent();
38 auto* session = ctx.Session()->GetParent(); 34 auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort();
39 auto* port = session->GetParent()->GetParent(); 35 auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager();
40 36
41 // Reserve a new session from the process resource limit. 37 // Create a session.
42 Kernel::KScopedResourceReservation session_reservation( 38 Kernel::KClientSession* session{};
43 kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions); 39 const ResultCode result = parent_port.CreateSession(std::addressof(session), session_manager);
44 if (!session_reservation.Succeeded()) { 40 if (result.IsError()) {
41 LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw);
45 IPC::ResponseBuilder rb{ctx, 2}; 42 IPC::ResponseBuilder rb{ctx, 2};
46 rb.Push(Kernel::ResultLimitReached); 43 rb.Push(result);
47 } 44 }
48 45
49 // Create a new session.
50 auto* clone = Kernel::KSession::Create(kernel);
51 clone->Initialize(&port->GetClientPort(), session->GetName());
52
53 // Commit the session reservation.
54 session_reservation.Commit();
55
56 // Enqueue the session with the named port.
57 port->EnqueueSession(&clone->GetServerSession());
58
59 // Set the session request manager.
60 clone->GetServerSession().SetSessionRequestManager(
61 session->GetServerSession().GetSessionRequestManager());
62
63 // We succeeded. 46 // We succeeded.
64 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 47 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
65 rb.Push(ResultSuccess); 48 rb.Push(ResultSuccess);
66 rb.PushMoveObjects(clone->GetClientSession()); 49 rb.PushMoveObjects(session);
67} 50}
68 51
69void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { 52void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index d8b20a3f2..bffa9ffcb 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
46 self.sm_interface = sm; 46 self.sm_interface = sm;
47 self.controller_interface = std::make_unique<Controller>(system); 47 self.controller_interface = std::make_unique<Controller>(system);
48 48
49 return sm->CreatePort(system.Kernel()); 49 return sm->CreatePort();
50} 50}
51 51
52ResultVal<Kernel::KServerPort*> ServiceManager::RegisterService(std::string name, 52ResultVal<Kernel::KServerPort*> ServiceManager::RegisterService(std::string name,