diff options
Diffstat (limited to 'src/core/hle/service/sm/sm.cpp')
-rw-r--r-- | src/core/hle/service/sm/sm.cpp | 43 |
1 files changed, 25 insertions, 18 deletions
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 246c94623..84720094f 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -23,7 +23,13 @@ constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6); constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} -ServiceManager::~ServiceManager() = default; + +ServiceManager::~ServiceManager() { + for (auto& [name, port] : service_ports) { + port->GetClientPort().Close(); + port->GetServerPort().Close(); + } +} void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { controller_interface->InvokeRequest(context); @@ -43,6 +49,10 @@ Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core return self.sm_interface->CreatePort(); } +void ServiceManager::SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port) { + self.sm_interface->AcceptSession(server_port); +} + Result ServiceManager::RegisterService(std::string name, u32 max_sessions, Kernel::SessionRequestHandlerPtr handler) { @@ -53,7 +63,11 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions, return ERR_ALREADY_REGISTERED; } - registered_services.emplace(std::move(name), handler); + auto* port = Kernel::KPort::Create(kernel); + port->Initialize(ServerSessionCountMax, false, name); + + service_ports.emplace(name, port); + registered_services.emplace(name, handler); return ResultSuccess; } @@ -68,25 +82,20 @@ Result ServiceManager::UnregisterService(const std::string& name) { } registered_services.erase(iter); + service_ports.erase(name); + return ResultSuccess; } ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { CASCADE_CODE(ValidateServiceName(name)); - auto it = registered_services.find(name); - if (it == registered_services.end()) { + auto it = service_ports.find(name); + if (it == service_ports.end()) { LOG_ERROR(Service_SM, "Server is not registered! service={}", name); return ERR_SERVICE_NOT_REGISTERED; } - auto* port = Kernel::KPort::Create(kernel); - SCOPE_EXIT({ port->Close(); }); - - port->Initialize(ServerSessionCountMax, false, name); - auto handler = it->second; - port->GetServerPort().SetSessionHandler(std::move(handler)); - - return port; + return it->second; } /** @@ -145,22 +154,20 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& // Find the named port. auto port_result = service_manager.GetServicePort(name); - if (port_result.Failed()) { + auto service = service_manager.GetService<Kernel::SessionRequestHandler>(name); + if (port_result.Failed() || !service) { LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); return port_result.Code(); } auto& port = port_result.Unwrap(); - SCOPE_EXIT({ port->GetClientPort().Close(); }); - - kernel.RegisterServerObject(&port->GetServerPort()); // Create a new session. Kernel::KClientSession* session{}; - if (const auto result = port->GetClientPort().CreateSession(std::addressof(session)); - result.IsError()) { + if (const auto result = port->GetClientPort().CreateSession(&session); result.IsError()) { LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); return result; } + service->AcceptSession(&port->GetServerPort()); LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); |