service: use interface factory in server manager
This commit is contained in:
parent
c1924951ad
commit
34e4012998
@ -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
|
||||||
|
@ -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,9 +121,19 @@ Result ServerManager::RegisterNamedService(const std::string& service_name,
|
|||||||
R_SUCCEED();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ServerManager::ManageNamedPort(const std::string& service_name,
|
Result ServerManager::RegisterNamedService(const std::string& service_name,
|
||||||
std::shared_ptr<SessionRequestHandler>&& handler,
|
std::shared_ptr<SessionRequestHandler>&& handler,
|
||||||
u32 max_sessions) {
|
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,
|
||||||
|
SessionRequestHandlerFactory&& handler_factory,
|
||||||
|
u32 max_sessions) {
|
||||||
ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
|
ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
|
||||||
|
|
||||||
// Create a new port.
|
// Create a new port.
|
||||||
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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{};
|
||||||
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user