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.
This commit is contained in:
Subv 2016-06-18 13:39:26 -05:00
parent c19afd2118
commit c5e7e0fa26
6 changed files with 21 additions and 26 deletions

View file

@ -14,7 +14,7 @@ namespace Kernel {
ClientPort::ClientPort() {} ClientPort::ClientPort() {}
ClientPort::~ClientPort() {} ClientPort::~ClientPort() {}
Kernel::SharedPtr<ClientPort> ClientPort::CreateForHLE(u32 max_sessions, std::unique_ptr<Service::Interface> hle_interface) { Kernel::SharedPtr<ClientPort> ClientPort::CreateForHLE(u32 max_sessions, std::shared_ptr<Service::Interface> hle_interface) {
SharedPtr<ClientPort> client_port(new ClientPort); SharedPtr<ClientPort> client_port(new ClientPort);
client_port->max_sessions = max_sessions; client_port->max_sessions = max_sessions;
client_port->active_sessions = 0; client_port->active_sessions = 0;
@ -34,12 +34,4 @@ void ClientPort::AddWaitingSession(SharedPtr<ServerSession> server_session) {
server_port->WakeupAllWaitingThreads(); 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 } // namespace

View file

@ -28,19 +28,13 @@ public:
* @param hle_interface Interface object that implements the commands of the service. * @param hle_interface Interface object that implements the commands of the service.
* @returns ClientPort for the given HLE interface. * @returns ClientPort for the given HLE interface.
*/ */
static Kernel::SharedPtr<ClientPort> CreateForHLE(u32 max_sessions, std::unique_ptr<Service::Interface> hle_interface); static Kernel::SharedPtr<ClientPort> CreateForHLE(u32 max_sessions, std::shared_ptr<Service::Interface> hle_interface);
/** /**
* Adds the specified server session to the queue of pending sessions of the associated ServerPort * 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 * @param server_session Server session to add to the queue
*/ */
virtual void AddWaitingSession(SharedPtr<ServerSession> server_session); void AddWaitingSession(SharedPtr<ServerSession> server_session);
/**
* Handle a sync request from the emulated application.
* @returns ResultCode from the operation.
*/
ResultCode HandleSyncRequest();
std::string GetTypeName() const override { return "ClientPort"; } std::string GetTypeName() const override { return "ClientPort"; }
std::string GetName() const override { return name; } std::string GetName() const override { return name; }
@ -54,7 +48,7 @@ public:
u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have u32 max_sessions; ///< Maximum number of simultaneous sessions the port can have
u32 active_sessions; ///< Number of currently open sessions to this port u32 active_sessions; ///< Number of currently open sessions to this port
std::string name; ///< Name of client port (optional) std::string name; ///< Name of client port (optional)
std::unique_ptr<Service::Interface> hle_interface = nullptr; ///< HLE implementation of this port's request handler std::shared_ptr<Service::Interface> hle_interface = nullptr; ///< HLE implementation of this port's request handler
private: private:
ClientPort(); ClientPort();

View file

@ -8,6 +8,7 @@
#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/client_session.h"
#include "core/hle/kernel/server_session.h" #include "core/hle/kernel/server_session.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
#include "core/hle/service/service.h"
namespace Kernel { namespace Kernel {
@ -20,6 +21,7 @@ ResultVal<SharedPtr<ClientSession>> ClientSession::Create(SharedPtr<ServerSessio
client_session->name = std::move(name); client_session->name = std::move(name);
client_session->server_session = server_session; client_session->server_session = server_session;
client_session->client_port = client_port; client_session->client_port = client_port;
client_session->hle_helper = client_port->hle_interface;
return MakeResult<SharedPtr<ClientSession>>(std::move(client_session)); return MakeResult<SharedPtr<ClientSession>>(std::move(client_session));
} }
@ -31,10 +33,9 @@ ResultCode ClientSession::HandleSyncRequest() {
if (result.IsError()) if (result.IsError())
return result; return result;
// Tell the client port to handle the request in case it's an HLE service. // If this ClientSession has an associated HLE helper, forward the request to it.
// The client port can be nullptr for port-less sessions (Like for example File and Directory sessions). if (hle_helper != nullptr)
if (client_port != nullptr) result = hle_helper->HandleSyncRequest(server_session);
result = client_port->HandleSyncRequest();
return result; return result;
} }

View file

@ -5,11 +5,16 @@
#pragma once #pragma once
#include <string> #include <string>
#include <memory>
#include "common/common_types.h" #include "common/common_types.h"
#include "core/hle/kernel/kernel.h" #include "core/hle/kernel/kernel.h"
namespace Service {
class Interface;
}
namespace Kernel { namespace Kernel {
class ClientPort; class ClientPort;
@ -41,6 +46,7 @@ public:
std::string name; ///< Name of client port (optional) std::string name; ///< Name of client port (optional)
SharedPtr<ServerSession> server_session; ///< The server session associated with this client session. SharedPtr<ServerSession> server_session; ///< The server session associated with this client session.
SharedPtr<ClientPort> client_port; ///< The client port which this session is connected to. SharedPtr<ClientPort> client_port; ///< The client port which this session is connected to.
std::shared_ptr<Service::Interface> hle_helper = nullptr; ///< HLE implementation of this port's request handler
private: private:
ClientSession(); ClientSession();

View file

@ -61,7 +61,9 @@ static std::string MakeFunctionString(const char* name, const char* port_name,
return function_string; return function_string;
} }
ResultCode Interface::HandleSyncRequest() { ResultCode Interface::HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> 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(); u32* cmd_buff = Kernel::GetCommandBuffer();
auto itr = m_functions.find(cmd_buff[0]); auto itr = m_functions.find(cmd_buff[0]);
@ -97,12 +99,12 @@ void Interface::Register(const FunctionInfo* functions, size_t n) {
// Module interface // Module interface
static void AddNamedPort(Interface* interface_) { static void AddNamedPort(Interface* interface_) {
auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::unique_ptr<Interface>(interface_)); auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::shared_ptr<Interface>(interface_));
g_kernel_named_ports.emplace(interface_->GetPortName(), client_port); g_kernel_named_ports.emplace(interface_->GetPortName(), client_port);
} }
void AddService(Interface* interface_) { void AddService(Interface* interface_) {
auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::unique_ptr<Interface>(interface_)); auto client_port = Kernel::ClientPort::CreateForHLE(interface_->GetMaxSessions(), std::shared_ptr<Interface>(interface_));
g_srv_services.emplace(interface_->GetPortName(), client_port); g_srv_services.emplace(interface_->GetPortName(), client_port);
} }

View file

@ -56,7 +56,7 @@ public:
return "[UNKNOWN SERVICE PORT]"; return "[UNKNOWN SERVICE PORT]";
} }
ResultCode HandleSyncRequest(); ResultCode HandleSyncRequest(Kernel::SharedPtr<Kernel::ServerSession> server_session);
protected: protected:
/** /**