diff options
| -rw-r--r-- | src/core/hle/service/hle_ipc.h | 1 | ||||
| -rw-r--r-- | src/core/hle/service/server_manager.cpp | 32 | ||||
| -rw-r--r-- | src/core/hle/service/server_manager.h | 14 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.cpp | 6 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 7 |
5 files changed, 37 insertions, 23 deletions
diff --git a/src/core/hle/service/hle_ipc.h b/src/core/hle/service/hle_ipc.h index ad5259a5c..4436f4f83 100644 --- a/src/core/hle/service/hle_ipc.h +++ b/src/core/hle/service/hle_ipc.h | |||
| @@ -75,6 +75,7 @@ protected: | |||
| 75 | 75 | ||
| 76 | using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; | 76 | using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; |
| 77 | using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>; | 77 | using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>; |
| 78 | using SessionRequestHandlerFactory = std::function<SessionRequestHandlerPtr()>; | ||
| 78 | 79 | ||
| 79 | /** | 80 | /** |
| 80 | * Manages the underlying HLE requests for a session, and whether (or not) the session should be | 81 | * Manages the underlying HLE requests for a session, and whether (or not) the session should be |
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp index e2e399534..6808247a9 100644 --- a/src/core/hle/service/server_manager.cpp +++ b/src/core/hle/service/server_manager.cpp | |||
| @@ -93,13 +93,13 @@ Result ServerManager::RegisterSession(Kernel::KServerSession* session, | |||
| 93 | } | 93 | } |
| 94 | 94 | ||
| 95 | Result ServerManager::RegisterNamedService(const std::string& service_name, | 95 | Result ServerManager::RegisterNamedService(const std::string& service_name, |
| 96 | std::shared_ptr<SessionRequestHandler>&& handler, | 96 | SessionRequestHandlerFactory&& handler_factory, |
| 97 | u32 max_sessions) { | 97 | u32 max_sessions) { |
| 98 | ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); | 98 | ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); |
| 99 | 99 | ||
| 100 | // Add the new server to sm:. | 100 | // Add the new server to sm:. |
| 101 | ASSERT(R_SUCCEEDED( | 101 | ASSERT(R_SUCCEEDED( |
| 102 | m_system.ServiceManager().RegisterService(service_name, max_sessions, handler))); | 102 | m_system.ServiceManager().RegisterService(service_name, max_sessions, handler_factory))); |
| 103 | 103 | ||
| 104 | // Get the registered port. | 104 | // Get the registered port. |
| 105 | Kernel::KPort* port{}; | 105 | Kernel::KPort* port{}; |
| @@ -112,7 +112,7 @@ Result ServerManager::RegisterNamedService(const std::string& service_name, | |||
| 112 | // Begin tracking the server port. | 112 | // Begin tracking the server port. |
| 113 | { | 113 | { |
| 114 | std::scoped_lock ll{m_list_mutex}; | 114 | std::scoped_lock ll{m_list_mutex}; |
| 115 | m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler)); | 115 | m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler_factory)); |
| 116 | } | 116 | } |
| 117 | 117 | ||
| 118 | // Signal the wakeup event. | 118 | // Signal the wakeup event. |
| @@ -121,8 +121,18 @@ Result ServerManager::RegisterNamedService(const std::string& service_name, | |||
| 121 | R_SUCCEED(); | 121 | R_SUCCEED(); |
| 122 | } | 122 | } |
| 123 | 123 | ||
| 124 | Result ServerManager::RegisterNamedService(const std::string& service_name, | ||
| 125 | std::shared_ptr<SessionRequestHandler>&& handler, | ||
| 126 | u32 max_sessions) { | ||
| 127 | // Make the factory. | ||
| 128 | const auto HandlerFactory = [handler]() { return handler; }; | ||
| 129 | |||
| 130 | // Register the service with the new factory. | ||
| 131 | R_RETURN(this->RegisterNamedService(service_name, std::move(HandlerFactory), max_sessions)); | ||
| 132 | } | ||
| 133 | |||
| 124 | Result ServerManager::ManageNamedPort(const std::string& service_name, | 134 | Result ServerManager::ManageNamedPort(const std::string& service_name, |
| 125 | std::shared_ptr<SessionRequestHandler>&& handler, | 135 | SessionRequestHandlerFactory&& handler_factory, |
| 126 | u32 max_sessions) { | 136 | u32 max_sessions) { |
| 127 | ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); | 137 | ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); |
| 128 | 138 | ||
| @@ -149,7 +159,7 @@ Result ServerManager::ManageNamedPort(const std::string& service_name, | |||
| 149 | // Begin tracking the server port. | 159 | // Begin tracking the server port. |
| 150 | { | 160 | { |
| 151 | std::scoped_lock ll{m_list_mutex}; | 161 | std::scoped_lock ll{m_list_mutex}; |
| 152 | m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler)); | 162 | m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler_factory)); |
| 153 | } | 163 | } |
| 154 | 164 | ||
| 155 | // We succeeded. | 165 | // We succeeded. |
| @@ -269,13 +279,13 @@ Result ServerManager::WaitAndProcessImpl() { | |||
| 269 | case HandleType::Port: { | 279 | case HandleType::Port: { |
| 270 | // Port signaled. | 280 | // Port signaled. |
| 271 | auto* port = wait_obj->DynamicCast<Kernel::KServerPort*>(); | 281 | auto* port = wait_obj->DynamicCast<Kernel::KServerPort*>(); |
| 272 | std::shared_ptr<SessionRequestHandler> handler; | 282 | SessionRequestHandlerFactory handler_factory; |
| 273 | 283 | ||
| 274 | // Remove from tracking. | 284 | // Remove from tracking. |
| 275 | { | 285 | { |
| 276 | std::scoped_lock ll{m_list_mutex}; | 286 | std::scoped_lock ll{m_list_mutex}; |
| 277 | ASSERT(m_ports.contains(port)); | 287 | ASSERT(m_ports.contains(port)); |
| 278 | m_ports.at(port).swap(handler); | 288 | m_ports.at(port).swap(handler_factory); |
| 279 | m_ports.erase(port); | 289 | m_ports.erase(port); |
| 280 | } | 290 | } |
| 281 | 291 | ||
| @@ -283,7 +293,7 @@ Result ServerManager::WaitAndProcessImpl() { | |||
| 283 | sl.unlock(); | 293 | sl.unlock(); |
| 284 | 294 | ||
| 285 | // Finish. | 295 | // Finish. |
| 286 | R_RETURN(this->OnPortEvent(port, std::move(handler))); | 296 | R_RETURN(this->OnPortEvent(port, std::move(handler_factory))); |
| 287 | } | 297 | } |
| 288 | case HandleType::Session: { | 298 | case HandleType::Session: { |
| 289 | // Session signaled. | 299 | // Session signaled. |
| @@ -333,19 +343,19 @@ Result ServerManager::WaitAndProcessImpl() { | |||
| 333 | } | 343 | } |
| 334 | 344 | ||
| 335 | Result ServerManager::OnPortEvent(Kernel::KServerPort* port, | 345 | Result ServerManager::OnPortEvent(Kernel::KServerPort* port, |
| 336 | std::shared_ptr<SessionRequestHandler>&& handler) { | 346 | SessionRequestHandlerFactory&& handler_factory) { |
| 337 | // Accept a new server session. | 347 | // Accept a new server session. |
| 338 | Kernel::KServerSession* session = port->AcceptSession(); | 348 | Kernel::KServerSession* session = port->AcceptSession(); |
| 339 | ASSERT(session != nullptr); | 349 | ASSERT(session != nullptr); |
| 340 | 350 | ||
| 341 | // Create the session manager and install the handler. | 351 | // Create the session manager and install the handler. |
| 342 | auto manager = std::make_shared<SessionRequestManager>(m_system.Kernel(), *this); | 352 | auto manager = std::make_shared<SessionRequestManager>(m_system.Kernel(), *this); |
| 343 | manager->SetSessionHandler(std::shared_ptr(handler)); | 353 | manager->SetSessionHandler(handler_factory()); |
| 344 | 354 | ||
| 345 | // Track the server session. | 355 | // Track the server session. |
| 346 | { | 356 | { |
| 347 | std::scoped_lock ll{m_list_mutex}; | 357 | std::scoped_lock ll{m_list_mutex}; |
| 348 | m_ports.emplace(port, std::move(handler)); | 358 | m_ports.emplace(port, std::move(handler_factory)); |
| 349 | m_sessions.emplace(session, std::move(manager)); | 359 | m_sessions.emplace(session, std::move(manager)); |
| 350 | } | 360 | } |
| 351 | 361 | ||
diff --git a/src/core/hle/service/server_manager.h b/src/core/hle/service/server_manager.h index 58b0a0832..c4bc07262 100644 --- a/src/core/hle/service/server_manager.h +++ b/src/core/hle/service/server_manager.h | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "common/polyfill_thread.h" | 13 | #include "common/polyfill_thread.h" |
| 14 | #include "common/thread.h" | 14 | #include "common/thread.h" |
| 15 | #include "core/hle/result.h" | 15 | #include "core/hle/result.h" |
| 16 | #include "core/hle/service/hle_ipc.h" | ||
| 16 | #include "core/hle/service/mutex.h" | 17 | #include "core/hle/service/mutex.h" |
| 17 | 18 | ||
| 18 | namespace Core { | 19 | namespace Core { |
| @@ -28,10 +29,6 @@ class KSynchronizationObject; | |||
| 28 | 29 | ||
| 29 | namespace Service { | 30 | namespace Service { |
| 30 | 31 | ||
| 31 | class HLERequestContext; | ||
| 32 | class SessionRequestHandler; | ||
| 33 | class SessionRequestManager; | ||
| 34 | |||
| 35 | class ServerManager { | 32 | class ServerManager { |
| 36 | public: | 33 | public: |
| 37 | explicit ServerManager(Core::System& system); | 34 | explicit ServerManager(Core::System& system); |
| @@ -40,10 +37,13 @@ public: | |||
| 40 | Result RegisterSession(Kernel::KServerSession* session, | 37 | Result RegisterSession(Kernel::KServerSession* session, |
| 41 | std::shared_ptr<SessionRequestManager> manager); | 38 | std::shared_ptr<SessionRequestManager> manager); |
| 42 | Result RegisterNamedService(const std::string& service_name, | 39 | Result RegisterNamedService(const std::string& service_name, |
| 40 | SessionRequestHandlerFactory&& handler_factory, | ||
| 41 | u32 max_sessions = 64); | ||
| 42 | Result RegisterNamedService(const std::string& service_name, | ||
| 43 | std::shared_ptr<SessionRequestHandler>&& handler, | 43 | std::shared_ptr<SessionRequestHandler>&& handler, |
| 44 | u32 max_sessions = 64); | 44 | u32 max_sessions = 64); |
| 45 | Result ManageNamedPort(const std::string& service_name, | 45 | Result ManageNamedPort(const std::string& service_name, |
| 46 | std::shared_ptr<SessionRequestHandler>&& handler, u32 max_sessions = 64); | 46 | SessionRequestHandlerFactory&& handler_factory, u32 max_sessions = 64); |
| 47 | Result ManageDeferral(Kernel::KEvent** out_event); | 47 | Result ManageDeferral(Kernel::KEvent** out_event); |
| 48 | 48 | ||
| 49 | Result LoopProcess(); | 49 | Result LoopProcess(); |
| @@ -56,7 +56,7 @@ private: | |||
| 56 | 56 | ||
| 57 | Result LoopProcessImpl(); | 57 | Result LoopProcessImpl(); |
| 58 | Result WaitAndProcessImpl(); | 58 | Result WaitAndProcessImpl(); |
| 59 | Result OnPortEvent(Kernel::KServerPort* port, std::shared_ptr<SessionRequestHandler>&& handler); | 59 | Result OnPortEvent(Kernel::KServerPort* port, SessionRequestHandlerFactory&& handler_factory); |
| 60 | Result OnSessionEvent(Kernel::KServerSession* session, | 60 | Result OnSessionEvent(Kernel::KServerSession* session, |
| 61 | std::shared_ptr<SessionRequestManager>&& manager); | 61 | std::shared_ptr<SessionRequestManager>&& manager); |
| 62 | Result OnDeferralEvent(std::list<RequestState>&& deferrals); | 62 | Result OnDeferralEvent(std::list<RequestState>&& deferrals); |
| @@ -68,7 +68,7 @@ private: | |||
| 68 | std::mutex m_list_mutex; | 68 | std::mutex m_list_mutex; |
| 69 | 69 | ||
| 70 | // Guest state tracking | 70 | // Guest state tracking |
| 71 | std::map<Kernel::KServerPort*, std::shared_ptr<SessionRequestHandler>> m_ports{}; | 71 | std::map<Kernel::KServerPort*, SessionRequestHandlerFactory> m_ports{}; |
| 72 | std::map<Kernel::KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{}; | 72 | std::map<Kernel::KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{}; |
| 73 | Kernel::KEvent* m_event{}; | 73 | Kernel::KEvent* m_event{}; |
| 74 | Kernel::KEvent* m_deferral_event{}; | 74 | Kernel::KEvent* m_deferral_event{}; |
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 9ab718e0a..53209537f 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -51,7 +51,7 @@ static Result ValidateServiceName(const std::string& name) { | |||
| 51 | } | 51 | } |
| 52 | 52 | ||
| 53 | Result ServiceManager::RegisterService(std::string name, u32 max_sessions, | 53 | Result ServiceManager::RegisterService(std::string name, u32 max_sessions, |
| 54 | SessionRequestHandlerPtr handler) { | 54 | SessionRequestHandlerFactory handler) { |
| 55 | R_TRY(ValidateServiceName(name)); | 55 | R_TRY(ValidateServiceName(name)); |
| 56 | 56 | ||
| 57 | std::scoped_lock lk{lock}; | 57 | std::scoped_lock lk{lock}; |
| @@ -264,7 +264,9 @@ void LoopProcess(Core::System& system) { | |||
| 264 | server_manager->ManageDeferral(&deferral_event); | 264 | server_manager->ManageDeferral(&deferral_event); |
| 265 | service_manager.SetDeferralEvent(deferral_event); | 265 | service_manager.SetDeferralEvent(deferral_event); |
| 266 | 266 | ||
| 267 | server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system)); | 267 | auto sm_service = std::make_shared<SM>(system.ServiceManager(), system); |
| 268 | server_manager->ManageNamedPort("sm:", [sm_service] { return sm_service; }); | ||
| 269 | |||
| 268 | ServerManager::RunServer(std::move(server_manager)); | 270 | ServerManager::RunServer(std::move(server_manager)); |
| 269 | } | 271 | } |
| 270 | 272 | ||
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 14bfaf8c2..cf102c339 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h | |||
| @@ -53,7 +53,8 @@ public: | |||
| 53 | explicit ServiceManager(Kernel::KernelCore& kernel_); | 53 | explicit ServiceManager(Kernel::KernelCore& kernel_); |
| 54 | ~ServiceManager(); | 54 | ~ServiceManager(); |
| 55 | 55 | ||
| 56 | Result RegisterService(std::string name, u32 max_sessions, SessionRequestHandlerPtr handler); | 56 | Result RegisterService(std::string name, u32 max_sessions, |
| 57 | SessionRequestHandlerFactory handler_factory); | ||
| 57 | Result UnregisterService(const std::string& name); | 58 | Result UnregisterService(const std::string& name); |
| 58 | Result GetServicePort(Kernel::KPort** out_port, const std::string& name); | 59 | Result GetServicePort(Kernel::KPort** out_port, const std::string& name); |
| 59 | 60 | ||
| @@ -64,7 +65,7 @@ public: | |||
| 64 | LOG_DEBUG(Service, "Can't find service: {}", service_name); | 65 | LOG_DEBUG(Service, "Can't find service: {}", service_name); |
| 65 | return nullptr; | 66 | return nullptr; |
| 66 | } | 67 | } |
| 67 | return std::static_pointer_cast<T>(service->second); | 68 | return std::static_pointer_cast<T>(service->second()); |
| 68 | } | 69 | } |
| 69 | 70 | ||
| 70 | void InvokeControlRequest(HLERequestContext& context); | 71 | void InvokeControlRequest(HLERequestContext& context); |
| @@ -79,7 +80,7 @@ private: | |||
| 79 | 80 | ||
| 80 | /// Map of registered services, retrieved using GetServicePort. | 81 | /// Map of registered services, retrieved using GetServicePort. |
| 81 | std::mutex lock; | 82 | std::mutex lock; |
| 82 | std::unordered_map<std::string, SessionRequestHandlerPtr> registered_services; | 83 | std::unordered_map<std::string, SessionRequestHandlerFactory> registered_services; |
| 83 | std::unordered_map<std::string, Kernel::KPort*> service_ports; | 84 | std::unordered_map<std::string, Kernel::KPort*> service_ports; |
| 84 | 85 | ||
| 85 | /// Kernel context | 86 | /// Kernel context |