From 073653e858abf377fd1ebbdb071809c8830ce99d Mon Sep 17 00:00:00 2001 From: Subv Date: Tue, 14 Jun 2016 18:03:30 -0500 Subject: Kernel/IPC: Use Ports and Sessions as the fundamental building block of Inter Process Communication. All handles obtained via srv::GetServiceHandle or svcConnectToPort are references to ClientSessions. Service modules will wait on the counterpart of those ClientSessions (Called ServerSessions) using svcReplyAndReceive or svcWaitSynchronization[1|N], and will be awoken when a SyncRequest is performed. HLE Interfaces are now ClientPorts which override the HandleSyncRequest virtual member function to perform command handling immediately. --- src/core/hle/kernel/client_port.cpp | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index aedc6f989..5ee7679eb 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -6,10 +6,17 @@ #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_port.h" +#include "core/hle/kernel/server_session.h" namespace Kernel { ClientPort::ClientPort() {} ClientPort::~ClientPort() {} +void ClientPort::AddWaitingSession(SharedPtr server_session) { + server_port->pending_sessions.push_back(server_session); + // Wake the threads waiting on the ServerPort + server_port->WakeupAllWaitingThreads(); +} + } // namespace -- cgit v1.2.3 From c19afd21188e91b9dd2780cf5cb9872a17ad113d Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 17 Jun 2016 17:09:43 -0500 Subject: Kernel/HLE: Service::Interface no longer inherits from any Kernel object, and is now its own standalone class. Interface is now used by aggregation in ClientPort, to forward service commands to their HLE implementation if needed. --- src/core/hle/kernel/client_port.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 5ee7679eb..9a9cd4bfd 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -7,16 +7,39 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" +#include "core/hle/service/service.h" namespace Kernel { ClientPort::ClientPort() {} ClientPort::~ClientPort() {} +Kernel::SharedPtr ClientPort::CreateForHLE(u32 max_sessions, std::unique_ptr hle_interface) { + SharedPtr client_port(new ClientPort); + client_port->max_sessions = max_sessions; + client_port->active_sessions = 0; + client_port->name = hle_interface->GetPortName(); + client_port->hle_interface = std::move(hle_interface); + + return client_port; +} + void ClientPort::AddWaitingSession(SharedPtr server_session) { + // A port that has an associated HLE interface doesn't have a server port. + if (hle_interface != nullptr) + return; + server_port->pending_sessions.push_back(server_session); // Wake the threads waiting on the ServerPort server_port->WakeupAllWaitingThreads(); } +ResultCode ClientPort::HandleSyncRequest() { + // Forward the request to the associated HLE interface if it exists + if (hle_interface != nullptr) + return hle_interface->HandleSyncRequest(); + + return RESULT_SUCCESS; +} + } // namespace -- cgit v1.2.3 From c5e7e0fa26fc793c8b9f3effe25586f7fb57953e Mon Sep 17 00:00:00 2001 From: Subv Date: Sat, 18 Jun 2016 13:39:26 -0500 Subject: IPC/HLE: Associate the ClientSessions with their parent port's HLE interface if it exists. Pass the triggering ServerSession to the HLE command handler to differentiate which session caused the request. --- src/core/hle/kernel/client_port.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 9a9cd4bfd..0ac36cd12 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -14,7 +14,7 @@ namespace Kernel { ClientPort::ClientPort() {} ClientPort::~ClientPort() {} -Kernel::SharedPtr ClientPort::CreateForHLE(u32 max_sessions, std::unique_ptr hle_interface) { +Kernel::SharedPtr ClientPort::CreateForHLE(u32 max_sessions, std::shared_ptr hle_interface) { SharedPtr client_port(new ClientPort); client_port->max_sessions = max_sessions; client_port->active_sessions = 0; @@ -34,12 +34,4 @@ void ClientPort::AddWaitingSession(SharedPtr server_session) { server_port->WakeupAllWaitingThreads(); } -ResultCode ClientPort::HandleSyncRequest() { - // Forward the request to the associated HLE interface if it exists - if (hle_interface != nullptr) - return hle_interface->HandleSyncRequest(); - - return RESULT_SUCCESS; -} - } // namespace -- cgit v1.2.3 From 009b15b3aa9858930f461d825f7dd030fc963801 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 30 Nov 2016 22:50:13 -0500 Subject: A bit of a redesign. Sessions and Ports are now detached from each other. HLE services are handled by means of a SessionRequestHandler class, Interface now inherits from this class. The File and Directory classes are no longer kernel objects, but SessionRequestHandlers instead, bound to a ServerSession when requested. File::OpenLinkFile now creates a new session pair and binds the File instance to it. --- src/core/hle/kernel/client_port.cpp | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 0ac36cd12..de67688c9 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -14,21 +14,7 @@ namespace Kernel { ClientPort::ClientPort() {} ClientPort::~ClientPort() {} -Kernel::SharedPtr ClientPort::CreateForHLE(u32 max_sessions, std::shared_ptr hle_interface) { - SharedPtr client_port(new ClientPort); - client_port->max_sessions = max_sessions; - client_port->active_sessions = 0; - client_port->name = hle_interface->GetPortName(); - client_port->hle_interface = std::move(hle_interface); - - return client_port; -} - void ClientPort::AddWaitingSession(SharedPtr server_session) { - // A port that has an associated HLE interface doesn't have a server port. - if (hle_interface != nullptr) - return; - server_port->pending_sessions.push_back(server_session); // Wake the threads waiting on the ServerPort server_port->WakeupAllWaitingThreads(); -- cgit v1.2.3 From 2eceee3a4cc2786dae4e9b80a8b5f3bb666d3fc6 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 30 Nov 2016 23:28:31 -0500 Subject: Fixed the rebase mistakes. --- src/core/hle/kernel/client_port.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index de67688c9..5ee7679eb 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -7,7 +7,6 @@ #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" -#include "core/hle/service/service.h" namespace Kernel { -- cgit v1.2.3 From dd8887c8cfbb6d3010dde240278a3d4018c5dd85 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 5 Dec 2016 11:02:08 -0500 Subject: KServerPorts now have an HLE handler "template", which is inherited by all ServerSessions created from it. --- src/core/hle/kernel/client_port.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 5ee7679eb..f25cb48dd 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -13,10 +13,18 @@ namespace Kernel { ClientPort::ClientPort() {} ClientPort::~ClientPort() {} -void ClientPort::AddWaitingSession(SharedPtr server_session) { +SharedPtr ClientPort::Connect() { + // Create a new session pair, let the created sessions inherit the parent port's HLE handler. + auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), server_port->hle_handler); + auto client_session = std::get>(sessions); + auto server_session = std::get>(sessions); + server_port->pending_sessions.push_back(server_session); + // Wake the threads waiting on the ServerPort server_port->WakeupAllWaitingThreads(); + + return std::move(client_session); } } // namespace -- cgit v1.2.3 From 00f0c775702af4145a4a81ec5d357c3586a5c6c3 Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 5 Dec 2016 12:05:00 -0500 Subject: Split SessionRequestHandler::HandleSyncRequest into HandleSyncRequest, TranslateRequest and HandleSyncRequestImpl. HandleSyncRequest now takes care of calling the command buffer translate function before actually invoking the command handler for HLE services. --- src/core/hle/kernel/client_port.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index f25cb48dd..b6a4cab26 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -4,6 +4,7 @@ #include "common/assert.h" #include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" -- cgit v1.2.3 From c93c5a72bb46796e898f54a7c13dfb8d941ddd4d Mon Sep 17 00:00:00 2001 From: Subv Date: Mon, 5 Dec 2016 13:59:57 -0500 Subject: Return an error code when connecting to a saturated port. The error code was taken from the 3DS kernel. --- src/core/hle/kernel/client_port.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index b6a4cab26..120ce554d 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -14,7 +14,14 @@ namespace Kernel { ClientPort::ClientPort() {} ClientPort::~ClientPort() {} -SharedPtr ClientPort::Connect() { +ResultVal> ClientPort::Connect() { + if (active_sessions >= max_sessions) { + return ResultCode(ErrorDescription::MaxConnectionsReached, + ErrorModule::OS, ErrorSummary::WouldBlock, + ErrorLevel::Temporary); + } + active_sessions++; + // Create a new session pair, let the created sessions inherit the parent port's HLE handler. auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), server_port->hle_handler); auto client_session = std::get>(sessions); @@ -25,7 +32,7 @@ SharedPtr ClientPort::Connect() { // Wake the threads waiting on the ServerPort server_port->WakeupAllWaitingThreads(); - return std::move(client_session); + return MakeResult>(std::move(client_session)); } } // namespace -- cgit v1.2.3 From f9bcf895103e5a6d99f5fe755bcac92b7781fd38 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 8 Dec 2016 11:06:19 -0500 Subject: Use std::move where appropriate. --- src/core/hle/kernel/client_port.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 120ce554d..20179e546 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -15,6 +15,9 @@ ClientPort::ClientPort() {} ClientPort::~ClientPort() {} ResultVal> ClientPort::Connect() { + // Note: Threads do not wait for the server endpoint to call + // AcceptSession before returning from this call. + if (active_sessions >= max_sessions) { return ResultCode(ErrorDescription::MaxConnectionsReached, ErrorModule::OS, ErrorSummary::WouldBlock, @@ -27,7 +30,7 @@ ResultVal> ClientPort::Connect() { auto client_session = std::get>(sessions); auto server_session = std::get>(sessions); - server_port->pending_sessions.push_back(server_session); + server_port->pending_sessions.push_back(std::move(server_session)); // Wake the threads waiting on the ServerPort server_port->WakeupAllWaitingThreads(); -- cgit v1.2.3 From 386112da3265d111595329508b860800e5cf14e8 Mon Sep 17 00:00:00 2001 From: Subv Date: Thu, 8 Dec 2016 15:01:10 -0500 Subject: Added a framework for partially handling Session disconnections. Further implementation will happen in a future commit. Fixes a regression. --- src/core/hle/kernel/client_port.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index 20179e546..bd8ef055d 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -19,9 +19,10 @@ ResultVal> ClientPort::Connect() { // AcceptSession before returning from this call. if (active_sessions >= max_sessions) { - return ResultCode(ErrorDescription::MaxConnectionsReached, + // TODO(Subv): Return an error code in this situation after session disconnection is implemented. + /*return ResultCode(ErrorDescription::MaxConnectionsReached, ErrorModule::OS, ErrorSummary::WouldBlock, - ErrorLevel::Temporary); + ErrorLevel::Temporary);*/ } active_sessions++; @@ -30,6 +31,9 @@ ResultVal> ClientPort::Connect() { auto client_session = std::get>(sessions); auto server_session = std::get>(sessions); + if (server_port->hle_handler) + server_port->hle_handler->ClientConnected(server_session); + server_port->pending_sessions.push_back(std::move(server_session)); // Wake the threads waiting on the ServerPort -- cgit v1.2.3 From 016307ae656afc85ab59a5c2598205ef81f99231 Mon Sep 17 00:00:00 2001 From: Subv Date: Wed, 14 Dec 2016 12:33:49 -0500 Subject: Fixed the codestyle to match our clang-format rules. --- src/core/hle/kernel/client_port.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/client_port.cpp') diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index bd8ef055d..22645f4ec 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -19,7 +19,8 @@ ResultVal> ClientPort::Connect() { // AcceptSession before returning from this call. if (active_sessions >= max_sessions) { - // TODO(Subv): Return an error code in this situation after session disconnection is implemented. + // TODO(Subv): Return an error code in this situation after session disconnection is + // implemented. /*return ResultCode(ErrorDescription::MaxConnectionsReached, ErrorModule::OS, ErrorSummary::WouldBlock, ErrorLevel::Temporary);*/ @@ -27,7 +28,8 @@ ResultVal> ClientPort::Connect() { active_sessions++; // Create a new session pair, let the created sessions inherit the parent port's HLE handler. - auto sessions = ServerSession::CreateSessionPair(server_port->GetName(), server_port->hle_handler); + auto sessions = + ServerSession::CreateSessionPair(server_port->GetName(), server_port->hle_handler); auto client_session = std::get>(sessions); auto server_session = std::get>(sessions); -- cgit v1.2.3