diff options
| -rw-r--r-- | src/core/CMakeLists.txt | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/client_port.cpp | 13 | ||||
| -rw-r--r-- | src/core/hle/kernel/client_session.cpp | 24 | ||||
| -rw-r--r-- | src/core/hle/kernel/client_session.h | 11 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.cpp | 29 | ||||
| -rw-r--r-- | src/core/hle/kernel/server_session.h | 12 | ||||
| -rw-r--r-- | src/core/hle/kernel/session.h | 27 | ||||
| -rw-r--r-- | src/core/hle/result.h | 1 |
8 files changed, 86 insertions, 32 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 61a0b1cc3..b161c05ba 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -241,6 +241,7 @@ set(HEADERS | |||
| 241 | hle/kernel/semaphore.h | 241 | hle/kernel/semaphore.h |
| 242 | hle/kernel/server_port.h | 242 | hle/kernel/server_port.h |
| 243 | hle/kernel/server_session.h | 243 | hle/kernel/server_session.h |
| 244 | hle/kernel/session.h | ||
| 244 | hle/kernel/shared_memory.h | 245 | hle/kernel/shared_memory.h |
| 245 | hle/kernel/thread.h | 246 | hle/kernel/thread.h |
| 246 | hle/kernel/timer.h | 247 | hle/kernel/timer.h |
diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 22645f4ec..ddcf4c916 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp | |||
| @@ -19,24 +19,21 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() { | |||
| 19 | // AcceptSession before returning from this call. | 19 | // AcceptSession before returning from this call. |
| 20 | 20 | ||
| 21 | if (active_sessions >= max_sessions) { | 21 | if (active_sessions >= max_sessions) { |
| 22 | // TODO(Subv): Return an error code in this situation after session disconnection is | 22 | return ResultCode(ErrorDescription::MaxConnectionsReached, ErrorModule::OS, |
| 23 | // implemented. | 23 | ErrorSummary::WouldBlock, ErrorLevel::Temporary); |
| 24 | /*return ResultCode(ErrorDescription::MaxConnectionsReached, | ||
| 25 | ErrorModule::OS, ErrorSummary::WouldBlock, | ||
| 26 | ErrorLevel::Temporary);*/ | ||
| 27 | } | 24 | } |
| 28 | active_sessions++; | 25 | active_sessions++; |
| 29 | 26 | ||
| 30 | // Create a new session pair, let the created sessions inherit the parent port's HLE handler. | 27 | // Create a new session pair, let the created sessions inherit the parent port's HLE handler. |
| 31 | auto sessions = | 28 | auto sessions = |
| 32 | ServerSession::CreateSessionPair(server_port->GetName(), server_port->hle_handler); | 29 | ServerSession::CreateSessionPair(server_port->GetName(), server_port->hle_handler, this); |
| 33 | auto client_session = std::get<SharedPtr<ClientSession>>(sessions); | 30 | auto client_session = std::get<SharedPtr<ClientSession>>(sessions); |
| 34 | auto server_session = std::get<SharedPtr<ServerSession>>(sessions); | 31 | auto server_session = std::get<SharedPtr<ServerSession>>(sessions); |
| 35 | 32 | ||
| 36 | if (server_port->hle_handler) | 33 | if (server_port->hle_handler) |
| 37 | server_port->hle_handler->ClientConnected(server_session); | 34 | server_port->hle_handler->ClientConnected(server_session); |
| 38 | 35 | else | |
| 39 | server_port->pending_sessions.push_back(std::move(server_session)); | 36 | server_port->pending_sessions.push_back(std::move(server_session)); |
| 40 | 37 | ||
| 41 | // Wake the threads waiting on the ServerPort | 38 | // Wake the threads waiting on the ServerPort |
| 42 | server_port->WakeupAllWaitingThreads(); | 39 | server_port->WakeupAllWaitingThreads(); |
diff --git a/src/core/hle/kernel/client_session.cpp b/src/core/hle/kernel/client_session.cpp index 0331386ec..c2f48176e 100644 --- a/src/core/hle/kernel/client_session.cpp +++ b/src/core/hle/kernel/client_session.cpp | |||
| @@ -14,27 +14,33 @@ ClientSession::~ClientSession() { | |||
| 14 | // This destructor will be called automatically when the last ClientSession handle is closed by | 14 | // This destructor will be called automatically when the last ClientSession handle is closed by |
| 15 | // the emulated application. | 15 | // the emulated application. |
| 16 | 16 | ||
| 17 | if (server_session->hle_handler) | 17 | if (parent->server) { |
| 18 | server_session->hle_handler->ClientDisconnected(server_session); | 18 | if (parent->server->hle_handler) |
| 19 | parent->server->hle_handler->ClientDisconnected(parent->server); | ||
| 19 | 20 | ||
| 20 | // TODO(Subv): If the session is still open, set the connection status to 2 (Closed by client), | 21 | // TODO(Subv): Force a wake up of all the ServerSession's waiting threads and set |
| 21 | // wake up all the ServerSession's waiting threads and set the WaitSynchronization result to | 22 | // their WaitSynchronization result to 0xC920181A. |
| 22 | // 0xC920181A. | 23 | } |
| 24 | |||
| 25 | parent->client = nullptr; | ||
| 23 | } | 26 | } |
| 24 | 27 | ||
| 25 | ResultVal<SharedPtr<ClientSession>> ClientSession::Create(ServerSession* server_session, | 28 | ResultVal<SharedPtr<ClientSession>> ClientSession::Create(std::string name) { |
| 26 | std::string name) { | ||
| 27 | SharedPtr<ClientSession> client_session(new ClientSession); | 29 | SharedPtr<ClientSession> client_session(new ClientSession); |
| 28 | 30 | ||
| 29 | client_session->name = std::move(name); | 31 | client_session->name = std::move(name); |
| 30 | client_session->server_session = server_session; | 32 | client_session->parent = nullptr; |
| 31 | client_session->session_status = SessionStatus::Open; | 33 | client_session->session_status = SessionStatus::Open; |
| 32 | return MakeResult<SharedPtr<ClientSession>>(std::move(client_session)); | 34 | return MakeResult<SharedPtr<ClientSession>>(std::move(client_session)); |
| 33 | } | 35 | } |
| 34 | 36 | ||
| 35 | ResultCode ClientSession::SendSyncRequest() { | 37 | ResultCode ClientSession::SendSyncRequest() { |
| 36 | // Signal the server session that new data is available | 38 | // Signal the server session that new data is available |
| 37 | return server_session->HandleSyncRequest(); | 39 | if (parent->server) |
| 40 | return parent->server->HandleSyncRequest(); | ||
| 41 | |||
| 42 | return ResultCode(ErrorDescription::SessionClosedByRemote, ErrorModule::OS, | ||
| 43 | ErrorSummary::Canceled, ErrorLevel::Status); | ||
| 38 | } | 44 | } |
| 39 | 45 | ||
| 40 | } // namespace | 46 | } // namespace |
diff --git a/src/core/hle/kernel/client_session.h b/src/core/hle/kernel/client_session.h index ed468dec6..adb2d0b5f 100644 --- a/src/core/hle/kernel/client_session.h +++ b/src/core/hle/kernel/client_session.h | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | 15 | ||
| 16 | class ServerSession; | 16 | class ServerSession; |
| 17 | class Session; | ||
| 17 | 18 | ||
| 18 | enum class SessionStatus { | 19 | enum class SessionStatus { |
| 19 | Open = 1, | 20 | Open = 1, |
| @@ -44,8 +45,10 @@ public: | |||
| 44 | */ | 45 | */ |
| 45 | ResultCode SendSyncRequest(); | 46 | ResultCode SendSyncRequest(); |
| 46 | 47 | ||
| 47 | std::string name; ///< Name of client port (optional) | 48 | std::string name; ///< Name of client port (optional) |
| 48 | ServerSession* server_session; ///< The server session associated with this client session. | 49 | |
| 50 | /// The parent session, which links to the server endpoint. | ||
| 51 | std::shared_ptr<Session> parent; | ||
| 49 | SessionStatus session_status; ///< The session's current status. | 52 | SessionStatus session_status; ///< The session's current status. |
| 50 | 53 | ||
| 51 | private: | 54 | private: |
| @@ -54,12 +57,10 @@ private: | |||
| 54 | 57 | ||
| 55 | /** | 58 | /** |
| 56 | * Creates a client session. | 59 | * Creates a client session. |
| 57 | * @param server_session The server session associated with this client session | ||
| 58 | * @param name Optional name of client session | 60 | * @param name Optional name of client session |
| 59 | * @return The created client session | 61 | * @return The created client session |
| 60 | */ | 62 | */ |
| 61 | static ResultVal<SharedPtr<ClientSession>> Create(ServerSession* server_session, | 63 | static ResultVal<SharedPtr<ClientSession>> Create(std::string name = "Unknown"); |
| 62 | std::string name = "Unknown"); | ||
| 63 | }; | 64 | }; |
| 64 | 65 | ||
| 65 | } // namespace | 66 | } // namespace |
diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 9447ff236..a93e55c76 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp | |||
| @@ -14,8 +14,15 @@ ServerSession::ServerSession() = default; | |||
| 14 | ServerSession::~ServerSession() { | 14 | ServerSession::~ServerSession() { |
| 15 | // This destructor will be called automatically when the last ServerSession handle is closed by | 15 | // This destructor will be called automatically when the last ServerSession handle is closed by |
| 16 | // the emulated application. | 16 | // the emulated application. |
| 17 | // TODO(Subv): Reduce the ClientPort's connection count, | 17 | |
| 18 | // if the session is still open, set the connection status to 3 (Closed by server), | 18 | // Decrease the port's connection count. |
| 19 | if (parent->port) | ||
| 20 | parent->port->active_sessions--; | ||
| 21 | |||
| 22 | // TODO(Subv): Wake up all the ClientSession's waiting threads and set | ||
| 23 | // the SendSyncRequest result to 0xC920181A. | ||
| 24 | |||
| 25 | parent->server = nullptr; | ||
| 19 | } | 26 | } |
| 20 | 27 | ||
| 21 | ResultVal<SharedPtr<ServerSession>> ServerSession::Create( | 28 | ResultVal<SharedPtr<ServerSession>> ServerSession::Create( |
| @@ -25,6 +32,7 @@ ResultVal<SharedPtr<ServerSession>> ServerSession::Create( | |||
| 25 | server_session->name = std::move(name); | 32 | server_session->name = std::move(name); |
| 26 | server_session->signaled = false; | 33 | server_session->signaled = false; |
| 27 | server_session->hle_handler = std::move(hle_handler); | 34 | server_session->hle_handler = std::move(hle_handler); |
| 35 | server_session->parent = nullptr; | ||
| 28 | 36 | ||
| 29 | return MakeResult<SharedPtr<ServerSession>>(std::move(server_session)); | 37 | return MakeResult<SharedPtr<ServerSession>>(std::move(server_session)); |
| 30 | } | 38 | } |
| @@ -61,13 +69,20 @@ ResultCode ServerSession::HandleSyncRequest() { | |||
| 61 | } | 69 | } |
| 62 | 70 | ||
| 63 | ServerSession::SessionPair ServerSession::CreateSessionPair( | 71 | ServerSession::SessionPair ServerSession::CreateSessionPair( |
| 64 | const std::string& name, std::shared_ptr<Service::SessionRequestHandler> hle_handler) { | 72 | const std::string& name, std::shared_ptr<Service::SessionRequestHandler> hle_handler, |
| 73 | SharedPtr<ClientPort> port) { | ||
| 74 | |||
| 65 | auto server_session = | 75 | auto server_session = |
| 66 | ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); | 76 | ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); |
| 67 | // We keep a non-owning pointer to the ServerSession in the ClientSession because we don't want | 77 | auto client_session = ClientSession::Create(name + "_Client").MoveFrom(); |
| 68 | // to prevent the ServerSession's destructor from being called when the emulated | 78 | |
| 69 | // application closes the last ServerSession handle. | 79 | std::shared_ptr<Session> parent(new Session); |
| 70 | auto client_session = ClientSession::Create(server_session.get(), name + "_Client").MoveFrom(); | 80 | parent->client = client_session.get(); |
| 81 | parent->server = server_session.get(); | ||
| 82 | parent->port = port; | ||
| 83 | |||
| 84 | client_session->parent = parent; | ||
| 85 | server_session->parent = parent; | ||
| 71 | 86 | ||
| 72 | return std::make_tuple(std::move(server_session), std::move(client_session)); | 87 | return std::make_tuple(std::move(server_session), std::move(client_session)); |
| 73 | } | 88 | } |
diff --git a/src/core/hle/kernel/server_session.h b/src/core/hle/kernel/server_session.h index 761fc4781..c907d487c 100644 --- a/src/core/hle/kernel/server_session.h +++ b/src/core/hle/kernel/server_session.h | |||
| @@ -9,6 +9,7 @@ | |||
| 9 | #include "common/assert.h" | 9 | #include "common/assert.h" |
| 10 | #include "common/common_types.h" | 10 | #include "common/common_types.h" |
| 11 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
| 12 | #include "core/hle/kernel/session.h" | ||
| 12 | #include "core/hle/kernel/thread.h" | 13 | #include "core/hle/kernel/thread.h" |
| 13 | #include "core/hle/result.h" | 14 | #include "core/hle/result.h" |
| 14 | #include "core/hle/service/service.h" | 15 | #include "core/hle/service/service.h" |
| @@ -17,6 +18,8 @@ | |||
| 17 | namespace Kernel { | 18 | namespace Kernel { |
| 18 | 19 | ||
| 19 | class ClientSession; | 20 | class ClientSession; |
| 21 | class ClientPort; | ||
| 22 | class ServerSession; | ||
| 20 | 23 | ||
| 21 | /** | 24 | /** |
| 22 | * Kernel object representing the server endpoint of an IPC session. Sessions are the basic CTR-OS | 25 | * Kernel object representing the server endpoint of an IPC session. Sessions are the basic CTR-OS |
| @@ -47,11 +50,13 @@ public: | |||
| 47 | * Creates a pair of ServerSession and an associated ClientSession. | 50 | * Creates a pair of ServerSession and an associated ClientSession. |
| 48 | * @param name Optional name of the ports. | 51 | * @param name Optional name of the ports. |
| 49 | * @param hle_handler Optional HLE handler for this server session. | 52 | * @param hle_handler Optional HLE handler for this server session. |
| 53 | * @param client_port Optional The ClientPort that spawned this session. | ||
| 50 | * @return The created session tuple | 54 | * @return The created session tuple |
| 51 | */ | 55 | */ |
| 52 | static SessionPair CreateSessionPair( | 56 | static SessionPair CreateSessionPair( |
| 53 | const std::string& name = "Unknown", | 57 | const std::string& name = "Unknown", |
| 54 | std::shared_ptr<Service::SessionRequestHandler> hle_handler = nullptr); | 58 | std::shared_ptr<Service::SessionRequestHandler> hle_handler = nullptr, |
| 59 | SharedPtr<ClientPort> client_port = nullptr); | ||
| 55 | 60 | ||
| 56 | /** | 61 | /** |
| 57 | * Handle a sync request from the emulated application. | 62 | * Handle a sync request from the emulated application. |
| @@ -63,8 +68,9 @@ public: | |||
| 63 | 68 | ||
| 64 | void Acquire(Thread* thread) override; | 69 | void Acquire(Thread* thread) override; |
| 65 | 70 | ||
| 66 | std::string name; ///< The name of this session (optional) | 71 | std::string name; ///< The name of this session (optional) |
| 67 | bool signaled; ///< Whether there's new data available to this ServerSession | 72 | bool signaled; ///< Whether there's new data available to this ServerSession |
| 73 | std::shared_ptr<Session> parent; ///< The parent session, which links to the client endpoint. | ||
| 68 | std::shared_ptr<Service::SessionRequestHandler> | 74 | std::shared_ptr<Service::SessionRequestHandler> |
| 69 | hle_handler; ///< This session's HLE request handler (optional) | 75 | hle_handler; ///< This session's HLE request handler (optional) |
| 70 | 76 | ||
diff --git a/src/core/hle/kernel/session.h b/src/core/hle/kernel/session.h new file mode 100644 index 000000000..a45e78022 --- /dev/null +++ b/src/core/hle/kernel/session.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | // Copyright 2017 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/kernel/kernel.h" | ||
| 8 | |||
| 9 | namespace Kernel { | ||
| 10 | |||
| 11 | class ClientSession; | ||
| 12 | class ClientPort; | ||
| 13 | class ServerSession; | ||
| 14 | |||
| 15 | /** | ||
| 16 | * Parent structure to link the client and server endpoints of a session with their associated | ||
| 17 | * client port. The client port need not exist, as is the case for portless sessions like the | ||
| 18 | * FS File and Directory sessions. When one of the endpoints of a session is destroyed, its | ||
| 19 | * corresponding field in this structure will be set to nullptr. | ||
| 20 | */ | ||
| 21 | class Session final { | ||
| 22 | public: | ||
| 23 | ClientSession* client = nullptr; ///< The client endpoint of the session. | ||
| 24 | ServerSession* server = nullptr; ///< The server endpoint of the session. | ||
| 25 | SharedPtr<ClientPort> port; ///< The port that this session is associated with (optional). | ||
| 26 | }; | ||
| 27 | } | ||
diff --git a/src/core/hle/result.h b/src/core/hle/result.h index cfefbbc64..13b948871 100644 --- a/src/core/hle/result.h +++ b/src/core/hle/result.h | |||
| @@ -16,6 +16,7 @@ | |||
| 16 | /// Detailed description of the error. This listing is likely incomplete. | 16 | /// Detailed description of the error. This listing is likely incomplete. |
| 17 | enum class ErrorDescription : u32 { | 17 | enum class ErrorDescription : u32 { |
| 18 | Success = 0, | 18 | Success = 0, |
| 19 | SessionClosedByRemote = 26, | ||
| 19 | WrongPermission = 46, | 20 | WrongPermission = 46, |
| 20 | OS_InvalidBufferDescriptor = 48, | 21 | OS_InvalidBufferDescriptor = 48, |
| 21 | MaxConnectionsReached = 52, | 22 | MaxConnectionsReached = 52, |