From 77b74f5d95626422f59b508cd2b355135ed256ca Mon Sep 17 00:00:00 2001 From: Liam Date: Sun, 30 Oct 2022 22:22:14 -0400 Subject: sm:: avoid excessive port recreation --- src/core/hle/service/service.cpp | 10 ++++++---- src/core/hle/service/sm/sm.cpp | 31 +++++++++++++++++-------------- src/core/hle/service/sm/sm.h | 1 + 3 files changed, 24 insertions(+), 18 deletions(-) diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 6a64c6005..5ab41c0c4 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -119,12 +119,14 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) Kernel::KClientPort& ServiceFrameworkBase::CreatePort() { const auto guard = LockService(); - ASSERT(!service_registered); + if (named_port == nullptr) { + ASSERT(!service_registered); - named_port = Kernel::KPort::Create(kernel); - named_port->Initialize(max_sessions, false, service_name); + named_port = Kernel::KPort::Create(kernel); + named_port->Initialize(max_sessions, false, service_name); - service_registered = true; + service_registered = true; + } return named_port->GetClientPort(); } diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index c1f535d71..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); @@ -57,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; } @@ -72,23 +82,20 @@ Result ServiceManager::UnregisterService(const std::string& name) { } registered_services.erase(iter); + service_ports.erase(name); + return ResultSuccess; } ResultVal 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); - - port->Initialize(ServerSessionCountMax, false, name); - auto handler = it->second; - - return port; + return it->second; } /** @@ -153,10 +160,6 @@ ResultVal SM::GetServiceImpl(Kernel::HLERequestContext& return port_result.Code(); } auto& port = port_result.Unwrap(); - SCOPE_EXIT({ - port->GetClientPort().Close(); - port->GetServerPort().Close(); - }); // Create a new session. Kernel::KClientSession* session{}; diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index cfe370652..02a5dde9e 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -79,6 +79,7 @@ private: /// Map of registered services, retrieved using GetServicePort. std::unordered_map registered_services; + std::unordered_map service_ports; /// Kernel context Kernel::KernelCore& kernel; -- cgit v1.2.3