diff options
author | Subv <subv2112@gmail.com> | 2016-06-18 00:09:43 +0200 |
---|---|---|
committer | Subv <subv2112@gmail.com> | 2016-12-01 05:03:59 +0100 |
commit | c19afd21188e91b9dd2780cf5cb9872a17ad113d (patch) | |
tree | 5404cd7850f049d474dbcc3cc4ee80874b0c7627 /src | |
parent | fixup! Kernel/IPC: Use Ports and Sessions as the fundamental building block of Inter Process Communication. (diff) | |
download | yuzu-c19afd21188e91b9dd2780cf5cb9872a17ad113d.tar yuzu-c19afd21188e91b9dd2780cf5cb9872a17ad113d.tar.gz yuzu-c19afd21188e91b9dd2780cf5cb9872a17ad113d.tar.bz2 yuzu-c19afd21188e91b9dd2780cf5cb9872a17ad113d.tar.lz yuzu-c19afd21188e91b9dd2780cf5cb9872a17ad113d.tar.xz yuzu-c19afd21188e91b9dd2780cf5cb9872a17ad113d.tar.zst yuzu-c19afd21188e91b9dd2780cf5cb9872a17ad113d.zip |
Diffstat (limited to 'src')
-rw-r--r-- | src/core/hle/kernel/client_port.cpp | 23 | ||||
-rw-r--r-- | src/core/hle/kernel/client_port.h | 29 | ||||
-rw-r--r-- | src/core/hle/service/service.cpp | 12 | ||||
-rw-r--r-- | src/core/hle/service/service.h | 12 |
4 files changed, 52 insertions, 24 deletions
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> ClientPort::CreateForHLE(u32 max_sessions, std::unique_ptr<Service::Interface> hle_interface) { + SharedPtr<ClientPort> 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<ServerSession> 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 diff --git a/src/core/hle/kernel/client_port.h b/src/core/hle/kernel/client_port.h index eb0882870..ee65606ba 100644 --- a/src/core/hle/kernel/client_port.h +++ b/src/core/hle/kernel/client_port.h @@ -5,19 +5,32 @@ #pragma once #include <string> +#include <memory> #include "common/common_types.h" #include "core/hle/kernel/kernel.h" +namespace Service { +class Interface; +} + namespace Kernel { class ServerPort; class ServerSession; -class ClientPort : public Object { +class ClientPort final : public Object { public: friend class ServerPort; /** + * Creates a serverless ClientPort that represents a bridge between the HLE implementation of a service/port and the emulated application. + * @param max_sessions Maximum number of sessions that this port is able to handle concurrently. + * @param hle_interface Interface object that implements the commands of the service. + * @returns ClientPort for the given HLE interface. + */ + static Kernel::SharedPtr<ClientPort> CreateForHLE(u32 max_sessions, std::unique_ptr<Service::Interface> hle_interface); + + /** * Adds the specified server session to the queue of pending sessions of the associated ServerPort * @param server_session Server session to add to the queue */ @@ -25,10 +38,9 @@ public: /** * Handle a sync request from the emulated application. - * Only HLE services should override this function. * @returns ResultCode from the operation. */ - virtual ResultCode HandleSyncRequest() { return RESULT_SUCCESS; } + ResultCode HandleSyncRequest(); std::string GetTypeName() const override { return "ClientPort"; } std::string GetName() const override { return name; } @@ -38,12 +50,13 @@ public: return HANDLE_TYPE; } - SharedPtr<ServerPort> server_port; ///< ServerPort associated with this client port. - u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have - u32 active_sessions; ///< Number of currently open sessions to this port - std::string name; ///< Name of client port (optional) + SharedPtr<ServerPort> server_port = nullptr; ///< ServerPort associated with this client port. + u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have + u32 active_sessions; ///< Number of currently open sessions to this port + std::string name; ///< Name of client port (optional) + std::unique_ptr<Service::Interface> hle_interface = nullptr; ///< HLE implementation of this port's request handler -protected: +private: ClientPort(); ~ClientPort() override; }; 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>(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>(interface_)); + g_srv_services.emplace(interface_->GetPortName(), client_port); } /// Initialize ServiceManager diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 8df968b2e..b22caca07 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -22,18 +22,16 @@ static const int kMaxPortSize = 8; ///< Maximum size of a port name (8 character static const u32 DefaultMaxSessions = 10; ///< Arbitrary default number of maximum connections to an HLE port /// Interface to a CTROS service -class Interface : public Kernel::ClientPort { - // TODO(yuriks): An "Interface" being a Kernel::Object is mostly non-sense. Interface should be - // just something that encapsulates a session and acts as a helper to implement service - // processes. +class Interface { public: - std::string GetName() const override { + std::string GetName() const { return GetPortName(); } virtual void SetVersion(u32 raw_version) { version.raw = raw_version; } + virtual ~Interface() {} /** * Gets the maximum allowed number of sessions that can be connected to this port at the same time. @@ -42,8 +40,6 @@ public: */ virtual u32 GetMaxSessions() const { return DefaultMaxSessions; } - void AddWaitingSession(Kernel::SharedPtr<Kernel::ServerSession> server_session) override { } - typedef void (*Function)(Interface*); struct FunctionInfo { @@ -60,7 +56,7 @@ public: return "[UNKNOWN SERVICE PORT]"; } - ResultCode HandleSyncRequest() override; + ResultCode HandleSyncRequest(); protected: /** |