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/service/service.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index ca7eeac8a..f51a042ff 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -41,8 +41,8 @@ namespace Service { -std::unordered_map> g_kernel_named_ports; -std::unordered_map> g_srv_services; +std::unordered_map> g_kernel_named_ports; +std::unordered_map> g_srv_services; /** * Creates a function string for logging, complete with the name (or header code, depending @@ -61,7 +61,7 @@ static std::string MakeFunctionString(const char* name, const char* port_name, return function_string; } -ResultVal Interface::SyncRequest() { +ResultCode Interface::HandleSyncRequest() { u32* cmd_buff = Kernel::GetCommandBuffer(); auto itr = m_functions.find(cmd_buff[0]); @@ -75,14 +75,14 @@ ResultVal Interface::SyncRequest() { // TODO(bunnei): Hack - ignore error cmd_buff[1] = 0; - return MakeResult(false); + return RESULT_SUCCESS; } LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); itr->second.func(this); - return MakeResult(false); // TODO: Implement return from actual function + return RESULT_SUCCESS; // TODO: Implement return from actual function, it should fail if the parameter translation fails } void Interface::Register(const FunctionInfo* functions, size_t n) { @@ -97,10 +97,16 @@ void Interface::Register(const FunctionInfo* functions, size_t n) { // Module interface static void AddNamedPort(Interface* interface_) { + interface_->name = interface_->GetPortName(); + interface_->active_sessions = 0; + interface_->max_sessions = interface_->GetMaxSessions(); g_kernel_named_ports.emplace(interface_->GetPortName(), interface_); } void AddService(Interface* interface_) { + interface_->name = interface_->GetPortName(); + interface_->active_sessions = 0; + interface_->max_sessions = interface_->GetMaxSessions(); g_srv_services.emplace(interface_->GetPortName(), interface_); } -- 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/service/service.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index f51a042ff..abfc1806b 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -97,17 +97,13 @@ void Interface::Register(const FunctionInfo* functions, size_t n) { // Module interface static void AddNamedPort(Interface* interface_) { - interface_->name = interface_->GetPortName(); - interface_->active_sessions = 0; - interface_->max_sessions = interface_->GetMaxSessions(); - g_kernel_named_ports.emplace(interface_->GetPortName(), interface_); + auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::unique_ptr(interface_)); + g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); } void AddService(Interface* interface_) { - interface_->name = interface_->GetPortName(); - interface_->active_sessions = 0; - interface_->max_sessions = interface_->GetMaxSessions(); - g_srv_services.emplace(interface_->GetPortName(), interface_); + auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::unique_ptr(interface_)); + g_srv_services.emplace(interface_->GetPortName(), client_port); } /// Initialize ServiceManager -- 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/service/service.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index abfc1806b..56e4f8734 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -61,7 +61,9 @@ static std::string MakeFunctionString(const char* name, const char* port_name, return function_string; } -ResultCode Interface::HandleSyncRequest() { +ResultCode Interface::HandleSyncRequest(Kernel::SharedPtr server_session) { + // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. + u32* cmd_buff = Kernel::GetCommandBuffer(); auto itr = m_functions.find(cmd_buff[0]); @@ -97,12 +99,12 @@ void Interface::Register(const FunctionInfo* functions, size_t n) { // Module interface static void AddNamedPort(Interface* interface_) { - auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::unique_ptr(interface_)); + auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::shared_ptr(interface_)); g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); } void AddService(Interface* interface_) { - auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::unique_ptr(interface_)); + auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::shared_ptr(interface_)); g_srv_services.emplace(interface_->GetPortName(), client_port); } -- 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/service/service.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 56e4f8734..c90802455 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -4,6 +4,9 @@ #include "common/logging/log.h" #include "common/string_util.h" + +#include "core/hle/kernel/server_port.h" +#include "core/hle/service/service.h" #include "core/hle/service/ac_u.h" #include "core/hle/service/act_a.h" #include "core/hle/service/act_u.h" @@ -41,8 +44,8 @@ namespace Service { -std::unordered_map> g_kernel_named_ports; -std::unordered_map> g_srv_services; +std::unordered_map, std::shared_ptr>> g_kernel_named_ports; +std::unordered_map, std::shared_ptr>> g_srv_services; /** * Creates a function string for logging, complete with the name (or header code, depending @@ -99,13 +102,15 @@ void Interface::Register(const FunctionInfo* functions, size_t n) { // Module interface static void AddNamedPort(Interface* interface_) { - auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::shared_ptr(interface_)); - g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); + auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName()); + auto client_port = std::get>(ports); + g_kernel_named_ports.emplace(interface_->GetPortName(), std::make_tuple(client_port, std::shared_ptr(interface_))); } void AddService(Interface* interface_) { - auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::shared_ptr(interface_)); - g_srv_services.emplace(interface_->GetPortName(), client_port); + auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName()); + auto client_port = std::get>(ports); + g_srv_services.emplace(interface_->GetPortName(), std::make_tuple(client_port, std::shared_ptr(interface_))); } /// Initialize ServiceManager -- 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/service/service.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index c90802455..3462af8ce 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -44,8 +44,8 @@ namespace Service { -std::unordered_map, std::shared_ptr>> g_kernel_named_ports; -std::unordered_map, std::shared_ptr>> g_srv_services; +std::unordered_map> g_kernel_named_ports; +std::unordered_map> g_srv_services; /** * Creates a function string for logging, complete with the name (or header code, depending @@ -102,15 +102,17 @@ void Interface::Register(const FunctionInfo* functions, size_t n) { // Module interface static void AddNamedPort(Interface* interface_) { - auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName()); + auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), + std::shared_ptr(interface_)); auto client_port = std::get>(ports); - g_kernel_named_ports.emplace(interface_->GetPortName(), std::make_tuple(client_port, std::shared_ptr(interface_))); + g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); } void AddService(Interface* interface_) { - auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName()); + auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), + std::shared_ptr(interface_)); auto client_port = std::get>(ports); - g_srv_services.emplace(interface_->GetPortName(), std::make_tuple(client_port, std::shared_ptr(interface_))); + g_srv_services.emplace(interface_->GetPortName(), client_port); } /// Initialize ServiceManager -- 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/service/service.cpp | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 3462af8ce..3d5e3058c 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -64,7 +64,27 @@ static std::string MakeFunctionString(const char* name, const char* port_name, return function_string; } -ResultCode Interface::HandleSyncRequest(Kernel::SharedPtr server_session) { +ResultCode SessionRequestHandler::HandleSyncRequest(Kernel::SharedPtr server_session) { + // Attempt to translate the incoming request's command buffer. + ResultCode result = TranslateRequest(server_session); + + if (result.IsError()) + return result; + + // Actually handle the request + HandleSyncRequestImpl(server_session); + + // TODO(Subv): Translate the response command buffer. + + return RESULT_SUCCESS; +} + +ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr server_session) { + // TODO(Subv): Implement this function once multiple concurrent processes are supported. + return RESULT_SUCCESS; +} + +void Interface::HandleSyncRequestImpl(Kernel::SharedPtr server_session) { // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -80,14 +100,12 @@ ResultCode Interface::HandleSyncRequest(Kernel::SharedPtr // TODO(bunnei): Hack - ignore error cmd_buff[1] = 0; - return RESULT_SUCCESS; + return; } LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); itr->second.func(this); - - return RESULT_SUCCESS; // TODO: Implement return from actual function, it should fail if the parameter translation fails } void Interface::Register(const FunctionInfo* functions, size_t n) { @@ -179,4 +197,5 @@ void Shutdown() { g_kernel_named_ports.clear(); LOG_DEBUG(Service, "shutdown OK"); } + } -- 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/service/service.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 3d5e3058c..6ea5cf745 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -84,6 +84,9 @@ ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr server_session) { // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. @@ -123,14 +126,14 @@ static void AddNamedPort(Interface* interface_) { auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), std::shared_ptr(interface_)); auto client_port = std::get>(ports); - g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); + g_kernel_named_ports.emplace(interface_->GetPortName(), std::move(client_port)); } void AddService(Interface* interface_) { auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), std::shared_ptr(interface_)); auto client_port = std::get>(ports); - g_srv_services.emplace(interface_->GetPortName(), client_port); + g_srv_services.emplace(interface_->GetPortName(), std::move(client_port)); } /// Initialize ServiceManager -- 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/service/service.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 6ea5cf745..167cb09a8 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -2,6 +2,8 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include + #include "common/logging/log.h" #include "common/string_util.h" @@ -79,6 +81,14 @@ ResultCode SessionRequestHandler::HandleSyncRequest(Kernel::SharedPtr server_session) { + connected_sessions.push_back(server_session); +} + +void SessionRequestHandler::ClientDisconnected(Kernel::SharedPtr server_session) { + boost::range::remove_erase(connected_sessions, server_session); +} + ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr server_session) { // TODO(Subv): Implement this function once multiple concurrent processes are supported. return RESULT_SUCCESS; -- cgit v1.2.3 From deb83c9fc5c27ca8c50db0b00deb9cd798a814e7 Mon Sep 17 00:00:00 2001 From: Subv Date: Fri, 9 Dec 2016 12:39:12 -0500 Subject: Kernel/IPC: Small codestyle cleanup --- src/core/hle/service/service.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 167cb09a8..4f973c634 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -94,8 +94,8 @@ ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr server_session) { // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. -- 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/service/service.cpp | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 4f973c634..418b128b1 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -66,21 +66,6 @@ static std::string MakeFunctionString(const char* name, const char* port_name, return function_string; } -ResultCode SessionRequestHandler::HandleSyncRequest(Kernel::SharedPtr server_session) { - // Attempt to translate the incoming request's command buffer. - ResultCode result = TranslateRequest(server_session); - - if (result.IsError()) - return result; - - // Actually handle the request - HandleSyncRequestImpl(server_session); - - // TODO(Subv): Translate the response command buffer. - - return RESULT_SUCCESS; -} - void SessionRequestHandler::ClientConnected(Kernel::SharedPtr server_session) { connected_sessions.push_back(server_session); } @@ -89,15 +74,10 @@ void SessionRequestHandler::ClientDisconnected(Kernel::SharedPtr server_session) { - // TODO(Subv): Implement this function once multiple concurrent processes are supported. - return RESULT_SUCCESS; -} - Interface::Interface(u32 max_sessions) : max_sessions(max_sessions) {} Interface::~Interface() = default; -void Interface::HandleSyncRequestImpl(Kernel::SharedPtr server_session) { +void Interface::HandleSyncRequest(Kernel::SharedPtr server_session) { // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. u32* cmd_buff = Kernel::GetCommandBuffer(); -- 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/service/service.cpp | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) (limited to 'src/core/hle/service/service.cpp') diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 418b128b1..9f68898db 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -8,7 +8,6 @@ #include "common/string_util.h" #include "core/hle/kernel/server_port.h" -#include "core/hle/service/service.h" #include "core/hle/service/ac_u.h" #include "core/hle/service/act_a.h" #include "core/hle/service/act_u.h" @@ -66,11 +65,13 @@ static std::string MakeFunctionString(const char* name, const char* port_name, return function_string; } -void SessionRequestHandler::ClientConnected(Kernel::SharedPtr server_session) { +void SessionRequestHandler::ClientConnected( + Kernel::SharedPtr server_session) { connected_sessions.push_back(server_session); } -void SessionRequestHandler::ClientDisconnected(Kernel::SharedPtr server_session) { +void SessionRequestHandler::ClientDisconnected( + Kernel::SharedPtr server_session) { boost::range::remove_erase(connected_sessions, server_session); } @@ -78,7 +79,8 @@ Interface::Interface(u32 max_sessions) : max_sessions(max_sessions) {} Interface::~Interface() = default; void Interface::HandleSyncRequest(Kernel::SharedPtr server_session) { - // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. + // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which + // session triggered each command. u32* cmd_buff = Kernel::GetCommandBuffer(); auto itr = m_functions.find(cmd_buff[0]); @@ -113,15 +115,17 @@ void Interface::Register(const FunctionInfo* functions, size_t n) { // Module interface static void AddNamedPort(Interface* interface_) { - auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), - std::shared_ptr(interface_)); + auto ports = + Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), + std::shared_ptr(interface_)); auto client_port = std::get>(ports); g_kernel_named_ports.emplace(interface_->GetPortName(), std::move(client_port)); } void AddService(Interface* interface_) { - auto ports = Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), - std::shared_ptr(interface_)); + auto ports = + Kernel::ServerPort::CreatePortPair(interface_->GetMaxSessions(), interface_->GetPortName(), + std::shared_ptr(interface_)); auto client_port = std::get>(ports); g_srv_services.emplace(interface_->GetPortName(), std::move(client_port)); } @@ -190,5 +194,4 @@ void Shutdown() { g_kernel_named_ports.clear(); LOG_DEBUG(Service, "shutdown OK"); } - } -- cgit v1.2.3