sm:: avoid excessive port recreation

This commit is contained in:
Liam 2022-10-30 22:22:14 -04:00
parent 633411c20f
commit 77b74f5d95
3 changed files with 24 additions and 18 deletions

View file

@ -119,12 +119,14 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
Kernel::KClientPort& ServiceFrameworkBase::CreatePort() { Kernel::KClientPort& ServiceFrameworkBase::CreatePort() {
const auto guard = LockService(); const auto guard = LockService();
ASSERT(!service_registered); if (named_port == nullptr) {
ASSERT(!service_registered);
named_port = Kernel::KPort::Create(kernel); named_port = Kernel::KPort::Create(kernel);
named_port->Initialize(max_sessions, false, service_name); named_port->Initialize(max_sessions, false, service_name);
service_registered = true; service_registered = true;
}
return named_port->GetClientPort(); return named_port->GetClientPort();
} }

View file

@ -23,7 +23,13 @@ constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6);
constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7);
ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} 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) { void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) {
controller_interface->InvokeRequest(context); controller_interface->InvokeRequest(context);
@ -57,7 +63,11 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
return ERR_ALREADY_REGISTERED; 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; return ResultSuccess;
} }
@ -72,23 +82,20 @@ Result ServiceManager::UnregisterService(const std::string& name) {
} }
registered_services.erase(iter); registered_services.erase(iter);
service_ports.erase(name);
return ResultSuccess; return ResultSuccess;
} }
ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) {
CASCADE_CODE(ValidateServiceName(name)); CASCADE_CODE(ValidateServiceName(name));
auto it = registered_services.find(name); auto it = service_ports.find(name);
if (it == registered_services.end()) { if (it == service_ports.end()) {
LOG_ERROR(Service_SM, "Server is not registered! service={}", name); LOG_ERROR(Service_SM, "Server is not registered! service={}", name);
return ERR_SERVICE_NOT_REGISTERED; return ERR_SERVICE_NOT_REGISTERED;
} }
auto* port = Kernel::KPort::Create(kernel); return it->second;
port->Initialize(ServerSessionCountMax, false, name);
auto handler = it->second;
return port;
} }
/** /**
@ -153,10 +160,6 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
return port_result.Code(); return port_result.Code();
} }
auto& port = port_result.Unwrap(); auto& port = port_result.Unwrap();
SCOPE_EXIT({
port->GetClientPort().Close();
port->GetServerPort().Close();
});
// Create a new session. // Create a new session.
Kernel::KClientSession* session{}; Kernel::KClientSession* session{};

View file

@ -79,6 +79,7 @@ private:
/// Map of registered services, retrieved using GetServicePort. /// Map of registered services, retrieved using GetServicePort.
std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services; std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services;
std::unordered_map<std::string, Kernel::KPort*> service_ports;
/// Kernel context /// Kernel context
Kernel::KernelCore& kernel; Kernel::KernelCore& kernel;