Răsfoiți Sursa

service: use interface factory in server manager

Liam 2 ani în urmă
părinte
comite
34e4012998

+ 1 - 0
src/core/hle/service/hle_ipc.h

@@ -75,6 +75,7 @@ protected:
 
 using SessionRequestHandlerWeakPtr = std::weak_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

+ 21 - 11
src/core/hle/service/server_manager.cpp

@@ -93,13 +93,13 @@ Result ServerManager::RegisterSession(Kernel::KServerSession* session,
 }
 
 Result ServerManager::RegisterNamedService(const std::string& service_name,
-                                           std::shared_ptr<SessionRequestHandler>&& handler,
+                                           SessionRequestHandlerFactory&& handler_factory,
                                            u32 max_sessions) {
     ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
 
     // Add the new server to sm:.
     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.
     Kernel::KPort* port{};
@@ -112,7 +112,7 @@ Result ServerManager::RegisterNamedService(const std::string& service_name,
     // Begin tracking the server port.
     {
         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.
@@ -121,8 +121,18 @@ Result ServerManager::RegisterNamedService(const std::string& service_name,
     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,
-                                      std::shared_ptr<SessionRequestHandler>&& handler,
+                                      SessionRequestHandlerFactory&& handler_factory,
                                       u32 max_sessions) {
     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.
     {
         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.
@@ -269,13 +279,13 @@ Result ServerManager::WaitAndProcessImpl() {
         case HandleType::Port: {
             // Port signaled.
             auto* port = wait_obj->DynamicCast<Kernel::KServerPort*>();
-            std::shared_ptr<SessionRequestHandler> handler;
+            SessionRequestHandlerFactory handler_factory;
 
             // Remove from tracking.
             {
                 std::scoped_lock ll{m_list_mutex};
                 ASSERT(m_ports.contains(port));
-                m_ports.at(port).swap(handler);
+                m_ports.at(port).swap(handler_factory);
                 m_ports.erase(port);
             }
 
@@ -283,7 +293,7 @@ Result ServerManager::WaitAndProcessImpl() {
             sl.unlock();
 
             // Finish.
-            R_RETURN(this->OnPortEvent(port, std::move(handler)));
+            R_RETURN(this->OnPortEvent(port, std::move(handler_factory)));
         }
         case HandleType::Session: {
             // Session signaled.
@@ -333,19 +343,19 @@ Result ServerManager::WaitAndProcessImpl() {
 }
 
 Result ServerManager::OnPortEvent(Kernel::KServerPort* port,
-                                  std::shared_ptr<SessionRequestHandler>&& handler) {
+                                  SessionRequestHandlerFactory&& handler_factory) {
     // Accept a new server session.
     Kernel::KServerSession* session = port->AcceptSession();
     ASSERT(session != nullptr);
 
     // Create the session manager and install the handler.
     auto manager = std::make_shared<SessionRequestManager>(m_system.Kernel(), *this);
-    manager->SetSessionHandler(std::shared_ptr(handler));
+    manager->SetSessionHandler(handler_factory());
 
     // Track the server session.
     {
         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));
     }
 

+ 7 - 7
src/core/hle/service/server_manager.h

@@ -13,6 +13,7 @@
 #include "common/polyfill_thread.h"
 #include "common/thread.h"
 #include "core/hle/result.h"
+#include "core/hle/service/hle_ipc.h"
 #include "core/hle/service/mutex.h"
 
 namespace Core {
@@ -28,10 +29,6 @@ class KSynchronizationObject;
 
 namespace Service {
 
-class HLERequestContext;
-class SessionRequestHandler;
-class SessionRequestManager;
-
 class ServerManager {
 public:
     explicit ServerManager(Core::System& system);
@@ -39,11 +36,14 @@ public:
 
     Result RegisterSession(Kernel::KServerSession* session,
                            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,
                                 std::shared_ptr<SessionRequestHandler>&& handler,
                                 u32 max_sessions = 64);
     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 LoopProcess();
@@ -56,7 +56,7 @@ private:
 
     Result LoopProcessImpl();
     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,
                           std::shared_ptr<SessionRequestManager>&& manager);
     Result OnDeferralEvent(std::list<RequestState>&& deferrals);
@@ -68,7 +68,7 @@ private:
     std::mutex m_list_mutex;
 
     // 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{};
     Kernel::KEvent* m_event{};
     Kernel::KEvent* m_deferral_event{};

+ 4 - 2
src/core/hle/service/sm/sm.cpp

@@ -51,7 +51,7 @@ static Result ValidateServiceName(const std::string& name) {
 }
 
 Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
-                                       SessionRequestHandlerPtr handler) {
+                                       SessionRequestHandlerFactory handler) {
     R_TRY(ValidateServiceName(name));
 
     std::scoped_lock lk{lock};
@@ -264,7 +264,9 @@ void LoopProcess(Core::System& system) {
     server_manager->ManageDeferral(&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));
 }
 

+ 4 - 3
src/core/hle/service/sm/sm.h

@@ -53,7 +53,8 @@ public:
     explicit ServiceManager(Kernel::KernelCore& kernel_);
     ~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 GetServicePort(Kernel::KPort** out_port, const std::string& name);
 
@@ -64,7 +65,7 @@ public:
             LOG_DEBUG(Service, "Can't find service: {}", service_name);
             return nullptr;
         }
-        return std::static_pointer_cast<T>(service->second);
+        return std::static_pointer_cast<T>(service->second());
     }
 
     void InvokeControlRequest(HLERequestContext& context);
@@ -79,7 +80,7 @@ private:
 
     /// Map of registered services, retrieved using GetServicePort.
     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;
 
     /// Kernel context