diff options
| author | 2021-06-06 22:52:07 -0700 | |
|---|---|---|
| committer | 2021-06-06 22:52:07 -0700 | |
| commit | 28eb8c83d479403b5da88ae7d3d2a1c6b81a6552 (patch) | |
| tree | 43b28bb3b8df05e3f19fe4a151571dedd7171255 /src | |
| parent | Merge pull request #6400 from ameerj/disable-uniform-simplify (diff) | |
| parent | hle: kernel: KServerSession: Use ASSERT_MSG where appropriate. (diff) | |
| download | yuzu-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')
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 | ||
| 31 | namespace Kernel { | 31 | namespace Kernel { |
| 32 | 32 | ||
| 33 | SessionRequestHandler::SessionRequestHandler() = default; | 33 | SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_) |
| 34 | : kernel{kernel_}, service_thread{kernel.CreateServiceThread(service_name_)} {} | ||
| 34 | 35 | ||
| 35 | SessionRequestHandler::~SessionRequestHandler() = default; | 36 | SessionRequestHandler::~SessionRequestHandler() { |
| 37 | kernel.ReleaseServiceThread(service_thread); | ||
| 38 | } | ||
| 39 | |||
| 40 | SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {} | ||
| 41 | |||
| 42 | SessionRequestManager::~SessionRequestManager() = default; | ||
| 36 | 43 | ||
| 37 | void SessionRequestHandler::ClientConnected(KServerSession* session) { | 44 | void 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; | |||
| 46 | class KReadableEvent; | 46 | class KReadableEvent; |
| 47 | class KSession; | 47 | class KSession; |
| 48 | class KWritableEvent; | 48 | class KWritableEvent; |
| 49 | class ServiceThread; | ||
| 49 | 50 | ||
| 50 | enum class ThreadWakeupReason; | 51 | enum class ThreadWakeupReason; |
| 51 | 52 | ||
| @@ -56,7 +57,7 @@ enum class ThreadWakeupReason; | |||
| 56 | */ | 57 | */ |
| 57 | class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> { | 58 | class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> { |
| 58 | public: | 59 | public: |
| 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 | |||
| 92 | protected: | ||
| 93 | KernelCore& kernel; | ||
| 94 | std::weak_ptr<ServiceThread> service_thread; | ||
| 86 | }; | 95 | }; |
| 87 | 96 | ||
| 88 | using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>; | 97 | using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>; |
| @@ -94,7 +103,8 @@ using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>; | |||
| 94 | */ | 103 | */ |
| 95 | class SessionRequestManager final { | 104 | class SessionRequestManager final { |
| 96 | public: | 105 | public: |
| 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 | |||
| 145 | private: | 159 | private: |
| 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 | |||
| 164 | private: | ||
| 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 | ||
| 16 | namespace Kernel { | 17 | namespace Kernel { |
| @@ -175,7 +176,7 @@ private: | |||
| 175 | 176 | ||
| 176 | class KAutoObjectWithListContainer; | 177 | class KAutoObjectWithListContainer; |
| 177 | 178 | ||
| 178 | class KAutoObjectWithList : public KAutoObject { | 179 | class KAutoObjectWithList : public KAutoObject, public boost::intrusive::set_base_hook<> { |
| 179 | public: | 180 | public: |
| 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 | |||
| 195 | public: | 200 | public: |
| 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 | ||
| 204 | private: | 209 | private: |
| 205 | friend class KAutoObjectWithListContainer; | 210 | friend class KAutoObjectWithListContainer; |
| 206 | |||
| 207 | Common::IntrusiveRedBlackTreeNode list_node; | ||
| 208 | }; | 211 | }; |
| 209 | 212 | ||
| 210 | template <typename T> | 213 | 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 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 { | |||
| 9 | void KAutoObjectWithListContainer::Register(KAutoObjectWithList* obj) { | 9 | void 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 | ||
| 15 | void KAutoObjectWithListContainer::Unregister(KAutoObjectWithList* obj) { | 15 | void 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 | ||
| 21 | size_t KAutoObjectWithListContainer::GetOwnedCount(KProcess* owner) { | 21 | 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 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 | ||
| 25 | public: | 27 | public: |
| 26 | using ListType = Common::IntrusiveRedBlackTreeMemberTraits< | 28 | using ListType = boost::intrusive::rbtree<KAutoObjectWithList>; |
| 27 | &KAutoObjectWithList::list_node>::TreeType<KAutoObjectWithList>; | ||
| 28 | 29 | ||
| 29 | public: | 30 | public: |
| 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 { | |||
| 16 | KClientPort::KClientPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} | 16 | KClientPort::KClientPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} |
| 17 | KClientPort::~KClientPort() = default; | 17 | KClientPort::~KClientPort() = default; |
| 18 | 18 | ||
| 19 | void KClientPort::Initialize(KPort* parent_, s32 max_sessions_, std::string&& name_) { | 19 | void 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 | ||
| 59 | ResultCode KClientPort::CreateSession(KClientSession** out) { | 59 | ResultCode 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 { | |||
| 16 | class KClientSession; | 16 | class KClientSession; |
| 17 | class KernelCore; | 17 | class KernelCore; |
| 18 | class KPort; | 18 | class KPort; |
| 19 | class SessionRequestManager; | ||
| 19 | 20 | ||
| 20 | class KClientPort final : public KSynchronizationObject { | 21 | class 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 | ||
| 57 | private: | 59 | private: |
| 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 { | |||
| 17 | KServerPort::KServerPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} | 17 | KServerPort::KServerPort(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} |
| 18 | KServerPort::~KServerPort() = default; | 18 | KServerPort::~KServerPort() = default; |
| 19 | 19 | ||
| 20 | void KServerPort::Initialize(KPort* parent_, std::string&& name_) { | 20 | void 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 | ||
| 24 | namespace Kernel { | 26 | namespace Kernel { |
| 25 | 27 | ||
| 26 | KServerSession::KServerSession(KernelCore& kernel_) | 28 | KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} |
| 27 | : KSynchronizationObject{kernel_}, manager{std::make_shared<SessionRequestManager>()} {} | ||
| 28 | 29 | ||
| 29 | KServerSession::~KServerSession() { | 30 | KServerSession::~KServerSession() {} |
| 30 | kernel.ReleaseServiceThread(service_thread); | ||
| 31 | } | ||
| 32 | 31 | ||
| 33 | void KServerSession::Initialize(KSession* parent_, std::string&& name_) { | 32 | void 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 | ||
| 40 | void KServerSession::Destroy() { | 45 | void 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; | |||
| 32 | class KernelCore; | 32 | class KernelCore; |
| 33 | class KSession; | 33 | class KSession; |
| 34 | class SessionRequestHandler; | 34 | class SessionRequestHandler; |
| 35 | class SessionRequestManager; | ||
| 35 | class KThread; | 36 | class KThread; |
| 36 | 37 | ||
| 37 | class KServerSession final : public KSynchronizationObject, | 38 | class 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 | |||
| 117 | private: | 109 | private: |
| 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_} {} |
| 16 | KSession::~KSession() = default; | 16 | KSession::~KSession() = default; |
| 17 | 17 | ||
| 18 | void KSession::Initialize(KClientPort* port_, const std::string& name_) { | 18 | void 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 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | 15 | ||
| 16 | class SessionRequestManager; | ||
| 17 | |||
| 16 | class KSession final : public KAutoObjectWithSlabHeapAndContainer<KSession, KAutoObjectWithList> { | 18 | class 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 | ||
| 14 | KWritableEvent::~KWritableEvent() = default; | 14 | KWritableEvent::~KWritableEvent() = default; |
| 15 | 15 | ||
| 16 | void KWritableEvent::Initialize(KEvent* parent_, std::string&& name_) { | 16 | void 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 | ||
| 94 | ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_, | 94 | ServiceFrameworkBase::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 | ||
| 99 | ServiceFrameworkBase::~ServiceFrameworkBase() { | 99 | ServiceFrameworkBase::~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 | ||
| 114 | Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) { | 114 | Kernel::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 { | |||
| 23 | class HLERequestContext; | 23 | class HLERequestContext; |
| 24 | class KClientPort; | 24 | class KClientPort; |
| 25 | class KServerSession; | 25 | class KServerSession; |
| 26 | class ServiceThread; | ||
| 26 | } // namespace Kernel | 27 | } // namespace Kernel |
| 27 | 28 | ||
| 28 | namespace Service { | 29 | namespace Service { |
| @@ -41,7 +42,7 @@ class ServiceManager; | |||
| 41 | 42 | ||
| 42 | static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 characters) | 43 | static 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. |
| 44 | static const u32 DefaultMaxSessions = 10; | 45 | static 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 | ||
| 30 | void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { | 30 | void 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 | ||
| 69 | void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { | 52 | 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 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 | ||
| 52 | ResultVal<Kernel::KServerPort*> ServiceManager::RegisterService(std::string name, | 52 | ResultVal<Kernel::KServerPort*> ServiceManager::RegisterService(std::string name, |