diff options
| author | 2021-04-13 17:48:37 -0700 | |
|---|---|---|
| committer | 2021-05-05 16:40:51 -0700 | |
| commit | 7444963bbb300cff269e410948de7fa577f5ff16 (patch) | |
| tree | 6e0000cb345dc02c8f2ca38958b7c90383f45b03 /src | |
| parent | hle: kernel: svc: Migrate GetThreadContext, GetThreadCoreMask. (diff) | |
| download | yuzu-7444963bbb300cff269e410948de7fa577f5ff16.tar.gz yuzu-7444963bbb300cff269e410948de7fa577f5ff16.tar.xz yuzu-7444963bbb300cff269e410948de7fa577f5ff16.zip | |
hle: kernel: Migrate KSession, KClientSession, and KServerSession to KAutoObject.
Diffstat (limited to 'src')
31 files changed, 412 insertions, 356 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 569b4802e..e30a30823 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -146,8 +146,6 @@ add_library(core STATIC | |||
| 146 | hle/kernel/board/nintendo/nx/secure_monitor.h | 146 | hle/kernel/board/nintendo/nx/secure_monitor.h |
| 147 | hle/kernel/client_port.cpp | 147 | hle/kernel/client_port.cpp |
| 148 | hle/kernel/client_port.h | 148 | hle/kernel/client_port.h |
| 149 | hle/kernel/client_session.cpp | ||
| 150 | hle/kernel/client_session.h | ||
| 151 | hle/kernel/code_set.cpp | 149 | hle/kernel/code_set.cpp |
| 152 | hle/kernel/code_set.h | 150 | hle/kernel/code_set.h |
| 153 | hle/kernel/svc_results.h | 151 | hle/kernel/svc_results.h |
| @@ -170,6 +168,8 @@ add_library(core STATIC | |||
| 170 | hle/kernel/k_affinity_mask.h | 168 | hle/kernel/k_affinity_mask.h |
| 171 | hle/kernel/k_class_token.cpp | 169 | hle/kernel/k_class_token.cpp |
| 172 | hle/kernel/k_class_token.h | 170 | hle/kernel/k_class_token.h |
| 171 | hle/kernel/k_client_session.cpp | ||
| 172 | hle/kernel/k_client_session.h | ||
| 173 | hle/kernel/k_condition_variable.cpp | 173 | hle/kernel/k_condition_variable.cpp |
| 174 | hle/kernel/k_condition_variable.h | 174 | hle/kernel/k_condition_variable.h |
| 175 | hle/kernel/k_event.cpp | 175 | hle/kernel/k_event.cpp |
| @@ -205,6 +205,10 @@ add_library(core STATIC | |||
| 205 | hle/kernel/k_scoped_lock.h | 205 | hle/kernel/k_scoped_lock.h |
| 206 | hle/kernel/k_scoped_resource_reservation.h | 206 | hle/kernel/k_scoped_resource_reservation.h |
| 207 | hle/kernel/k_scoped_scheduler_lock_and_sleep.h | 207 | hle/kernel/k_scoped_scheduler_lock_and_sleep.h |
| 208 | hle/kernel/k_server_session.cpp | ||
| 209 | hle/kernel/k_server_session.h | ||
| 210 | hle/kernel/k_session.cpp | ||
| 211 | hle/kernel/k_session.h | ||
| 208 | hle/kernel/k_shared_memory.cpp | 212 | hle/kernel/k_shared_memory.cpp |
| 209 | hle/kernel/k_shared_memory.h | 213 | hle/kernel/k_shared_memory.h |
| 210 | hle/kernel/k_slab_heap.h | 214 | hle/kernel/k_slab_heap.h |
| @@ -233,12 +237,8 @@ add_library(core STATIC | |||
| 233 | hle/kernel/process_capability.h | 237 | hle/kernel/process_capability.h |
| 234 | hle/kernel/server_port.cpp | 238 | hle/kernel/server_port.cpp |
| 235 | hle/kernel/server_port.h | 239 | hle/kernel/server_port.h |
| 236 | hle/kernel/server_session.cpp | ||
| 237 | hle/kernel/server_session.h | ||
| 238 | hle/kernel/service_thread.cpp | 240 | hle/kernel/service_thread.cpp |
| 239 | hle/kernel/service_thread.h | 241 | hle/kernel/service_thread.h |
| 240 | hle/kernel/session.cpp | ||
| 241 | hle/kernel/session.h | ||
| 242 | hle/kernel/slab_helpers.h | 242 | hle/kernel/slab_helpers.h |
| 243 | hle/kernel/svc.cpp | 243 | hle/kernel/svc.cpp |
| 244 | hle/kernel/svc.h | 244 | hle/kernel/svc.h |
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 8f12616bd..99b7d3d82 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h | |||
| @@ -14,11 +14,9 @@ | |||
| 14 | #include "common/common_types.h" | 14 | #include "common/common_types.h" |
| 15 | #include "core/hle/ipc.h" | 15 | #include "core/hle/ipc.h" |
| 16 | #include "core/hle/kernel/client_port.h" | 16 | #include "core/hle/kernel/client_port.h" |
| 17 | #include "core/hle/kernel/client_session.h" | ||
| 18 | #include "core/hle/kernel/hle_ipc.h" | 17 | #include "core/hle/kernel/hle_ipc.h" |
| 18 | #include "core/hle/kernel/k_session.h" | ||
| 19 | #include "core/hle/kernel/object.h" | 19 | #include "core/hle/kernel/object.h" |
| 20 | #include "core/hle/kernel/server_session.h" | ||
| 21 | #include "core/hle/kernel/session.h" | ||
| 22 | #include "core/hle/result.h" | 20 | #include "core/hle/result.h" |
| 23 | 21 | ||
| 24 | namespace IPC { | 22 | namespace IPC { |
| @@ -137,9 +135,11 @@ public: | |||
| 137 | if (context->Session()->IsDomain()) { | 135 | if (context->Session()->IsDomain()) { |
| 138 | context->AddDomainObject(std::move(iface)); | 136 | context->AddDomainObject(std::move(iface)); |
| 139 | } else { | 137 | } else { |
| 140 | auto [client, server] = Kernel::Session::Create(kernel, iface->GetServiceName()); | 138 | auto* session = Kernel::KSession::Create(kernel); |
| 141 | context->AddMoveObject(client.get()); | 139 | session->Initialize(iface->GetServiceName()); |
| 142 | iface->ClientConnected(std::move(client), std::move(server)); | 140 | |
| 141 | context->AddMoveObject(&session->GetClientSession()); | ||
| 142 | iface->ClientConnected(session); | ||
| 143 | } | 143 | } |
| 144 | } | 144 | } |
| 145 | 145 | ||
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index d856b83e3..ce88da1c3 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp | |||
| @@ -3,11 +3,10 @@ | |||
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| 5 | #include "core/hle/kernel/client_port.h" | 5 | #include "core/hle/kernel/client_port.h" |
| 6 | #include "core/hle/kernel/client_session.h" | ||
| 7 | #include "core/hle/kernel/hle_ipc.h" | 6 | #include "core/hle/kernel/hle_ipc.h" |
| 7 | #include "core/hle/kernel/k_session.h" | ||
| 8 | #include "core/hle/kernel/object.h" | 8 | #include "core/hle/kernel/object.h" |
| 9 | #include "core/hle/kernel/server_port.h" | 9 | #include "core/hle/kernel/server_port.h" |
| 10 | #include "core/hle/kernel/session.h" | ||
| 11 | #include "core/hle/kernel/svc_results.h" | 10 | #include "core/hle/kernel/svc_results.h" |
| 12 | 11 | ||
| 13 | namespace Kernel { | 12 | namespace Kernel { |
| @@ -19,21 +18,22 @@ std::shared_ptr<ServerPort> ClientPort::GetServerPort() const { | |||
| 19 | return server_port; | 18 | return server_port; |
| 20 | } | 19 | } |
| 21 | 20 | ||
| 22 | ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() { | 21 | ResultVal<KClientSession*> ClientPort::Connect() { |
| 23 | if (active_sessions >= max_sessions) { | 22 | if (active_sessions >= max_sessions) { |
| 24 | return ResultOutOfSessions; | 23 | return ResultOutOfSessions; |
| 25 | } | 24 | } |
| 26 | active_sessions++; | 25 | active_sessions++; |
| 27 | 26 | ||
| 28 | auto [client, server] = Kernel::Session::Create(kernel, name); | 27 | auto* session = Kernel::KSession::Create(kernel); |
| 28 | session->Initialize(name + ":ClientPort"); | ||
| 29 | 29 | ||
| 30 | if (server_port->HasHLEHandler()) { | 30 | if (server_port->HasHLEHandler()) { |
| 31 | server_port->GetHLEHandler()->ClientConnected(client, std::move(server)); | 31 | server_port->GetHLEHandler()->ClientConnected(session); |
| 32 | } else { | 32 | } else { |
| 33 | server_port->AppendPendingSession(std::move(server)); | 33 | server_port->AppendPendingSession(std::addressof(session->GetServerSession())); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | return MakeResult(std::move(client)); | 36 | return MakeResult(std::addressof(session->GetClientSession())); |
| 37 | } | 37 | } |
| 38 | 38 | ||
| 39 | void ClientPort::ConnectionClosed() { | 39 | void ClientPort::ConnectionClosed() { |
diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index 77559ebf9..0b20fef40 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h | |||
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | 15 | ||
| 16 | class ClientSession; | 16 | class KClientSession; |
| 17 | class KernelCore; | 17 | class KernelCore; |
| 18 | class ServerPort; | 18 | class ServerPort; |
| 19 | 19 | ||
| @@ -43,7 +43,7 @@ public: | |||
| 43 | * waiting on it to awake. | 43 | * waiting on it to awake. |
| 44 | * @returns ClientSession The client endpoint of the created Session pair, or error code. | 44 | * @returns ClientSession The client endpoint of the created Session pair, or error code. |
| 45 | */ | 45 | */ |
| 46 | ResultVal<std::shared_ptr<ClientSession>> Connect(); | 46 | ResultVal<KClientSession*> Connect(); |
| 47 | 47 | ||
| 48 | /** | 48 | /** |
| 49 | * Signifies that a previously active connection has been closed, | 49 | * Signifies that a previously active connection has been closed, |
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp deleted file mode 100644 index fa9cad498..000000000 --- a/src/core/hle/kernel/client_session.cpp +++ /dev/null | |||
| @@ -1,52 +0,0 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/client_session.h" | ||
| 6 | #include "core/hle/kernel/hle_ipc.h" | ||
| 7 | #include "core/hle/kernel/k_thread.h" | ||
| 8 | #include "core/hle/kernel/server_session.h" | ||
| 9 | #include "core/hle/kernel/session.h" | ||
| 10 | #include "core/hle/kernel/svc_results.h" | ||
| 11 | #include "core/hle/result.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | |||
| 15 | ClientSession::ClientSession(KernelCore& kernel) : KSynchronizationObject{kernel} {} | ||
| 16 | |||
| 17 | ClientSession::~ClientSession() { | ||
| 18 | // This destructor will be called automatically when the last ClientSession handle is closed by | ||
| 19 | // the emulated application. | ||
| 20 | if (parent->Server()) { | ||
| 21 | parent->Server()->ClientDisconnected(); | ||
| 22 | } | ||
| 23 | } | ||
| 24 | |||
| 25 | bool ClientSession::IsSignaled() const { | ||
| 26 | UNIMPLEMENTED(); | ||
| 27 | return true; | ||
| 28 | } | ||
| 29 | |||
| 30 | ResultVal<std::shared_ptr<ClientSession>> ClientSession::Create(KernelCore& kernel, | ||
| 31 | std::shared_ptr<Session> parent, | ||
| 32 | std::string name) { | ||
| 33 | std::shared_ptr<ClientSession> client_session{std::make_shared<ClientSession>(kernel)}; | ||
| 34 | |||
| 35 | client_session->name = std::move(name); | ||
| 36 | client_session->parent = std::move(parent); | ||
| 37 | |||
| 38 | return MakeResult(std::move(client_session)); | ||
| 39 | } | ||
| 40 | |||
| 41 | ResultCode ClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, | ||
| 42 | Core::Timing::CoreTiming& core_timing) { | ||
| 43 | // Keep ServerSession alive until we're done working with it. | ||
| 44 | if (!parent->Server()) { | ||
| 45 | return ResultSessionClosed; | ||
| 46 | } | ||
| 47 | |||
| 48 | // Signal the server session that new data is available | ||
| 49 | return parent->Server()->HandleSyncRequest(std::move(thread), memory, core_timing); | ||
| 50 | } | ||
| 51 | |||
| 52 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/handle_table.cpp b/src/core/hle/kernel/handle_table.cpp index adfcd3c5b..ddb1e6fb2 100644 --- a/src/core/hle/kernel/handle_table.cpp +++ b/src/core/hle/kernel/handle_table.cpp | |||
| @@ -56,7 +56,10 @@ ResultVal<Handle> HandleTable::Create(Object* obj) { | |||
| 56 | case HandleType::Event: | 56 | case HandleType::Event: |
| 57 | case HandleType::Process: | 57 | case HandleType::Process: |
| 58 | case HandleType::ReadableEvent: | 58 | case HandleType::ReadableEvent: |
| 59 | case HandleType::WritableEvent: { | 59 | case HandleType::WritableEvent: |
| 60 | case HandleType::ClientSession: | ||
| 61 | case HandleType::ServerSession: | ||
| 62 | case HandleType::Session: { | ||
| 60 | Handle handle{}; | 63 | Handle handle{}; |
| 61 | Add(&handle, reinterpret_cast<KAutoObject*>(obj), {}); | 64 | Add(&handle, reinterpret_cast<KAutoObject*>(obj), {}); |
| 62 | return MakeResult<Handle>(handle); | 65 | return MakeResult<Handle>(handle); |
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 1e831aaca..d647d9dd3 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp | |||
| @@ -19,12 +19,12 @@ | |||
| 19 | #include "core/hle/kernel/k_readable_event.h" | 19 | #include "core/hle/kernel/k_readable_event.h" |
| 20 | #include "core/hle/kernel/k_scheduler.h" | 20 | #include "core/hle/kernel/k_scheduler.h" |
| 21 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 21 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 22 | #include "core/hle/kernel/k_server_session.h" | ||
| 22 | #include "core/hle/kernel/k_thread.h" | 23 | #include "core/hle/kernel/k_thread.h" |
| 23 | #include "core/hle/kernel/k_writable_event.h" | 24 | #include "core/hle/kernel/k_writable_event.h" |
| 24 | #include "core/hle/kernel/kernel.h" | 25 | #include "core/hle/kernel/kernel.h" |
| 25 | #include "core/hle/kernel/object.h" | 26 | #include "core/hle/kernel/object.h" |
| 26 | #include "core/hle/kernel/process.h" | 27 | #include "core/hle/kernel/process.h" |
| 27 | #include "core/hle/kernel/server_session.h" | ||
| 28 | #include "core/hle/kernel/svc_results.h" | 28 | #include "core/hle/kernel/svc_results.h" |
| 29 | #include "core/hle/kernel/time_manager.h" | 29 | #include "core/hle/kernel/time_manager.h" |
| 30 | #include "core/memory.h" | 30 | #include "core/memory.h" |
| @@ -35,24 +35,19 @@ SessionRequestHandler::SessionRequestHandler() = default; | |||
| 35 | 35 | ||
| 36 | SessionRequestHandler::~SessionRequestHandler() = default; | 36 | SessionRequestHandler::~SessionRequestHandler() = default; |
| 37 | 37 | ||
| 38 | void SessionRequestHandler::ClientConnected(std::shared_ptr<ClientSession> client_session, | 38 | void SessionRequestHandler::ClientConnected(KSession* session) { |
| 39 | std::shared_ptr<ServerSession> server_session) { | 39 | session->GetServerSession().SetHleHandler(shared_from_this()); |
| 40 | server_session->SetHleHandler(shared_from_this()); | 40 | sessions.push_back(session); |
| 41 | client_sessions.push_back(std::move(client_session)); | ||
| 42 | server_sessions.push_back(std::move(server_session)); | ||
| 43 | } | 41 | } |
| 44 | 42 | ||
| 45 | void SessionRequestHandler::ClientDisconnected( | 43 | void SessionRequestHandler::ClientDisconnected(KSession* session) { |
| 46 | const std::shared_ptr<ServerSession>& server_session) { | 44 | session->GetServerSession().SetHleHandler(nullptr); |
| 47 | server_session->SetHleHandler(nullptr); | 45 | boost::range::remove_erase(sessions, session); |
| 48 | boost::range::remove_erase(server_sessions, server_session); | ||
| 49 | } | 46 | } |
| 50 | 47 | ||
| 51 | HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_, | 48 | HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_, |
| 52 | std::shared_ptr<ServerSession> server_session_, | 49 | KServerSession* server_session_, KThread* thread_) |
| 53 | KThread* thread_) | 50 | : server_session(server_session_), thread(thread_), kernel{kernel_}, memory{memory_} { |
| 54 | : server_session(std::move(server_session_)), | ||
| 55 | thread(thread_), kernel{kernel_}, memory{memory_} { | ||
| 56 | cmd_buf[0] = 0; | 51 | cmd_buf[0] = 0; |
| 57 | } | 52 | } |
| 58 | 53 | ||
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 74a95bc76..dc5c3b47d 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h | |||
| @@ -39,10 +39,10 @@ class HandleTable; | |||
| 39 | class HLERequestContext; | 39 | class HLERequestContext; |
| 40 | class KernelCore; | 40 | class KernelCore; |
| 41 | class Process; | 41 | class Process; |
| 42 | class ClientSession; | 42 | class KServerSession; |
| 43 | class ServerSession; | ||
| 44 | class KThread; | 43 | class KThread; |
| 45 | class KReadableEvent; | 44 | class KReadableEvent; |
| 45 | class KSession; | ||
| 46 | class KWritableEvent; | 46 | class KWritableEvent; |
| 47 | 47 | ||
| 48 | enum class ThreadWakeupReason; | 48 | enum class ThreadWakeupReason; |
| @@ -72,22 +72,20 @@ public: | |||
| 72 | * associated ServerSession alive for the duration of the connection. | 72 | * associated ServerSession alive for the duration of the connection. |
| 73 | * @param server_session Owning pointer to the ServerSession associated with the connection. | 73 | * @param server_session Owning pointer to the ServerSession associated with the connection. |
| 74 | */ | 74 | */ |
| 75 | void ClientConnected( | 75 | void ClientConnected(KSession* session); |
| 76 | std::shared_ptr<ClientSession> client_session, std::shared_ptr<ServerSession> server_session); | ||
| 77 | 76 | ||
| 78 | /** | 77 | /** |
| 79 | * Signals that a client has just disconnected from this HLE handler and releases the | 78 | * Signals that a client has just disconnected from this HLE handler and releases the |
| 80 | * associated ServerSession. | 79 | * associated ServerSession. |
| 81 | * @param server_session ServerSession associated with the connection. | 80 | * @param server_session ServerSession associated with the connection. |
| 82 | */ | 81 | */ |
| 83 | void ClientDisconnected(const std::shared_ptr<ServerSession>& server_session); | 82 | void ClientDisconnected(KSession* session); |
| 84 | 83 | ||
| 85 | protected: | 84 | protected: |
| 86 | /// List of sessions that are connected to this handler. | 85 | /// List of sessions that are connected to this handler. |
| 87 | /// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list | 86 | /// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list |
| 88 | /// for the duration of the connection. | 87 | /// for the duration of the connection. |
| 89 | std::vector<std::shared_ptr<ClientSession>> client_sessions; | 88 | std::vector<KSession*> sessions; |
| 90 | std::vector<std::shared_ptr<ServerSession>> server_sessions; | ||
| 91 | }; | 89 | }; |
| 92 | 90 | ||
| 93 | /** | 91 | /** |
| @@ -112,7 +110,7 @@ protected: | |||
| 112 | class HLERequestContext { | 110 | class HLERequestContext { |
| 113 | public: | 111 | public: |
| 114 | explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory, | 112 | explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory, |
| 115 | std::shared_ptr<ServerSession> session, KThread* thread); | 113 | KServerSession* session, KThread* thread); |
| 116 | ~HLERequestContext(); | 114 | ~HLERequestContext(); |
| 117 | 115 | ||
| 118 | /// Returns a pointer to the IPC command buffer for this request. | 116 | /// Returns a pointer to the IPC command buffer for this request. |
| @@ -124,7 +122,7 @@ public: | |||
| 124 | * Returns the session through which this request was made. This can be used as a map key to | 122 | * Returns the session through which this request was made. This can be used as a map key to |
| 125 | * access per-client data on services. | 123 | * access per-client data on services. |
| 126 | */ | 124 | */ |
| 127 | const std::shared_ptr<Kernel::ServerSession>& Session() const { | 125 | Kernel::KServerSession* Session() { |
| 128 | return server_session; | 126 | return server_session; |
| 129 | } | 127 | } |
| 130 | 128 | ||
| @@ -288,7 +286,7 @@ private: | |||
| 288 | void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); | 286 | void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming); |
| 289 | 287 | ||
| 290 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; | 288 | std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf; |
| 291 | std::shared_ptr<Kernel::ServerSession> server_session; | 289 | Kernel::KServerSession* server_session{}; |
| 292 | KThread* thread; | 290 | KThread* thread; |
| 293 | 291 | ||
| 294 | // TODO(yuriks): Check common usage of this and optimize size accordingly | 292 | // TODO(yuriks): Check common usage of this and optimize size accordingly |
diff --git a/src/core/hle/kernel/init/init_slab_setup.cpp b/src/core/hle/kernel/init/init_slab_setup.cpp index b292f7db2..84d509d52 100644 --- a/src/core/hle/kernel/init/init_slab_setup.cpp +++ b/src/core/hle/kernel/init/init_slab_setup.cpp | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include "core/hle/kernel/k_event.h" | 12 | #include "core/hle/kernel/k_event.h" |
| 13 | #include "core/hle/kernel/k_memory_layout.h" | 13 | #include "core/hle/kernel/k_memory_layout.h" |
| 14 | #include "core/hle/kernel/k_memory_manager.h" | 14 | #include "core/hle/kernel/k_memory_manager.h" |
| 15 | #include "core/hle/kernel/k_session.h" | ||
| 15 | #include "core/hle/kernel/k_shared_memory.h" | 16 | #include "core/hle/kernel/k_shared_memory.h" |
| 16 | #include "core/hle/kernel/k_system_control.h" | 17 | #include "core/hle/kernel/k_system_control.h" |
| 17 | #include "core/hle/kernel/k_thread.h" | 18 | #include "core/hle/kernel/k_thread.h" |
| @@ -27,7 +28,8 @@ namespace Kernel::Init { | |||
| 27 | HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \ | 28 | HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \ |
| 28 | HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \ | 29 | HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \ |
| 29 | HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ | 30 | HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \ |
| 30 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) | 31 | HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \ |
| 32 | HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__) | ||
| 31 | 33 | ||
| 32 | namespace { | 34 | namespace { |
| 33 | 35 | ||
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp new file mode 100644 index 000000000..0618dc246 --- /dev/null +++ b/src/core/hle/kernel/k_client_session.cpp | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/hle_ipc.h" | ||
| 6 | #include "core/hle/kernel/k_client_session.h" | ||
| 7 | #include "core/hle/kernel/k_server_session.h" | ||
| 8 | #include "core/hle/kernel/k_session.h" | ||
| 9 | #include "core/hle/kernel/k_thread.h" | ||
| 10 | #include "core/hle/kernel/svc_results.h" | ||
| 11 | #include "core/hle/result.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | |||
| 15 | KClientSession::KClientSession(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {} | ||
| 16 | KClientSession::~KClientSession() = default; | ||
| 17 | |||
| 18 | void KClientSession::Destroy() { | ||
| 19 | parent->OnClientClosed(); | ||
| 20 | parent->Close(); | ||
| 21 | } | ||
| 22 | |||
| 23 | void KClientSession::OnServerClosed() {} | ||
| 24 | |||
| 25 | ResultCode KClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, | ||
| 26 | Core::Timing::CoreTiming& core_timing) { | ||
| 27 | // Signal the server session that new data is available | ||
| 28 | return parent->GetServerSession().HandleSyncRequest(thread, memory, core_timing); | ||
| 29 | } | ||
| 30 | |||
| 31 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/k_client_session.h index 7a1d15d0c..c4b193773 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/k_client_session.h | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | 1 | // Copyright 2021 yuzu emulator team |
| 2 | // Licensed under GPLv2 or any later version | 2 | // Licensed under GPLv2 or any later version |
| 3 | // Refer to the license.txt file included. | 3 | // Refer to the license.txt file included. |
| 4 | 4 | ||
| @@ -7,7 +7,9 @@ | |||
| 7 | #include <memory> | 7 | #include <memory> |
| 8 | #include <string> | 8 | #include <string> |
| 9 | 9 | ||
| 10 | #include "core/hle/kernel/k_auto_object.h" | ||
| 10 | #include "core/hle/kernel/k_synchronization_object.h" | 11 | #include "core/hle/kernel/k_synchronization_object.h" |
| 12 | #include "core/hle/kernel/slab_helpers.h" | ||
| 11 | #include "core/hle/result.h" | 13 | #include "core/hle/result.h" |
| 12 | 14 | ||
| 13 | union ResultCode; | 15 | union ResultCode; |
| @@ -23,43 +25,53 @@ class CoreTiming; | |||
| 23 | namespace Kernel { | 25 | namespace Kernel { |
| 24 | 26 | ||
| 25 | class KernelCore; | 27 | class KernelCore; |
| 26 | class Session; | 28 | class KSession; |
| 27 | class KThread; | 29 | class KThread; |
| 28 | 30 | ||
| 29 | class ClientSession final : public KSynchronizationObject { | 31 | class KClientSession final |
| 30 | public: | 32 | : public KAutoObjectWithSlabHeapAndContainer<KClientSession, KAutoObjectWithList> { |
| 31 | explicit ClientSession(KernelCore& kernel); | 33 | KERNEL_AUTOOBJECT_TRAITS(KClientSession, KAutoObject); |
| 32 | ~ClientSession() override; | ||
| 33 | 34 | ||
| 34 | friend class Session; | 35 | public: |
| 36 | explicit KClientSession(KernelCore& kernel); | ||
| 37 | virtual ~KClientSession(); | ||
| 35 | 38 | ||
| 36 | std::string GetTypeName() const override { | 39 | void Initialize(KSession* parent_, std::string&& name_) { |
| 37 | return "ClientSession"; | 40 | // Set member variables. |
| 41 | parent = parent_; | ||
| 42 | name = std::move(name_); | ||
| 38 | } | 43 | } |
| 39 | 44 | ||
| 40 | std::string GetName() const override { | 45 | virtual void Destroy() override; |
| 41 | return name; | 46 | static void PostDestroy([[maybe_unused]] uintptr_t arg) {} |
| 47 | |||
| 48 | constexpr KSession* GetParent() const { | ||
| 49 | return parent; | ||
| 42 | } | 50 | } |
| 43 | 51 | ||
| 52 | ResultCode SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, | ||
| 53 | Core::Timing::CoreTiming& core_timing); | ||
| 54 | |||
| 55 | void OnServerClosed(); | ||
| 56 | |||
| 57 | // DEPRECATED | ||
| 58 | |||
| 44 | static constexpr HandleType HANDLE_TYPE = HandleType::ClientSession; | 59 | static constexpr HandleType HANDLE_TYPE = HandleType::ClientSession; |
| 45 | HandleType GetHandleType() const override { | 60 | HandleType GetHandleType() const override { |
| 46 | return HANDLE_TYPE; | 61 | return HANDLE_TYPE; |
| 47 | } | 62 | } |
| 48 | 63 | ||
| 49 | ResultCode SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, | 64 | std::string GetTypeName() const override { |
| 50 | Core::Timing::CoreTiming& core_timing); | 65 | return "ClientSession"; |
| 51 | 66 | } | |
| 52 | bool IsSignaled() const override; | ||
| 53 | 67 | ||
| 54 | void Finalize() override {} | 68 | std::string GetName() const override { |
| 69 | return name; | ||
| 70 | } | ||
| 55 | 71 | ||
| 56 | private: | 72 | private: |
| 57 | static ResultVal<std::shared_ptr<ClientSession>> Create(KernelCore& kernel, | ||
| 58 | std::shared_ptr<Session> parent, | ||
| 59 | std::string name = "Unknown"); | ||
| 60 | |||
| 61 | /// The parent session, which links to the server endpoint. | 73 | /// The parent session, which links to the server endpoint. |
| 62 | std::shared_ptr<Session> parent; | 74 | KSession* parent{}; |
| 63 | 75 | ||
| 64 | /// Name of the client session (optional) | 76 | /// Name of the client session (optional) |
| 65 | std::string name; | 77 | std::string name; |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/k_server_session.cpp index bb247959c..8cd2c283c 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/k_server_session.cpp | |||
| @@ -11,43 +11,38 @@ | |||
| 11 | #include "core/core_timing.h" | 11 | #include "core/core_timing.h" |
| 12 | #include "core/hle/ipc_helpers.h" | 12 | #include "core/hle/ipc_helpers.h" |
| 13 | #include "core/hle/kernel/client_port.h" | 13 | #include "core/hle/kernel/client_port.h" |
| 14 | #include "core/hle/kernel/client_session.h" | ||
| 15 | #include "core/hle/kernel/handle_table.h" | 14 | #include "core/hle/kernel/handle_table.h" |
| 16 | #include "core/hle/kernel/hle_ipc.h" | 15 | #include "core/hle/kernel/hle_ipc.h" |
| 17 | #include "core/hle/kernel/k_scheduler.h" | 16 | #include "core/hle/kernel/k_scheduler.h" |
| 17 | #include "core/hle/kernel/k_server_session.h" | ||
| 18 | #include "core/hle/kernel/k_session.h" | ||
| 18 | #include "core/hle/kernel/k_thread.h" | 19 | #include "core/hle/kernel/k_thread.h" |
| 19 | #include "core/hle/kernel/kernel.h" | 20 | #include "core/hle/kernel/kernel.h" |
| 20 | #include "core/hle/kernel/process.h" | 21 | #include "core/hle/kernel/process.h" |
| 21 | #include "core/hle/kernel/server_session.h" | ||
| 22 | #include "core/hle/kernel/session.h" | ||
| 23 | #include "core/memory.h" | 22 | #include "core/memory.h" |
| 24 | 23 | ||
| 25 | namespace Kernel { | 24 | namespace Kernel { |
| 26 | 25 | ||
| 27 | ServerSession::ServerSession(KernelCore& kernel) : KSynchronizationObject{kernel} {} | 26 | KServerSession::KServerSession(KernelCore& kernel) : KSynchronizationObject{kernel} {} |
| 28 | 27 | ||
| 29 | ServerSession::~ServerSession() { | 28 | KServerSession::~KServerSession() { |
| 30 | kernel.ReleaseServiceThread(service_thread); | 29 | kernel.ReleaseServiceThread(service_thread); |
| 31 | } | 30 | } |
| 32 | 31 | ||
| 33 | ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel, | 32 | void KServerSession::Initialize(KSession* parent_, std::string&& name_) { |
| 34 | std::shared_ptr<Session> parent, | 33 | // Set member variables. |
| 35 | std::string name) { | 34 | parent = parent_; |
| 36 | std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)}; | 35 | name = std::move(name_); |
| 37 | 36 | service_thread = kernel.CreateServiceThread(name); | |
| 38 | session->name = std::move(name); | ||
| 39 | session->parent = std::move(parent); | ||
| 40 | session->service_thread = kernel.CreateServiceThread(session->name); | ||
| 41 | |||
| 42 | return MakeResult(std::move(session)); | ||
| 43 | } | 37 | } |
| 44 | 38 | ||
| 45 | bool ServerSession::IsSignaled() const { | 39 | void KServerSession::Destroy() { |
| 46 | // Closed sessions should never wait, an error will be returned from svcReplyAndReceive. | 40 | parent->OnServerClosed(); |
| 47 | return !parent->Client(); | 41 | |
| 42 | parent->Close(); | ||
| 48 | } | 43 | } |
| 49 | 44 | ||
| 50 | void ServerSession::ClientDisconnected() { | 45 | void KServerSession::OnClientClosed() { |
| 51 | // We keep a shared pointer to the hle handler to keep it alive throughout | 46 | // We keep a shared pointer to the hle handler to keep it alive throughout |
| 52 | // the call to ClientDisconnected, as ClientDisconnected invalidates the | 47 | // the call to ClientDisconnected, as ClientDisconnected invalidates the |
| 53 | // hle_handler member itself during the course of the function executing. | 48 | // hle_handler member itself during the course of the function executing. |
| @@ -55,19 +50,31 @@ void ServerSession::ClientDisconnected() { | |||
| 55 | if (handler) { | 50 | if (handler) { |
| 56 | // Note that after this returns, this server session's hle_handler is | 51 | // Note that after this returns, this server session's hle_handler is |
| 57 | // invalidated (set to null). | 52 | // invalidated (set to null). |
| 58 | handler->ClientDisconnected(SharedFrom(this)); | 53 | handler->ClientDisconnected(parent); |
| 54 | } | ||
| 55 | } | ||
| 56 | |||
| 57 | bool KServerSession::IsSignaled() const { | ||
| 58 | ASSERT(kernel.GlobalSchedulerContext().IsLocked()); | ||
| 59 | |||
| 60 | // If the client is closed, we're always signaled. | ||
| 61 | if (parent->IsClientClosed()) { | ||
| 62 | return true; | ||
| 59 | } | 63 | } |
| 64 | |||
| 65 | // Otherwise, we're signaled if we have a request and aren't handling one. | ||
| 66 | return false; | ||
| 60 | } | 67 | } |
| 61 | 68 | ||
| 62 | void ServerSession::AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler) { | 69 | void KServerSession::AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler) { |
| 63 | domain_request_handlers.push_back(std::move(handler)); | 70 | domain_request_handlers.push_back(std::move(handler)); |
| 64 | } | 71 | } |
| 65 | 72 | ||
| 66 | std::size_t ServerSession::NumDomainRequestHandlers() const { | 73 | std::size_t KServerSession::NumDomainRequestHandlers() const { |
| 67 | return domain_request_handlers.size(); | 74 | return domain_request_handlers.size(); |
| 68 | } | 75 | } |
| 69 | 76 | ||
| 70 | ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) { | 77 | ResultCode KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) { |
| 71 | if (!context.HasDomainMessageHeader()) { | 78 | if (!context.HasDomainMessageHeader()) { |
| 72 | return RESULT_SUCCESS; | 79 | return RESULT_SUCCESS; |
| 73 | } | 80 | } |
| @@ -106,21 +113,21 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con | |||
| 106 | return RESULT_SUCCESS; | 113 | return RESULT_SUCCESS; |
| 107 | } | 114 | } |
| 108 | 115 | ||
| 109 | ResultCode ServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory) { | 116 | ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory) { |
| 110 | u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))}; | 117 | u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))}; |
| 111 | auto context = std::make_shared<HLERequestContext>(kernel, memory, SharedFrom(this), thread); | 118 | auto context = std::make_shared<HLERequestContext>(kernel, memory, this, thread); |
| 112 | 119 | ||
| 113 | context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); | 120 | context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf); |
| 114 | 121 | ||
| 115 | if (auto strong_ptr = service_thread.lock()) { | 122 | if (auto strong_ptr = service_thread.lock()) { |
| 116 | strong_ptr->QueueSyncRequest(*this, std::move(context)); | 123 | strong_ptr->QueueSyncRequest(*parent, std::move(context)); |
| 117 | return RESULT_SUCCESS; | 124 | return RESULT_SUCCESS; |
| 118 | } | 125 | } |
| 119 | 126 | ||
| 120 | return RESULT_SUCCESS; | 127 | return RESULT_SUCCESS; |
| 121 | } | 128 | } |
| 122 | 129 | ||
| 123 | ResultCode ServerSession::CompleteSyncRequest(HLERequestContext& context) { | 130 | ResultCode KServerSession::CompleteSyncRequest(HLERequestContext& context) { |
| 124 | ResultCode result = RESULT_SUCCESS; | 131 | ResultCode result = RESULT_SUCCESS; |
| 125 | // If the session has been converted to a domain, handle the domain request | 132 | // If the session has been converted to a domain, handle the domain request |
| 126 | if (IsDomain() && context.HasDomainMessageHeader()) { | 133 | if (IsDomain() && context.HasDomainMessageHeader()) { |
| @@ -149,8 +156,8 @@ ResultCode ServerSession::CompleteSyncRequest(HLERequestContext& context) { | |||
| 149 | return result; | 156 | return result; |
| 150 | } | 157 | } |
| 151 | 158 | ||
| 152 | ResultCode ServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, | 159 | ResultCode KServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, |
| 153 | Core::Timing::CoreTiming& core_timing) { | 160 | Core::Timing::CoreTiming& core_timing) { |
| 154 | return QueueSyncRequest(thread, memory); | 161 | return QueueSyncRequest(thread, memory); |
| 155 | } | 162 | } |
| 156 | 163 | ||
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/k_server_session.h index 77ed18c60..ef81c4e30 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/k_server_session.h | |||
| @@ -27,55 +27,34 @@ namespace Kernel { | |||
| 27 | 27 | ||
| 28 | class HLERequestContext; | 28 | class HLERequestContext; |
| 29 | class KernelCore; | 29 | class KernelCore; |
| 30 | class Session; | 30 | class KSession; |
| 31 | class SessionRequestHandler; | 31 | class SessionRequestHandler; |
| 32 | class KThread; | 32 | class KThread; |
| 33 | 33 | ||
| 34 | /** | 34 | class KServerSession final : public KSynchronizationObject { |
| 35 | * Kernel object representing the server endpoint of an IPC session. Sessions are the basic CTR-OS | 35 | KERNEL_AUTOOBJECT_TRAITS(KServerSession, KSynchronizationObject); |
| 36 | * primitive for communication between different processes, and are used to implement service calls | 36 | |
| 37 | * to the various system services. | ||
| 38 | * | ||
| 39 | * To make a service call, the client must write the command header and parameters to the buffer | ||
| 40 | * located at offset 0x80 of the TLS (Thread-Local Storage) area, then execute a SendSyncRequest | ||
| 41 | * SVC call with its ClientSession handle. The kernel will read the command header, using it to | ||
| 42 | * marshall the parameters to the process at the server endpoint of the session. | ||
| 43 | * After the server replies to the request, the response is marshalled back to the caller's | ||
| 44 | * TLS buffer and control is transferred back to it. | ||
| 45 | */ | ||
| 46 | class ServerSession final : public KSynchronizationObject { | ||
| 47 | friend class ServiceThread; | 37 | friend class ServiceThread; |
| 48 | 38 | ||
| 49 | public: | 39 | public: |
| 50 | explicit ServerSession(KernelCore& kernel); | 40 | explicit KServerSession(KernelCore& kernel); |
| 51 | ~ServerSession() override; | 41 | virtual ~KServerSession() override; |
| 52 | 42 | ||
| 53 | friend class Session; | 43 | virtual void Destroy() override; |
| 54 | 44 | ||
| 55 | static ResultVal<std::shared_ptr<ServerSession>> Create(KernelCore& kernel, | 45 | void Initialize(KSession* parent_, std::string&& name_); |
| 56 | std::shared_ptr<Session> parent, | ||
| 57 | std::string name = "Unknown"); | ||
| 58 | 46 | ||
| 59 | std::string GetTypeName() const override { | 47 | constexpr KSession* GetParent() { |
| 60 | return "ServerSession"; | 48 | return parent; |
| 61 | } | ||
| 62 | |||
| 63 | std::string GetName() const override { | ||
| 64 | return name; | ||
| 65 | } | 49 | } |
| 66 | 50 | ||
| 67 | static constexpr HandleType HANDLE_TYPE = HandleType::ServerSession; | 51 | constexpr const KSession* GetParent() const { |
| 68 | HandleType GetHandleType() const override { | 52 | return parent; |
| 69 | return HANDLE_TYPE; | ||
| 70 | } | 53 | } |
| 71 | 54 | ||
| 72 | Session* GetParent() { | 55 | virtual bool IsSignaled() const override; |
| 73 | return parent.get(); | ||
| 74 | } | ||
| 75 | 56 | ||
| 76 | const Session* GetParent() const { | 57 | void OnClientClosed(); |
| 77 | return parent.get(); | ||
| 78 | } | ||
| 79 | 58 | ||
| 80 | /** | 59 | /** |
| 81 | * Sets the HLE handler for the session. This handler will be called to service IPC requests | 60 | * Sets the HLE handler for the session. This handler will be called to service IPC requests |
| @@ -98,9 +77,6 @@ public: | |||
| 98 | ResultCode HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, | 77 | ResultCode HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, |
| 99 | Core::Timing::CoreTiming& core_timing); | 78 | Core::Timing::CoreTiming& core_timing); |
| 100 | 79 | ||
| 101 | /// Called when a client disconnection occurs. | ||
| 102 | void ClientDisconnected(); | ||
| 103 | |||
| 104 | /// Adds a new domain request handler to the collection of request handlers within | 80 | /// Adds a new domain request handler to the collection of request handlers within |
| 105 | /// this ServerSession instance. | 81 | /// this ServerSession instance. |
| 106 | void AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler); | 82 | void AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler); |
| @@ -124,9 +100,20 @@ public: | |||
| 124 | convert_to_domain = true; | 100 | convert_to_domain = true; |
| 125 | } | 101 | } |
| 126 | 102 | ||
| 127 | bool IsSignaled() const override; | 103 | // DEPRECATED |
| 128 | 104 | ||
| 129 | void Finalize() override {} | 105 | std::string GetTypeName() const override { |
| 106 | return "ServerSession"; | ||
| 107 | } | ||
| 108 | |||
| 109 | std::string GetName() const override { | ||
| 110 | return name; | ||
| 111 | } | ||
| 112 | |||
| 113 | static constexpr HandleType HANDLE_TYPE = HandleType::ServerSession; | ||
| 114 | HandleType GetHandleType() const override { | ||
| 115 | return HANDLE_TYPE; | ||
| 116 | } | ||
| 130 | 117 | ||
| 131 | private: | 118 | private: |
| 132 | /// Queues a sync request from the emulated application. | 119 | /// Queues a sync request from the emulated application. |
| @@ -139,9 +126,6 @@ private: | |||
| 139 | /// object handle. | 126 | /// object handle. |
| 140 | ResultCode HandleDomainSyncRequest(Kernel::HLERequestContext& context); | 127 | ResultCode HandleDomainSyncRequest(Kernel::HLERequestContext& context); |
| 141 | 128 | ||
| 142 | /// The parent session, which links to the client endpoint. | ||
| 143 | std::shared_ptr<Session> parent; | ||
| 144 | |||
| 145 | /// This session's HLE request handler (applicable when not a domain) | 129 | /// This session's HLE request handler (applicable when not a domain) |
| 146 | std::shared_ptr<SessionRequestHandler> hle_handler; | 130 | std::shared_ptr<SessionRequestHandler> hle_handler; |
| 147 | 131 | ||
| @@ -156,6 +140,9 @@ private: | |||
| 156 | 140 | ||
| 157 | /// Thread to dispatch service requests | 141 | /// Thread to dispatch service requests |
| 158 | std::weak_ptr<ServiceThread> service_thread; | 142 | std::weak_ptr<ServiceThread> service_thread; |
| 143 | |||
| 144 | /// KSession that owns this KServerSession | ||
| 145 | KSession* parent{}; | ||
| 159 | }; | 146 | }; |
| 160 | 147 | ||
| 161 | } // namespace Kernel | 148 | } // namespace Kernel |
diff --git a/src/core/hle/kernel/k_session.cpp b/src/core/hle/kernel/k_session.cpp new file mode 100644 index 000000000..ca1cf18cd --- /dev/null +++ b/src/core/hle/kernel/k_session.cpp | |||
| @@ -0,0 +1,67 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | #include "core/hle/kernel/k_client_session.h" | ||
| 7 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | ||
| 8 | #include "core/hle/kernel/k_server_session.h" | ||
| 9 | #include "core/hle/kernel/k_session.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | KSession::KSession(KernelCore& kernel) | ||
| 14 | : KAutoObjectWithSlabHeapAndContainer{kernel}, server{kernel}, client{kernel} {} | ||
| 15 | KSession::~KSession() = default; | ||
| 16 | |||
| 17 | void KSession::Initialize(std::string&& name_) { | ||
| 18 | // Increment reference count. | ||
| 19 | // Because reference count is one on creation, this will result | ||
| 20 | // in a reference count of two. Thus, when both server and client are closed | ||
| 21 | // this object will be destroyed. | ||
| 22 | Open(); | ||
| 23 | |||
| 24 | // Create our sub sessions. | ||
| 25 | KAutoObject::Create(std::addressof(server)); | ||
| 26 | KAutoObject::Create(std::addressof(client)); | ||
| 27 | |||
| 28 | // Initialize our sub sessions. | ||
| 29 | server.Initialize(this, name_ + ":Server"); | ||
| 30 | client.Initialize(this, name_ + ":Client"); | ||
| 31 | |||
| 32 | // Set state and name. | ||
| 33 | SetState(State::Normal); | ||
| 34 | name = std::move(name_); | ||
| 35 | |||
| 36 | // Set our owner process. | ||
| 37 | process = kernel.CurrentProcess(); | ||
| 38 | process->Open(); | ||
| 39 | |||
| 40 | // Mark initialized. | ||
| 41 | initialized = true; | ||
| 42 | } | ||
| 43 | |||
| 44 | void KSession::Finalize() {} | ||
| 45 | |||
| 46 | void KSession::OnServerClosed() { | ||
| 47 | if (GetState() == State::Normal) { | ||
| 48 | SetState(State::ServerClosed); | ||
| 49 | client.OnServerClosed(); | ||
| 50 | } | ||
| 51 | } | ||
| 52 | |||
| 53 | void KSession::OnClientClosed() { | ||
| 54 | if (GetState() == State::Normal) { | ||
| 55 | SetState(State::ClientClosed); | ||
| 56 | server.OnClientClosed(); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | void KSession::PostDestroy(uintptr_t arg) { | ||
| 61 | // Release the session count resource the owner process holds. | ||
| 62 | Process* owner = reinterpret_cast<Process*>(arg); | ||
| 63 | owner->GetResourceLimit()->Release(LimitableResource::Sessions, 1); | ||
| 64 | owner->Close(); | ||
| 65 | } | ||
| 66 | |||
| 67 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_session.h b/src/core/hle/kernel/k_session.h new file mode 100644 index 000000000..1d24e80cd --- /dev/null +++ b/src/core/hle/kernel/k_session.h | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | // Copyright 2021 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <atomic> | ||
| 8 | #include <string> | ||
| 9 | |||
| 10 | #include "core/hle/kernel/k_client_session.h" | ||
| 11 | #include "core/hle/kernel/k_server_session.h" | ||
| 12 | #include "core/hle/kernel/slab_helpers.h" | ||
| 13 | |||
| 14 | namespace Kernel { | ||
| 15 | |||
| 16 | class KSession final : public KAutoObjectWithSlabHeapAndContainer<KSession, KAutoObjectWithList> { | ||
| 17 | KERNEL_AUTOOBJECT_TRAITS(KSession, KAutoObject); | ||
| 18 | |||
| 19 | private: | ||
| 20 | enum class State : u8 { | ||
| 21 | Invalid = 0, | ||
| 22 | Normal = 1, | ||
| 23 | ClientClosed = 2, | ||
| 24 | ServerClosed = 3, | ||
| 25 | }; | ||
| 26 | |||
| 27 | public: | ||
| 28 | explicit KSession(KernelCore& kernel); | ||
| 29 | virtual ~KSession() override; | ||
| 30 | |||
| 31 | void Initialize(std::string&& name_); | ||
| 32 | |||
| 33 | virtual void Finalize() override; | ||
| 34 | |||
| 35 | virtual bool IsInitialized() const override { | ||
| 36 | return initialized; | ||
| 37 | } | ||
| 38 | |||
| 39 | virtual uintptr_t GetPostDestroyArgument() const override { | ||
| 40 | return reinterpret_cast<uintptr_t>(process); | ||
| 41 | } | ||
| 42 | |||
| 43 | static void PostDestroy(uintptr_t arg); | ||
| 44 | |||
| 45 | void OnServerClosed(); | ||
| 46 | |||
| 47 | void OnClientClosed(); | ||
| 48 | |||
| 49 | bool IsServerClosed() const { | ||
| 50 | return this->GetState() != State::Normal; | ||
| 51 | } | ||
| 52 | |||
| 53 | bool IsClientClosed() const { | ||
| 54 | return this->GetState() != State::Normal; | ||
| 55 | } | ||
| 56 | |||
| 57 | KClientSession& GetClientSession() { | ||
| 58 | return client; | ||
| 59 | } | ||
| 60 | |||
| 61 | KServerSession& GetServerSession() { | ||
| 62 | return server; | ||
| 63 | } | ||
| 64 | |||
| 65 | const KClientSession& GetClientSession() const { | ||
| 66 | return client; | ||
| 67 | } | ||
| 68 | |||
| 69 | const KServerSession& GetServerSession() const { | ||
| 70 | return server; | ||
| 71 | } | ||
| 72 | |||
| 73 | const ClientPort* GetParent() const { | ||
| 74 | return port; | ||
| 75 | } | ||
| 76 | |||
| 77 | // DEPRECATED | ||
| 78 | |||
| 79 | std::string GetName() const override { | ||
| 80 | return name; | ||
| 81 | } | ||
| 82 | |||
| 83 | static constexpr HandleType HANDLE_TYPE = HandleType::Session; | ||
| 84 | HandleType GetHandleType() const override { | ||
| 85 | return HANDLE_TYPE; | ||
| 86 | } | ||
| 87 | |||
| 88 | private: | ||
| 89 | void SetState(State state) { | ||
| 90 | atomic_state = static_cast<u8>(state); | ||
| 91 | } | ||
| 92 | |||
| 93 | State GetState() const { | ||
| 94 | return static_cast<State>(atomic_state.load()); | ||
| 95 | } | ||
| 96 | |||
| 97 | private: | ||
| 98 | KServerSession server; | ||
| 99 | KClientSession client; | ||
| 100 | std::atomic<std::underlying_type<State>::type> atomic_state{ | ||
| 101 | static_cast<std::underlying_type<State>::type>(State::Invalid)}; | ||
| 102 | ClientPort* port{}; | ||
| 103 | std::string name; | ||
| 104 | Process* process{}; | ||
| 105 | bool initialized{}; | ||
| 106 | }; | ||
| 107 | |||
| 108 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 850436eb3..ecced1034 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -33,11 +33,13 @@ class ClientPort; | |||
| 33 | class GlobalSchedulerContext; | 33 | class GlobalSchedulerContext; |
| 34 | class HandleTable; | 34 | class HandleTable; |
| 35 | class KAutoObjectWithListContainer; | 35 | class KAutoObjectWithListContainer; |
| 36 | class KClientSession; | ||
| 36 | class KEvent; | 37 | class KEvent; |
| 37 | class KLinkedListNode; | 38 | class KLinkedListNode; |
| 38 | class KMemoryManager; | 39 | class KMemoryManager; |
| 39 | class KResourceLimit; | 40 | class KResourceLimit; |
| 40 | class KScheduler; | 41 | class KScheduler; |
| 42 | class KSession; | ||
| 41 | class KSharedMemory; | 43 | class KSharedMemory; |
| 42 | class KThread; | 44 | class KThread; |
| 43 | class KWritableEvent; | 45 | class KWritableEvent; |
| @@ -272,6 +274,10 @@ public: | |||
| 272 | return slab_heap_container->linked_list_node; | 274 | return slab_heap_container->linked_list_node; |
| 273 | } else if constexpr (std::is_same_v<T, KWritableEvent>) { | 275 | } else if constexpr (std::is_same_v<T, KWritableEvent>) { |
| 274 | return slab_heap_container->writeable_event; | 276 | return slab_heap_container->writeable_event; |
| 277 | } else if constexpr (std::is_same_v<T, KClientSession>) { | ||
| 278 | return slab_heap_container->client_session; | ||
| 279 | } else if constexpr (std::is_same_v<T, KSession>) { | ||
| 280 | return slab_heap_container->session; | ||
| 275 | } | 281 | } |
| 276 | } | 282 | } |
| 277 | 283 | ||
| @@ -312,6 +318,8 @@ private: | |||
| 312 | KSlabHeap<KSharedMemory> shared_memory; | 318 | KSlabHeap<KSharedMemory> shared_memory; |
| 313 | KSlabHeap<KLinkedListNode> linked_list_node; | 319 | KSlabHeap<KLinkedListNode> linked_list_node; |
| 314 | KSlabHeap<KWritableEvent> writeable_event; | 320 | KSlabHeap<KWritableEvent> writeable_event; |
| 321 | KSlabHeap<KClientSession> client_session; | ||
| 322 | KSlabHeap<KSession> session; | ||
| 315 | }; | 323 | }; |
| 316 | 324 | ||
| 317 | std::unique_ptr<SlabHeapContainer> slab_heap_container; | 325 | std::unique_ptr<SlabHeapContainer> slab_heap_container; |
diff --git a/src/core/hle/kernel/server_port.cpp b/src/core/hle/kernel/server_port.cpp index 5d17346ad..8626b56fd 100644 --- a/src/core/hle/kernel/server_port.cpp +++ b/src/core/hle/kernel/server_port.cpp | |||
| @@ -5,10 +5,10 @@ | |||
| 5 | #include <tuple> | 5 | #include <tuple> |
| 6 | #include "common/assert.h" | 6 | #include "common/assert.h" |
| 7 | #include "core/hle/kernel/client_port.h" | 7 | #include "core/hle/kernel/client_port.h" |
| 8 | #include "core/hle/kernel/k_server_session.h" | ||
| 8 | #include "core/hle/kernel/k_thread.h" | 9 | #include "core/hle/kernel/k_thread.h" |
| 9 | #include "core/hle/kernel/object.h" | 10 | #include "core/hle/kernel/object.h" |
| 10 | #include "core/hle/kernel/server_port.h" | 11 | #include "core/hle/kernel/server_port.h" |
| 11 | #include "core/hle/kernel/server_session.h" | ||
| 12 | #include "core/hle/kernel/svc_results.h" | 12 | #include "core/hle/kernel/svc_results.h" |
| 13 | 13 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| @@ -16,17 +16,17 @@ namespace Kernel { | |||
| 16 | ServerPort::ServerPort(KernelCore& kernel) : KSynchronizationObject{kernel} {} | 16 | ServerPort::ServerPort(KernelCore& kernel) : KSynchronizationObject{kernel} {} |
| 17 | ServerPort::~ServerPort() = default; | 17 | ServerPort::~ServerPort() = default; |
| 18 | 18 | ||
| 19 | ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() { | 19 | ResultVal<KServerSession*> ServerPort::Accept() { |
| 20 | if (pending_sessions.empty()) { | 20 | if (pending_sessions.empty()) { |
| 21 | return ResultNotFound; | 21 | return ResultNotFound; |
| 22 | } | 22 | } |
| 23 | 23 | ||
| 24 | auto session = std::move(pending_sessions.back()); | 24 | auto* session = pending_sessions.back(); |
| 25 | pending_sessions.pop_back(); | 25 | pending_sessions.pop_back(); |
| 26 | return MakeResult(std::move(session)); | 26 | return MakeResult(session); |
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | void ServerPort::AppendPendingSession(std::shared_ptr<ServerSession> pending_session) { | 29 | void ServerPort::AppendPendingSession(KServerSession* pending_session) { |
| 30 | pending_sessions.push_back(std::move(pending_session)); | 30 | pending_sessions.push_back(std::move(pending_session)); |
| 31 | if (pending_sessions.size() == 1) { | 31 | if (pending_sessions.size() == 1) { |
| 32 | NotifyAvailable(); | 32 | NotifyAvailable(); |
diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index 29b4f2509..eebceaa2a 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h | |||
| @@ -17,7 +17,7 @@ namespace Kernel { | |||
| 17 | 17 | ||
| 18 | class ClientPort; | 18 | class ClientPort; |
| 19 | class KernelCore; | 19 | class KernelCore; |
| 20 | class ServerSession; | 20 | class KServerSession; |
| 21 | class SessionRequestHandler; | 21 | class SessionRequestHandler; |
| 22 | 22 | ||
| 23 | class ServerPort final : public KSynchronizationObject { | 23 | class ServerPort final : public KSynchronizationObject { |
| @@ -55,7 +55,7 @@ public: | |||
| 55 | * Accepts a pending incoming connection on this port. If there are no pending sessions, will | 55 | * Accepts a pending incoming connection on this port. If there are no pending sessions, will |
| 56 | * return ERR_NO_PENDING_SESSIONS. | 56 | * return ERR_NO_PENDING_SESSIONS. |
| 57 | */ | 57 | */ |
| 58 | ResultVal<std::shared_ptr<ServerSession>> Accept(); | 58 | ResultVal<KServerSession*> Accept(); |
| 59 | 59 | ||
| 60 | /// Whether or not this server port has an HLE handler available. | 60 | /// Whether or not this server port has an HLE handler available. |
| 61 | bool HasHLEHandler() const { | 61 | bool HasHLEHandler() const { |
| @@ -77,7 +77,7 @@ public: | |||
| 77 | 77 | ||
| 78 | /// Appends a ServerSession to the collection of ServerSessions | 78 | /// Appends a ServerSession to the collection of ServerSessions |
| 79 | /// waiting to be accepted by this port. | 79 | /// waiting to be accepted by this port. |
| 80 | void AppendPendingSession(std::shared_ptr<ServerSession> pending_session); | 80 | void AppendPendingSession(KServerSession* pending_session); |
| 81 | 81 | ||
| 82 | bool IsSignaled() const override; | 82 | bool IsSignaled() const override; |
| 83 | 83 | ||
| @@ -85,7 +85,7 @@ public: | |||
| 85 | 85 | ||
| 86 | private: | 86 | private: |
| 87 | /// ServerSessions waiting to be accepted by the port | 87 | /// ServerSessions waiting to be accepted by the port |
| 88 | std::vector<std::shared_ptr<ServerSession>> pending_sessions; | 88 | std::vector<KServerSession*> pending_sessions; |
| 89 | 89 | ||
| 90 | /// This session's HLE request handler template (optional) | 90 | /// This session's HLE request handler template (optional) |
| 91 | /// ServerSessions created from this port inherit a reference to this handler. | 91 | /// ServerSessions created from this port inherit a reference to this handler. |
diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp index ee46f3e21..04be8a502 100644 --- a/src/core/hle/kernel/service_thread.cpp +++ b/src/core/hle/kernel/service_thread.cpp | |||
| @@ -13,8 +13,8 @@ | |||
| 13 | #include "common/scope_exit.h" | 13 | #include "common/scope_exit.h" |
| 14 | #include "common/thread.h" | 14 | #include "common/thread.h" |
| 15 | #include "core/core.h" | 15 | #include "core/core.h" |
| 16 | #include "core/hle/kernel/k_session.h" | ||
| 16 | #include "core/hle/kernel/kernel.h" | 17 | #include "core/hle/kernel/kernel.h" |
| 17 | #include "core/hle/kernel/server_session.h" | ||
| 18 | #include "core/hle/kernel/service_thread.h" | 18 | #include "core/hle/kernel/service_thread.h" |
| 19 | #include "core/hle/lock.h" | 19 | #include "core/hle/lock.h" |
| 20 | #include "video_core/renderer_base.h" | 20 | #include "video_core/renderer_base.h" |
| @@ -26,7 +26,7 @@ public: | |||
| 26 | explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name); | 26 | explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name); |
| 27 | ~Impl(); | 27 | ~Impl(); |
| 28 | 28 | ||
| 29 | void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context); | 29 | void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context); |
| 30 | 30 | ||
| 31 | private: | 31 | private: |
| 32 | std::vector<std::thread> threads; | 32 | std::vector<std::thread> threads; |
| @@ -69,18 +69,27 @@ ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads, const std | |||
| 69 | }); | 69 | }); |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | void ServiceThread::Impl::QueueSyncRequest(ServerSession& session, | 72 | void ServiceThread::Impl::QueueSyncRequest(KSession& session, |
| 73 | std::shared_ptr<HLERequestContext>&& context) { | 73 | std::shared_ptr<HLERequestContext>&& context) { |
| 74 | { | 74 | { |
| 75 | std::unique_lock lock{queue_mutex}; | 75 | std::unique_lock lock{queue_mutex}; |
| 76 | 76 | ||
| 77 | // ServerSession owns the service thread, so we cannot caption a strong pointer here in the | 77 | // Open a reference to the session to ensure it is not closes while the service request |
| 78 | // event that the ServerSession is terminated. | 78 | // completes asynchronously. |
| 79 | std::weak_ptr<ServerSession> weak_ptr{SharedFrom(&session)}; | 79 | session.Open(); |
| 80 | requests.emplace([weak_ptr, context{std::move(context)}]() { | 80 | |
| 81 | if (auto strong_ptr = weak_ptr.lock()) { | 81 | requests.emplace([session_ptr{&session}, context{std::move(context)}]() { |
| 82 | strong_ptr->CompleteSyncRequest(*context); | 82 | // Close the reference. |
| 83 | SCOPE_EXIT({ session_ptr->Close(); }); | ||
| 84 | |||
| 85 | // If the session has been closed, we are done. | ||
| 86 | if (session_ptr->IsServerClosed()) { | ||
| 87 | return; | ||
| 83 | } | 88 | } |
| 89 | |||
| 90 | // Complete the service request. | ||
| 91 | KScopedAutoObject server_session{&session_ptr->GetServerSession()}; | ||
| 92 | server_session->CompleteSyncRequest(*context); | ||
| 84 | }); | 93 | }); |
| 85 | } | 94 | } |
| 86 | condition.notify_one(); | 95 | condition.notify_one(); |
| @@ -102,7 +111,7 @@ ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const | |||
| 102 | 111 | ||
| 103 | ServiceThread::~ServiceThread() = default; | 112 | ServiceThread::~ServiceThread() = default; |
| 104 | 113 | ||
| 105 | void ServiceThread::QueueSyncRequest(ServerSession& session, | 114 | void ServiceThread::QueueSyncRequest(KSession& session, |
| 106 | std::shared_ptr<HLERequestContext>&& context) { | 115 | std::shared_ptr<HLERequestContext>&& context) { |
| 107 | impl->QueueSyncRequest(session, std::move(context)); | 116 | impl->QueueSyncRequest(session, std::move(context)); |
| 108 | } | 117 | } |
diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h index 025ab8fb5..6a7fd7c56 100644 --- a/src/core/hle/kernel/service_thread.h +++ b/src/core/hle/kernel/service_thread.h | |||
| @@ -11,14 +11,14 @@ namespace Kernel { | |||
| 11 | 11 | ||
| 12 | class HLERequestContext; | 12 | class HLERequestContext; |
| 13 | class KernelCore; | 13 | class KernelCore; |
| 14 | class ServerSession; | 14 | class KSession; |
| 15 | 15 | ||
| 16 | class ServiceThread final { | 16 | class ServiceThread final { |
| 17 | public: | 17 | public: |
| 18 | explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name); | 18 | explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name); |
| 19 | ~ServiceThread(); | 19 | ~ServiceThread(); |
| 20 | 20 | ||
| 21 | void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context); | 21 | void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context); |
| 22 | 22 | ||
| 23 | private: | 23 | private: |
| 24 | class Impl; | 24 | class Impl; |
diff --git a/src/core/hle/kernel/session.cpp b/src/core/hle/kernel/session.cpp deleted file mode 100644 index 8830d4e91..000000000 --- a/src/core/hle/kernel/session.cpp +++ /dev/null | |||
| @@ -1,41 +0,0 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "common/assert.h" | ||
| 6 | #include "core/hle/kernel/client_session.h" | ||
| 7 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | ||
| 8 | #include "core/hle/kernel/server_session.h" | ||
| 9 | #include "core/hle/kernel/session.h" | ||
| 10 | |||
| 11 | namespace Kernel { | ||
| 12 | |||
| 13 | Session::Session(KernelCore& kernel) : KSynchronizationObject{kernel} {} | ||
| 14 | Session::~Session() { | ||
| 15 | // Release reserved resource when the Session pair was created. | ||
| 16 | kernel.GetSystemResourceLimit()->Release(LimitableResource::Sessions, 1); | ||
| 17 | } | ||
| 18 | |||
| 19 | Session::SessionPair Session::Create(KernelCore& kernel, std::string name) { | ||
| 20 | // Reserve a new session from the resource limit. | ||
| 21 | KScopedResourceReservation session_reservation(kernel.GetSystemResourceLimit(), | ||
| 22 | LimitableResource::Sessions); | ||
| 23 | ASSERT(session_reservation.Succeeded()); | ||
| 24 | auto session{std::make_shared<Session>(kernel)}; | ||
| 25 | auto client_session{Kernel::ClientSession::Create(kernel, session, name + "_Client").Unwrap()}; | ||
| 26 | auto server_session{Kernel::ServerSession::Create(kernel, session, name + "_Server").Unwrap()}; | ||
| 27 | |||
| 28 | session->name = std::move(name); | ||
| 29 | session->client = client_session; | ||
| 30 | session->server = server_session; | ||
| 31 | |||
| 32 | session_reservation.Commit(); | ||
| 33 | return std::make_pair(std::move(client_session), std::move(server_session)); | ||
| 34 | } | ||
| 35 | |||
| 36 | bool Session::IsSignaled() const { | ||
| 37 | UNIMPLEMENTED(); | ||
| 38 | return true; | ||
| 39 | } | ||
| 40 | |||
| 41 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h deleted file mode 100644 index fa3c5651a..000000000 --- a/src/core/hle/kernel/session.h +++ /dev/null | |||
| @@ -1,64 +0,0 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <memory> | ||
| 8 | #include <string> | ||
| 9 | #include <utility> | ||
| 10 | |||
| 11 | #include "core/hle/kernel/k_synchronization_object.h" | ||
| 12 | |||
| 13 | namespace Kernel { | ||
| 14 | |||
| 15 | class ClientSession; | ||
| 16 | class ServerSession; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * Parent structure to link the client and server endpoints of a session with their associated | ||
| 20 | * client port. | ||
| 21 | */ | ||
| 22 | class Session final : public KSynchronizationObject { | ||
| 23 | public: | ||
| 24 | explicit Session(KernelCore& kernel); | ||
| 25 | ~Session() override; | ||
| 26 | |||
| 27 | using SessionPair = std::pair<std::shared_ptr<ClientSession>, std::shared_ptr<ServerSession>>; | ||
| 28 | |||
| 29 | static SessionPair Create(KernelCore& kernel, std::string name = "Unknown"); | ||
| 30 | |||
| 31 | std::string GetName() const override { | ||
| 32 | return name; | ||
| 33 | } | ||
| 34 | |||
| 35 | static constexpr HandleType HANDLE_TYPE = HandleType::Session; | ||
| 36 | HandleType GetHandleType() const override { | ||
| 37 | return HANDLE_TYPE; | ||
| 38 | } | ||
| 39 | |||
| 40 | bool IsSignaled() const override; | ||
| 41 | |||
| 42 | void Finalize() override {} | ||
| 43 | |||
| 44 | std::shared_ptr<ClientSession> Client() { | ||
| 45 | if (auto result{client.lock()}) { | ||
| 46 | return result; | ||
| 47 | } | ||
| 48 | return {}; | ||
| 49 | } | ||
| 50 | |||
| 51 | std::shared_ptr<ServerSession> Server() { | ||
| 52 | if (auto result{server.lock()}) { | ||
| 53 | return result; | ||
| 54 | } | ||
| 55 | return {}; | ||
| 56 | } | ||
| 57 | |||
| 58 | private: | ||
| 59 | std::string name; | ||
| 60 | std::weak_ptr<ClientSession> client; | ||
| 61 | std::weak_ptr<ServerSession> server; | ||
| 62 | }; | ||
| 63 | |||
| 64 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index b83ee3e69..28c45e8a3 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -22,9 +22,9 @@ | |||
| 22 | #include "core/core_timing_util.h" | 22 | #include "core/core_timing_util.h" |
| 23 | #include "core/cpu_manager.h" | 23 | #include "core/cpu_manager.h" |
| 24 | #include "core/hle/kernel/client_port.h" | 24 | #include "core/hle/kernel/client_port.h" |
| 25 | #include "core/hle/kernel/client_session.h" | ||
| 26 | #include "core/hle/kernel/handle_table.h" | 25 | #include "core/hle/kernel/handle_table.h" |
| 27 | #include "core/hle/kernel/k_address_arbiter.h" | 26 | #include "core/hle/kernel/k_address_arbiter.h" |
| 27 | #include "core/hle/kernel/k_client_session.h" | ||
| 28 | #include "core/hle/kernel/k_condition_variable.h" | 28 | #include "core/hle/kernel/k_condition_variable.h" |
| 29 | #include "core/hle/kernel/k_event.h" | 29 | #include "core/hle/kernel/k_event.h" |
| 30 | #include "core/hle/kernel/k_memory_block.h" | 30 | #include "core/hle/kernel/k_memory_block.h" |
| @@ -323,12 +323,12 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | |||
| 323 | 323 | ||
| 324 | auto client_port = it->second; | 324 | auto client_port = it->second; |
| 325 | 325 | ||
| 326 | std::shared_ptr<ClientSession> client_session; | 326 | KClientSession* client_session{}; |
| 327 | CASCADE_RESULT(client_session, client_port->Connect()); | 327 | CASCADE_RESULT(client_session, client_port->Connect()); |
| 328 | 328 | ||
| 329 | // Return the client session | 329 | // Return the client session |
| 330 | auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 330 | auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); |
| 331 | CASCADE_RESULT(*out_handle, handle_table.Create(client_session.get())); | 331 | CASCADE_RESULT(*out_handle, handle_table.Create(client_session)); |
| 332 | return RESULT_SUCCESS; | 332 | return RESULT_SUCCESS; |
| 333 | } | 333 | } |
| 334 | 334 | ||
| @@ -340,15 +340,13 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle, | |||
| 340 | 340 | ||
| 341 | /// Makes a blocking IPC call to an OS service. | 341 | /// Makes a blocking IPC call to an OS service. |
| 342 | static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | 342 | static ResultCode SendSyncRequest(Core::System& system, Handle handle) { |
| 343 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); | ||
| 344 | |||
| 343 | auto& kernel = system.Kernel(); | 345 | auto& kernel = system.Kernel(); |
| 344 | const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); | ||
| 345 | auto session = handle_table.Get<ClientSession>(handle); | ||
| 346 | if (!session) { | ||
| 347 | LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle); | ||
| 348 | return ResultInvalidHandle; | ||
| 349 | } | ||
| 350 | 346 | ||
| 351 | LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); | 347 | KScopedAutoObject session = |
| 348 | kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle); | ||
| 349 | R_UNLESS(session.IsNotNull(), ResultInvalidHandle); | ||
| 352 | 350 | ||
| 353 | auto thread = kernel.CurrentScheduler()->GetCurrentThread(); | 351 | auto thread = kernel.CurrentScheduler()->GetCurrentThread(); |
| 354 | { | 352 | { |
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp index cf8ad7598..ae995df6b 100644 --- a/src/core/hle/service/am/applets/applets.cpp +++ b/src/core/hle/service/am/applets/applets.cpp | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include "core/frontend/applets/web_browser.h" | 14 | #include "core/frontend/applets/web_browser.h" |
| 15 | #include "core/hle/kernel/k_readable_event.h" | 15 | #include "core/hle/kernel/k_readable_event.h" |
| 16 | #include "core/hle/kernel/k_writable_event.h" | 16 | #include "core/hle/kernel/k_writable_event.h" |
| 17 | #include "core/hle/kernel/server_session.h" | ||
| 18 | #include "core/hle/service/am/am.h" | 17 | #include "core/hle/service/am/am.h" |
| 19 | #include "core/hle/service/am/applet_ae.h" | 18 | #include "core/hle/service/am/applet_ae.h" |
| 20 | #include "core/hle/service/am/applet_oe.h" | 19 | #include "core/hle/service/am/applet_oe.h" |
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 49c1db42a..6b3ebeb8f 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp | |||
| @@ -14,7 +14,6 @@ | |||
| 14 | #include "core/hardware_properties.h" | 14 | #include "core/hardware_properties.h" |
| 15 | #include "core/hle/ipc_helpers.h" | 15 | #include "core/hle/ipc_helpers.h" |
| 16 | #include "core/hle/kernel/client_port.h" | 16 | #include "core/hle/kernel/client_port.h" |
| 17 | #include "core/hle/kernel/client_session.h" | ||
| 18 | #include "core/hle/kernel/k_readable_event.h" | 17 | #include "core/hle/kernel/k_readable_event.h" |
| 19 | #include "core/hle/kernel/k_shared_memory.h" | 18 | #include "core/hle/kernel/k_shared_memory.h" |
| 20 | #include "core/hle/kernel/k_writable_event.h" | 19 | #include "core/hle/kernel/k_writable_event.h" |
diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp index b0cb07d24..c8519e2db 100644 --- a/src/core/hle/service/mm/mm_u.cpp +++ b/src/core/hle/service/mm/mm_u.cpp | |||
| @@ -4,7 +4,6 @@ | |||
| 4 | 4 | ||
| 5 | #include "common/logging/log.h" | 5 | #include "common/logging/log.h" |
| 6 | #include "core/hle/ipc_helpers.h" | 6 | #include "core/hle/ipc_helpers.h" |
| 7 | #include "core/hle/kernel/client_session.h" | ||
| 8 | #include "core/hle/service/mm/mm_u.h" | 7 | #include "core/hle/service/mm/mm_u.h" |
| 9 | #include "core/hle/service/sm/sm.h" | 8 | #include "core/hle/service/sm/sm.h" |
| 10 | 9 | ||
diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 916445517..076f50b0b 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h | |||
| @@ -21,11 +21,8 @@ class System; | |||
| 21 | } | 21 | } |
| 22 | 22 | ||
| 23 | namespace Kernel { | 23 | namespace Kernel { |
| 24 | class ClientPort; | ||
| 25 | class ServerPort; | ||
| 26 | class ServerSession; | ||
| 27 | class HLERequestContext; | 24 | class HLERequestContext; |
| 28 | } // namespace Kernel | 25 | } |
| 29 | 26 | ||
| 30 | namespace Service { | 27 | namespace Service { |
| 31 | 28 | ||
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index b34fe4bc2..cb397fcc7 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp | |||
| @@ -5,9 +5,9 @@ | |||
| 5 | #include "common/assert.h" | 5 | #include "common/assert.h" |
| 6 | #include "common/logging/log.h" | 6 | #include "common/logging/log.h" |
| 7 | #include "core/hle/ipc_helpers.h" | 7 | #include "core/hle/ipc_helpers.h" |
| 8 | #include "core/hle/kernel/client_session.h" | 8 | #include "core/hle/kernel/k_client_session.h" |
| 9 | #include "core/hle/kernel/server_session.h" | 9 | #include "core/hle/kernel/k_server_session.h" |
| 10 | #include "core/hle/kernel/session.h" | 10 | #include "core/hle/kernel/k_session.h" |
| 11 | #include "core/hle/service/sm/controller.h" | 11 | #include "core/hle/service/sm/controller.h" |
| 12 | 12 | ||
| 13 | namespace Service::SM { | 13 | namespace Service::SM { |
| @@ -30,7 +30,7 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { | |||
| 30 | 30 | ||
| 31 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; | 31 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; |
| 32 | rb.Push(RESULT_SUCCESS); | 32 | rb.Push(RESULT_SUCCESS); |
| 33 | rb.PushMoveObjects(ctx.Session()->GetParent()->Client().get()); | 33 | rb.PushMoveObjects(ctx.Session()->GetParent()->GetClientSession()); |
| 34 | } | 34 | } |
| 35 | 35 | ||
| 36 | void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { | 36 | 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 62f7a5358..66e41277f 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -7,7 +7,9 @@ | |||
| 7 | #include "core/core.h" | 7 | #include "core/core.h" |
| 8 | #include "core/hle/ipc_helpers.h" | 8 | #include "core/hle/ipc_helpers.h" |
| 9 | #include "core/hle/kernel/client_port.h" | 9 | #include "core/hle/kernel/client_port.h" |
| 10 | #include "core/hle/kernel/client_session.h" | 10 | #include "core/hle/kernel/k_client_session.h" |
| 11 | #include "core/hle/kernel/k_server_session.h" | ||
| 12 | #include "core/hle/kernel/k_session.h" | ||
| 11 | #include "core/hle/kernel/server_port.h" | 13 | #include "core/hle/kernel/server_port.h" |
| 12 | #include "core/hle/result.h" | 14 | #include "core/hle/result.h" |
| 13 | #include "core/hle/service/sm/controller.h" | 15 | #include "core/hle/service/sm/controller.h" |
| @@ -89,13 +91,6 @@ ResultVal<std::shared_ptr<Kernel::ClientPort>> ServiceManager::GetServicePort( | |||
| 89 | return MakeResult(it->second); | 91 | return MakeResult(it->second); |
| 90 | } | 92 | } |
| 91 | 93 | ||
| 92 | ResultVal<std::shared_ptr<Kernel::ClientSession>> ServiceManager::ConnectToService( | ||
| 93 | const std::string& name) { | ||
| 94 | |||
| 95 | CASCADE_RESULT(auto client_port, GetServicePort(name)); | ||
| 96 | return client_port->Connect(); | ||
| 97 | } | ||
| 98 | |||
| 99 | SM::~SM() = default; | 94 | SM::~SM() = default; |
| 100 | 95 | ||
| 101 | /** | 96 | /** |
| @@ -130,19 +125,20 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { | |||
| 130 | return; | 125 | return; |
| 131 | } | 126 | } |
| 132 | 127 | ||
| 133 | auto [client, server] = Kernel::Session::Create(kernel, name); | 128 | auto* session = Kernel::KSession::Create(kernel); |
| 129 | session->Initialize(std::move(name)); | ||
| 134 | 130 | ||
| 135 | const auto& server_port = client_port.Unwrap()->GetServerPort(); | 131 | const auto& server_port = client_port.Unwrap()->GetServerPort(); |
| 136 | if (server_port->GetHLEHandler()) { | 132 | if (server_port->GetHLEHandler()) { |
| 137 | server_port->GetHLEHandler()->ClientConnected(client, server); | 133 | server_port->GetHLEHandler()->ClientConnected(session); |
| 138 | } else { | 134 | } else { |
| 139 | server_port->AppendPendingSession(server); | 135 | server_port->AppendPendingSession(&session->GetServerSession()); |
| 140 | } | 136 | } |
| 141 | 137 | ||
| 142 | LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId()); | 138 | LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetObjectId()); |
| 143 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; | 139 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; |
| 144 | rb.Push(RESULT_SUCCESS); | 140 | rb.Push(RESULT_SUCCESS); |
| 145 | rb.PushMoveObjects(client.get()); | 141 | rb.PushMoveObjects(session->GetClientSession()); |
| 146 | } | 142 | } |
| 147 | 143 | ||
| 148 | void SM::RegisterService(Kernel::HLERequestContext& ctx) { | 144 | void SM::RegisterService(Kernel::HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 3f46ae44f..8f6862fa9 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h | |||
| @@ -22,7 +22,7 @@ class System; | |||
| 22 | 22 | ||
| 23 | namespace Kernel { | 23 | namespace Kernel { |
| 24 | class ClientPort; | 24 | class ClientPort; |
| 25 | class ClientSession; | 25 | class KClientSession; |
| 26 | class KernelCore; | 26 | class KernelCore; |
| 27 | class ServerPort; | 27 | class ServerPort; |
| 28 | class SessionRequestHandler; | 28 | class SessionRequestHandler; |
| @@ -59,7 +59,6 @@ public: | |||
| 59 | u32 max_sessions); | 59 | u32 max_sessions); |
| 60 | ResultCode UnregisterService(const std::string& name); | 60 | ResultCode UnregisterService(const std::string& name); |
| 61 | ResultVal<std::shared_ptr<Kernel::ClientPort>> GetServicePort(const std::string& name); | 61 | ResultVal<std::shared_ptr<Kernel::ClientPort>> GetServicePort(const std::string& name); |
| 62 | ResultVal<std::shared_ptr<Kernel::ClientSession>> ConnectToService(const std::string& name); | ||
| 63 | 62 | ||
| 64 | template <Common::DerivedFrom<Kernel::SessionRequestHandler> T> | 63 | template <Common::DerivedFrom<Kernel::SessionRequestHandler> T> |
| 65 | std::shared_ptr<T> GetService(const std::string& service_name) const { | 64 | std::shared_ptr<T> GetService(const std::string& service_name) const { |
| @@ -81,7 +80,7 @@ private: | |||
| 81 | std::weak_ptr<SM> sm_interface; | 80 | std::weak_ptr<SM> sm_interface; |
| 82 | std::unique_ptr<Controller> controller_interface; | 81 | std::unique_ptr<Controller> controller_interface; |
| 83 | 82 | ||
| 84 | /// Map of registered services, retrieved using GetServicePort or ConnectToService. | 83 | /// Map of registered services, retrieved using GetServicePort. |
| 85 | std::unordered_map<std::string, std::shared_ptr<Kernel::ClientPort>> registered_services; | 84 | std::unordered_map<std::string, std::shared_ptr<Kernel::ClientPort>> registered_services; |
| 86 | 85 | ||
| 87 | /// Kernel context | 86 | /// Kernel context |
diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index 30283f239..413a00ae0 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp | |||
| @@ -9,7 +9,6 @@ | |||
| 9 | #include "core/hardware_properties.h" | 9 | #include "core/hardware_properties.h" |
| 10 | #include "core/hle/ipc_helpers.h" | 10 | #include "core/hle/ipc_helpers.h" |
| 11 | #include "core/hle/kernel/client_port.h" | 11 | #include "core/hle/kernel/client_port.h" |
| 12 | #include "core/hle/kernel/client_session.h" | ||
| 13 | #include "core/hle/kernel/k_scheduler.h" | 12 | #include "core/hle/kernel/k_scheduler.h" |
| 14 | #include "core/hle/kernel/kernel.h" | 13 | #include "core/hle/kernel/kernel.h" |
| 15 | #include "core/hle/service/time/interface.h" | 14 | #include "core/hle/service/time/interface.h" |