From c3d3b173d39b7c12fa9b3d5d34040e9377f2888e Mon Sep 17 00:00:00 2001 From: bunnei Date: Mon, 25 Nov 2019 18:28:48 -0500 Subject: kernel: Implement a more accurate IPC dispatch. --- src/core/hle/service/sm/controller.cpp | 5 +---- src/core/hle/service/sm/sm.cpp | 33 ++++++++++++++++++++------------- src/core/hle/service/sm/sm.h | 6 ++++-- 3 files changed, 25 insertions(+), 19 deletions(-) (limited to 'src/core/hle/service/sm') diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index af2fadcef..c45b285f8 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -30,10 +30,7 @@ void Controller::DuplicateSession(Kernel::HLERequestContext& ctx) { IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(RESULT_SUCCESS); - std::shared_ptr session{ctx.Session()->GetParent()->client}; - rb.PushMoveObjects(session); - - LOG_DEBUG(Service, "session={}", session->GetObjectId()); + rb.PushMoveObjects(ctx.Session()->GetParent()->Client()); } void Controller::DuplicateSessionEx(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index a0a7206bb..88909504d 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -36,10 +36,11 @@ static ResultCode ValidateServiceName(const std::string& name) { return RESULT_SUCCESS; } -void ServiceManager::InstallInterfaces(std::shared_ptr self) { +void ServiceManager::InstallInterfaces(std::shared_ptr self, + Kernel::KernelCore& kernel) { ASSERT(self->sm_interface.expired()); - auto sm = std::make_shared(self); + auto sm = std::make_shared(self, kernel); sm->InstallAsNamedPort(); self->sm_interface = sm; self->controller_interface = std::make_unique(); @@ -114,8 +115,6 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { std::string name(name_buf.begin(), end); - // TODO(yuriks): Permission checks go here - auto client_port = service_manager->GetServicePort(name); if (client_port.Failed()) { IPC::ResponseBuilder rb{ctx, 2}; @@ -127,14 +126,22 @@ void SM::GetService(Kernel::HLERequestContext& ctx) { return; } - auto session = client_port.Unwrap()->Connect(); - ASSERT(session.Succeeded()); - if (session.Succeeded()) { - LOG_DEBUG(Service_SM, "called service={} -> session={}", name, (*session)->GetObjectId()); - IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; - rb.Push(session.Code()); - rb.PushMoveObjects(std::move(session).Unwrap()); + auto [client, server] = Kernel::Session::Create(kernel, name); + + const auto& server_port = client_port.Unwrap()->GetServerPort(); + if (server_port->GetHLEHandler()) { + server_port->GetHLEHandler()->ClientConnected(server); + } else { + server_port->AppendPendingSession(server); } + + // Wake the threads waiting on the ServerPort + server_port->WakeupAllWaitingThreads(); + + LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId()); + IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; + rb.Push(RESULT_SUCCESS); + rb.PushMoveObjects(std::move(client)); } void SM::RegisterService(Kernel::HLERequestContext& ctx) { @@ -178,8 +185,8 @@ void SM::UnregisterService(Kernel::HLERequestContext& ctx) { rb.Push(service_manager->UnregisterService(name)); } -SM::SM(std::shared_ptr service_manager) - : ServiceFramework("sm:", 4), service_manager(std::move(service_manager)) { +SM::SM(std::shared_ptr service_manager, Kernel::KernelCore& kernel) + : ServiceFramework{"sm:", 4}, service_manager{std::move(service_manager)}, kernel{kernel} { static const FunctionInfo functions[] = { {0x00000000, &SM::Initialize, "Initialize"}, {0x00000001, &SM::GetService, "GetService"}, diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 3de22268b..b06d2f103 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -18,6 +18,7 @@ namespace Kernel { class ClientPort; class ClientSession; +class KernelCore; class ServerPort; class SessionRequestHandler; } // namespace Kernel @@ -29,7 +30,7 @@ class Controller; /// Interface to "sm:" service class SM final : public ServiceFramework { public: - explicit SM(std::shared_ptr service_manager); + explicit SM(std::shared_ptr service_manager, Kernel::KernelCore& kernel); ~SM() override; private: @@ -39,11 +40,12 @@ private: void UnregisterService(Kernel::HLERequestContext& ctx); std::shared_ptr service_manager; + Kernel::KernelCore& kernel; }; class ServiceManager { public: - static void InstallInterfaces(std::shared_ptr self); + static void InstallInterfaces(std::shared_ptr self, Kernel::KernelCore& kernel); ServiceManager(); ~ServiceManager(); -- cgit v1.2.3