service: use interface factory in server manager

This commit is contained in:
Liam 2023-12-09 11:22:42 -05:00
parent c1924951ad
commit 34e4012998
5 changed files with 37 additions and 23 deletions

View file

@ -75,6 +75,7 @@ protected:
using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>;
using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>; using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
using SessionRequestHandlerFactory = std::function<SessionRequestHandlerPtr()>;
/** /**
* Manages the underlying HLE requests for a session, and whether (or not) the session should be * Manages the underlying HLE requests for a session, and whether (or not) the session should be

View file

@ -93,13 +93,13 @@ Result ServerManager::RegisterSession(Kernel::KServerSession* session,
} }
Result ServerManager::RegisterNamedService(const std::string& service_name, Result ServerManager::RegisterNamedService(const std::string& service_name,
std::shared_ptr<SessionRequestHandler>&& handler, SessionRequestHandlerFactory&& handler_factory,
u32 max_sessions) { u32 max_sessions) {
ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
// Add the new server to sm:. // Add the new server to sm:.
ASSERT(R_SUCCEEDED( ASSERT(R_SUCCEEDED(
m_system.ServiceManager().RegisterService(service_name, max_sessions, handler))); m_system.ServiceManager().RegisterService(service_name, max_sessions, handler_factory)));
// Get the registered port. // Get the registered port.
Kernel::KPort* port{}; Kernel::KPort* port{};
@ -112,7 +112,7 @@ Result ServerManager::RegisterNamedService(const std::string& service_name,
// Begin tracking the server port. // Begin tracking the server port.
{ {
std::scoped_lock ll{m_list_mutex}; std::scoped_lock ll{m_list_mutex};
m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler)); m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler_factory));
} }
// Signal the wakeup event. // Signal the wakeup event.
@ -121,8 +121,18 @@ Result ServerManager::RegisterNamedService(const std::string& service_name,
R_SUCCEED(); R_SUCCEED();
} }
Result ServerManager::RegisterNamedService(const std::string& service_name,
std::shared_ptr<SessionRequestHandler>&& handler,
u32 max_sessions) {
// Make the factory.
const auto HandlerFactory = [handler]() { return handler; };
// Register the service with the new factory.
R_RETURN(this->RegisterNamedService(service_name, std::move(HandlerFactory), max_sessions));
}
Result ServerManager::ManageNamedPort(const std::string& service_name, Result ServerManager::ManageNamedPort(const std::string& service_name,
std::shared_ptr<SessionRequestHandler>&& handler, SessionRequestHandlerFactory&& handler_factory,
u32 max_sessions) { u32 max_sessions) {
ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
@ -149,7 +159,7 @@ Result ServerManager::ManageNamedPort(const std::string& service_name,
// Begin tracking the server port. // Begin tracking the server port.
{ {
std::scoped_lock ll{m_list_mutex}; std::scoped_lock ll{m_list_mutex};
m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler)); m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler_factory));
} }
// We succeeded. // We succeeded.
@ -269,13 +279,13 @@ Result ServerManager::WaitAndProcessImpl() {
case HandleType::Port: { case HandleType::Port: {
// Port signaled. // Port signaled.
auto* port = wait_obj->DynamicCast<Kernel::KServerPort*>(); auto* port = wait_obj->DynamicCast<Kernel::KServerPort*>();
std::shared_ptr<SessionRequestHandler> handler; SessionRequestHandlerFactory handler_factory;
// Remove from tracking. // Remove from tracking.
{ {
std::scoped_lock ll{m_list_mutex}; std::scoped_lock ll{m_list_mutex};
ASSERT(m_ports.contains(port)); ASSERT(m_ports.contains(port));
m_ports.at(port).swap(handler); m_ports.at(port).swap(handler_factory);
m_ports.erase(port); m_ports.erase(port);
} }
@ -283,7 +293,7 @@ Result ServerManager::WaitAndProcessImpl() {
sl.unlock(); sl.unlock();
// Finish. // Finish.
R_RETURN(this->OnPortEvent(port, std::move(handler))); R_RETURN(this->OnPortEvent(port, std::move(handler_factory)));
} }
case HandleType::Session: { case HandleType::Session: {
// Session signaled. // Session signaled.
@ -333,19 +343,19 @@ Result ServerManager::WaitAndProcessImpl() {
} }
Result ServerManager::OnPortEvent(Kernel::KServerPort* port, Result ServerManager::OnPortEvent(Kernel::KServerPort* port,
std::shared_ptr<SessionRequestHandler>&& handler) { SessionRequestHandlerFactory&& handler_factory) {
// Accept a new server session. // Accept a new server session.
Kernel::KServerSession* session = port->AcceptSession(); Kernel::KServerSession* session = port->AcceptSession();
ASSERT(session != nullptr); ASSERT(session != nullptr);
// Create the session manager and install the handler. // Create the session manager and install the handler.
auto manager = std::make_shared<SessionRequestManager>(m_system.Kernel(), *this); auto manager = std::make_shared<SessionRequestManager>(m_system.Kernel(), *this);
manager->SetSessionHandler(std::shared_ptr(handler)); manager->SetSessionHandler(handler_factory());
// Track the server session. // Track the server session.
{ {
std::scoped_lock ll{m_list_mutex}; std::scoped_lock ll{m_list_mutex};
m_ports.emplace(port, std::move(handler)); m_ports.emplace(port, std::move(handler_factory));
m_sessions.emplace(session, std::move(manager)); m_sessions.emplace(session, std::move(manager));
} }

View file

@ -13,6 +13,7 @@
#include "common/polyfill_thread.h" #include "common/polyfill_thread.h"
#include "common/thread.h" #include "common/thread.h"
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/hle_ipc.h"
#include "core/hle/service/mutex.h" #include "core/hle/service/mutex.h"
namespace Core { namespace Core {
@ -28,10 +29,6 @@ class KSynchronizationObject;
namespace Service { namespace Service {
class HLERequestContext;
class SessionRequestHandler;
class SessionRequestManager;
class ServerManager { class ServerManager {
public: public:
explicit ServerManager(Core::System& system); explicit ServerManager(Core::System& system);
@ -39,11 +36,14 @@ public:
Result RegisterSession(Kernel::KServerSession* session, Result RegisterSession(Kernel::KServerSession* session,
std::shared_ptr<SessionRequestManager> manager); std::shared_ptr<SessionRequestManager> manager);
Result RegisterNamedService(const std::string& service_name,
SessionRequestHandlerFactory&& handler_factory,
u32 max_sessions = 64);
Result RegisterNamedService(const std::string& service_name, Result RegisterNamedService(const std::string& service_name,
std::shared_ptr<SessionRequestHandler>&& handler, std::shared_ptr<SessionRequestHandler>&& handler,
u32 max_sessions = 64); u32 max_sessions = 64);
Result ManageNamedPort(const std::string& service_name, Result ManageNamedPort(const std::string& service_name,
std::shared_ptr<SessionRequestHandler>&& handler, u32 max_sessions = 64); SessionRequestHandlerFactory&& handler_factory, u32 max_sessions = 64);
Result ManageDeferral(Kernel::KEvent** out_event); Result ManageDeferral(Kernel::KEvent** out_event);
Result LoopProcess(); Result LoopProcess();
@ -56,7 +56,7 @@ private:
Result LoopProcessImpl(); Result LoopProcessImpl();
Result WaitAndProcessImpl(); Result WaitAndProcessImpl();
Result OnPortEvent(Kernel::KServerPort* port, std::shared_ptr<SessionRequestHandler>&& handler); Result OnPortEvent(Kernel::KServerPort* port, SessionRequestHandlerFactory&& handler_factory);
Result OnSessionEvent(Kernel::KServerSession* session, Result OnSessionEvent(Kernel::KServerSession* session,
std::shared_ptr<SessionRequestManager>&& manager); std::shared_ptr<SessionRequestManager>&& manager);
Result OnDeferralEvent(std::list<RequestState>&& deferrals); Result OnDeferralEvent(std::list<RequestState>&& deferrals);
@ -68,7 +68,7 @@ private:
std::mutex m_list_mutex; std::mutex m_list_mutex;
// Guest state tracking // Guest state tracking
std::map<Kernel::KServerPort*, std::shared_ptr<SessionRequestHandler>> m_ports{}; std::map<Kernel::KServerPort*, SessionRequestHandlerFactory> m_ports{};
std::map<Kernel::KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{}; std::map<Kernel::KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{};
Kernel::KEvent* m_event{}; Kernel::KEvent* m_event{};
Kernel::KEvent* m_deferral_event{}; Kernel::KEvent* m_deferral_event{};

View file

@ -51,7 +51,7 @@ static Result ValidateServiceName(const std::string& name) {
} }
Result ServiceManager::RegisterService(std::string name, u32 max_sessions, Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
SessionRequestHandlerPtr handler) { SessionRequestHandlerFactory handler) {
R_TRY(ValidateServiceName(name)); R_TRY(ValidateServiceName(name));
std::scoped_lock lk{lock}; std::scoped_lock lk{lock};
@ -264,7 +264,9 @@ void LoopProcess(Core::System& system) {
server_manager->ManageDeferral(&deferral_event); server_manager->ManageDeferral(&deferral_event);
service_manager.SetDeferralEvent(deferral_event); service_manager.SetDeferralEvent(deferral_event);
server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system)); auto sm_service = std::make_shared<SM>(system.ServiceManager(), system);
server_manager->ManageNamedPort("sm:", [sm_service] { return sm_service; });
ServerManager::RunServer(std::move(server_manager)); ServerManager::RunServer(std::move(server_manager));
} }

View file

@ -53,7 +53,8 @@ public:
explicit ServiceManager(Kernel::KernelCore& kernel_); explicit ServiceManager(Kernel::KernelCore& kernel_);
~ServiceManager(); ~ServiceManager();
Result RegisterService(std::string name, u32 max_sessions, SessionRequestHandlerPtr handler); Result RegisterService(std::string name, u32 max_sessions,
SessionRequestHandlerFactory handler_factory);
Result UnregisterService(const std::string& name); Result UnregisterService(const std::string& name);
Result GetServicePort(Kernel::KPort** out_port, const std::string& name); Result GetServicePort(Kernel::KPort** out_port, const std::string& name);
@ -64,7 +65,7 @@ public:
LOG_DEBUG(Service, "Can't find service: {}", service_name); LOG_DEBUG(Service, "Can't find service: {}", service_name);
return nullptr; return nullptr;
} }
return std::static_pointer_cast<T>(service->second); return std::static_pointer_cast<T>(service->second());
} }
void InvokeControlRequest(HLERequestContext& context); void InvokeControlRequest(HLERequestContext& context);
@ -79,7 +80,7 @@ private:
/// Map of registered services, retrieved using GetServicePort. /// Map of registered services, retrieved using GetServicePort.
std::mutex lock; std::mutex lock;
std::unordered_map<std::string, SessionRequestHandlerPtr> registered_services; std::unordered_map<std::string, SessionRequestHandlerFactory> registered_services;
std::unordered_map<std::string, Kernel::KPort*> service_ports; std::unordered_map<std::string, Kernel::KPort*> service_ports;
/// Kernel context /// Kernel context