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/server_session.cpp | 58 ++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 src/core/hle/kernel/server_session.cpp (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp new file mode 100644 index 000000000..9f5350ce5 --- /dev/null +++ b/src/core/hle/kernel/server_session.cpp @@ -0,0 +1,58 @@ +// Copyright 2016 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include + +#include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" +#include "core/hle/kernel/server_session.h" +#include "core/hle/kernel/thread.h" + +namespace Kernel { + +ServerSession::ServerSession() {} +ServerSession::~ServerSession() {} + +ResultVal> ServerSession::Create(std::string name) { + SharedPtr server_session(new ServerSession); + + server_session->name = std::move(name); + server_session->signaled = false; + + return MakeResult>(std::move(server_session)); +} + +bool ServerSession::ShouldWait() { + return !signaled; +} + +void ServerSession::Acquire() { + ASSERT_MSG(!ShouldWait(), "object unavailable!"); + signaled = false; +} + +ResultCode ServerSession::HandleSyncRequest() { + // The ServerSession received a sync request, this means that there's new data available + // from one of its ClientSessions, so wake up any threads that may be waiting on a svcReplyAndReceive or similar. + signaled = true; + WakeupAllWaitingThreads(); + return RESULT_SUCCESS; +} + +SharedPtr ServerSession::CreateClientSession() { + // In Citra, some types of ServerSessions (File and Directory sessions) are not created as a pair of Server-Client sessions, + // but are instead created as a single ServerSession, which then hands over a ClientSession on demand (When opening the File or Directory). + // The real kernel (Or more specifically, the real FS service) does create the pair of Sessions at the same time (via svcCreateSession), and simply + // stores the ClientSession until it is needed. + return ClientSession::Create(SharedPtr(this), nullptr, name + "Client").MoveFrom(); +} + +std::tuple, SharedPtr> ServerSession::CreateSessionPair(SharedPtr client_port, std::string name) { + auto server_session = ServerSession::Create(name + "Server").MoveFrom(); + auto client_session = ClientSession::Create(server_session, client_port, name + "Client").MoveFrom(); + + return std::make_tuple(server_session, client_session); +} + +} -- cgit v1.2.3 From 0a33d915f88b89e2fae20edc1e33a8ef60a2519c Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 17 Jun 2016 15:24:38 -0500 Subject: fixup! Kernel/IPC: Use Ports and Sessions as the fundamental building block of Inter Process Communication. --- src/core/hle/kernel/server_session.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 9f5350ce5..720c0eb94 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -48,7 +48,7 @@ SharedPtr ServerSession::CreateClientSession() { return ClientSession::Create(SharedPtr(this), nullptr, name + "Client").MoveFrom(); } -std::tuple, SharedPtr> ServerSession::CreateSessionPair(SharedPtr client_port, std::string name) { +std::tuple, SharedPtr> ServerSession::CreateSessionPair(SharedPtr client_port, const std::string& name) { auto server_session = ServerSession::Create(name + "Server").MoveFrom(); auto client_session = ClientSession::Create(server_session, client_port, name + "Client").MoveFrom(); -- 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/server_session.cpp | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 720c0eb94..200a7b815 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -14,11 +14,12 @@ namespace Kernel { ServerSession::ServerSession() {} ServerSession::~ServerSession() {} -ResultVal> ServerSession::Create(std::string name) { +ResultVal> ServerSession::Create(std::string name, std::shared_ptr hle_handler) { SharedPtr server_session(new ServerSession); server_session->name = std::move(name); server_session->signaled = false; + server_session->hle_handler = hle_handler; return MakeResult>(std::move(server_session)); } @@ -34,23 +35,21 @@ void ServerSession::Acquire() { ResultCode ServerSession::HandleSyncRequest() { // The ServerSession received a sync request, this means that there's new data available - // from one of its ClientSessions, so wake up any threads that may be waiting on a svcReplyAndReceive or similar. + // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or similar. + + // If this ServerSession has an associated HLE handler, forward the request to it. + if (hle_handler != nullptr) + return hle_handler->HandleSyncRequest(SharedPtr(this)); + + // If this ServerSession does not have an HLE implementation, just wake up the threads waiting on it. signaled = true; WakeupAllWaitingThreads(); return RESULT_SUCCESS; } -SharedPtr ServerSession::CreateClientSession() { - // In Citra, some types of ServerSessions (File and Directory sessions) are not created as a pair of Server-Client sessions, - // but are instead created as a single ServerSession, which then hands over a ClientSession on demand (When opening the File or Directory). - // The real kernel (Or more specifically, the real FS service) does create the pair of Sessions at the same time (via svcCreateSession), and simply - // stores the ClientSession until it is needed. - return ClientSession::Create(SharedPtr(this), nullptr, name + "Client").MoveFrom(); -} - -std::tuple, SharedPtr> ServerSession::CreateSessionPair(SharedPtr client_port, const std::string& name) { - auto server_session = ServerSession::Create(name + "Server").MoveFrom(); - auto client_session = ClientSession::Create(server_session, client_port, name + "Client").MoveFrom(); +std::tuple, SharedPtr> ServerSession::CreateSessionPair(const std::string& name, std::shared_ptr hle_handler) { + auto server_session = ServerSession::Create(name + "Server", hle_handler).MoveFrom(); + auto client_session = ClientSession::Create(server_session, name + "Client").MoveFrom(); return std::make_tuple(server_session, client_session); } -- 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/server_session.cpp | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 200a7b815..006d67e65 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -4,7 +4,6 @@ #include -#include "core/hle/kernel/client_port.h" #include "core/hle/kernel/client_session.h" #include "core/hle/kernel/server_session.h" #include "core/hle/kernel/thread.h" -- cgit v1.2.3 From 2ce61344d612b8574e12d8acdf59ac994b390ab5 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 2 Dec 2016 22:58:02 -0500 Subject: Declare empty ServerSession and ClientSession constructors as default. --- src/core/hle/kernel/server_session.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 006d67e65..be334efd7 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -10,8 +10,8 @@ namespace Kernel { -ServerSession::ServerSession() {} -ServerSession::~ServerSession() {} +ServerSession::ServerSession() = default; +ServerSession::~ServerSession() = default; ResultVal> ServerSession::Create(std::string name, std::shared_ptr hle_handler) { SharedPtr server_session(new ServerSession); -- 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/server_session.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index be334efd7..3782cb493 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -47,10 +47,10 @@ ResultCode ServerSession::HandleSyncRequest() { } std::tuple, SharedPtr> ServerSession::CreateSessionPair(const std::string& name, std::shared_ptr hle_handler) { - auto server_session = ServerSession::Create(name + "Server", hle_handler).MoveFrom(); - auto client_session = ClientSession::Create(server_session, name + "Client").MoveFrom(); + auto server_session = ServerSession::Create(name + "_Server", hle_handler).MoveFrom(); + auto client_session = ClientSession::Create(server_session, name + "_Client").MoveFrom(); - return std::make_tuple(server_session, client_session); + return std::make_tuple(std::move(server_session), std::move(client_session)); } } -- 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/server_session.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 3782cb493..f8bccadfd 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -18,7 +18,7 @@ ResultVal> ServerSession::Create(std::string name, std: server_session->name = std::move(name); server_session->signaled = false; - server_session->hle_handler = hle_handler; + server_session->hle_handler = std::move(hle_handler); return MakeResult>(std::move(server_session)); } @@ -46,8 +46,9 @@ ResultCode ServerSession::HandleSyncRequest() { return RESULT_SUCCESS; } -std::tuple, SharedPtr> ServerSession::CreateSessionPair(const std::string& name, std::shared_ptr hle_handler) { - auto server_session = ServerSession::Create(name + "_Server", hle_handler).MoveFrom(); +ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, + std::shared_ptr hle_handler) { + auto server_session = ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); auto client_session = ClientSession::Create(server_session, name + "_Client").MoveFrom(); return std::make_tuple(std::move(server_session), std::move(client_session)); -- 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/server_session.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index f8bccadfd..3fac6b934 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -11,7 +11,11 @@ namespace Kernel { ServerSession::ServerSession() = default; -ServerSession::~ServerSession() = default; +ServerSession::~ServerSession() { + // This destructor will be called automatically when the last ServerSession handle is closed by the emulated application. + // TODO(Subv): Reduce the ClientPort's connection count, + // if the session is still open, set the connection status to 3 (Closed by server), +} ResultVal> ServerSession::Create(std::string name, std::shared_ptr hle_handler) { SharedPtr server_session(new ServerSession); @@ -49,7 +53,9 @@ ResultCode ServerSession::HandleSyncRequest() { ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, std::shared_ptr hle_handler) { auto server_session = ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); - auto client_session = ClientSession::Create(server_session, name + "_Client").MoveFrom(); + // We keep a non-owning pointer to the ServerSession in the ClientSession because we don't want to prevent the + // ServerSession's destructor from being called when the emulated application closes the last ServerSession handle. + auto client_session = ClientSession::Create(server_session.get(), name + "_Client").MoveFrom(); return std::make_tuple(std::move(server_session), std::move(client_session)); } -- cgit v1.2.3 From ebbb55ec8f827096f1c743cc4b7f4a2aa05a3ed3 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 9 Dec 2016 12:52:12 -0500 Subject: Moved the HLE command buffer translation task to ServerSession instead of the HLE handler superclass. --- src/core/hle/kernel/server_session.cpp | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 3fac6b934..1e54c3a2e 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -41,8 +41,14 @@ ResultCode ServerSession::HandleSyncRequest() { // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or similar. // If this ServerSession has an associated HLE handler, forward the request to it. - if (hle_handler != nullptr) - return hle_handler->HandleSyncRequest(SharedPtr(this)); + if (hle_handler != nullptr) { + // Attempt to translate the incoming request's command buffer. + ResultCode result = TranslateHLERequest(this); + if (result.IsError()) + return result; + hle_handler->HandleSyncRequest(SharedPtr(this)); + // TODO(Subv): Translate the response command buffer. + } // If this ServerSession does not have an HLE implementation, just wake up the threads waiting on it. signaled = true; @@ -60,4 +66,9 @@ ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& n return std::make_tuple(std::move(server_session), std::move(client_session)); } +ResultCode TranslateHLERequest(ServerSession* server_session) { + // TODO(Subv): Implement this function once multiple concurrent processes are supported. + return RESULT_SUCCESS; +} + } -- 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/server_session.cpp | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src/core/hle/kernel/server_session.cpp') diff --git a/src/core/hle/kernel/server_session.cpp b/src/core/hle/kernel/server_session.cpp index 1e54c3a2e..146458c1c 100644 --- a/src/core/hle/kernel/server_session.cpp +++ b/src/core/hle/kernel/server_session.cpp @@ -12,12 +12,14 @@ namespace Kernel { ServerSession::ServerSession() = default; ServerSession::~ServerSession() { - // This destructor will be called automatically when the last ServerSession handle is closed by the emulated application. + // This destructor will be called automatically when the last ServerSession handle is closed by + // the emulated application. // TODO(Subv): Reduce the ClientPort's connection count, // if the session is still open, set the connection status to 3 (Closed by server), } -ResultVal> ServerSession::Create(std::string name, std::shared_ptr hle_handler) { +ResultVal> ServerSession::Create( + std::string name, std::shared_ptr hle_handler) { SharedPtr server_session(new ServerSession); server_session->name = std::move(name); @@ -38,7 +40,8 @@ void ServerSession::Acquire() { ResultCode ServerSession::HandleSyncRequest() { // The ServerSession received a sync request, this means that there's new data available - // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or similar. + // from its ClientSession, so wake up any threads that may be waiting on a svcReplyAndReceive or + // similar. // If this ServerSession has an associated HLE handler, forward the request to it. if (hle_handler != nullptr) { @@ -50,17 +53,20 @@ ResultCode ServerSession::HandleSyncRequest() { // TODO(Subv): Translate the response command buffer. } - // If this ServerSession does not have an HLE implementation, just wake up the threads waiting on it. + // If this ServerSession does not have an HLE implementation, just wake up the threads waiting + // on it. signaled = true; WakeupAllWaitingThreads(); return RESULT_SUCCESS; } -ServerSession::SessionPair ServerSession::CreateSessionPair(const std::string& name, - std::shared_ptr hle_handler) { - auto server_session = ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); - // We keep a non-owning pointer to the ServerSession in the ClientSession because we don't want to prevent the - // ServerSession's destructor from being called when the emulated application closes the last ServerSession handle. +ServerSession::SessionPair ServerSession::CreateSessionPair( + const std::string& name, std::shared_ptr hle_handler) { + auto server_session = + ServerSession::Create(name + "_Server", std::move(hle_handler)).MoveFrom(); + // We keep a non-owning pointer to the ServerSession in the ClientSession because we don't want + // to prevent the ServerSession's destructor from being called when the emulated + // application closes the last ServerSession handle. auto client_session = ClientSession::Create(server_session.get(), name + "_Client").MoveFrom(); return std::make_tuple(std::move(server_session), std::move(client_session)); @@ -70,5 +76,4 @@ ResultCode TranslateHLERequest(ServerSession* server_session) { // TODO(Subv): Implement this function once multiple concurrent processes are supported. return RESULT_SUCCESS; } - } -- cgit v1.2.3