hle: kernel: Implement named service ports using service interface factory.
- This allows us to create a new interface each time ConnectToNamedPort is called, removing the assumption that these are static.
This commit is contained in:
		| @@ -44,6 +44,7 @@ | ||||
| #include "core/hle/kernel/time_manager.h" | ||||
| #include "core/hle/lock.h" | ||||
| #include "core/hle/result.h" | ||||
| #include "core/hle/service/sm/sm.h" | ||||
| #include "core/memory.h" | ||||
|  | ||||
| MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); | ||||
| @@ -656,6 +657,7 @@ struct KernelCore::Impl { | ||||
|  | ||||
|     /// Map of named ports managed by the kernel, which can be retrieved using | ||||
|     /// the ConnectToPort SVC. | ||||
|     std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory; | ||||
|     NamedPortTable named_ports; | ||||
|  | ||||
|     std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; | ||||
| @@ -844,18 +846,17 @@ void KernelCore::PrepareReschedule(std::size_t id) { | ||||
|     // TODO: Reimplement, this | ||||
| } | ||||
|  | ||||
| void KernelCore::AddNamedPort(std::string name, KClientPort* port) { | ||||
|     port->Open(); | ||||
|     impl->named_ports.emplace(std::move(name), port); | ||||
| void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory) { | ||||
|     impl->service_interface_factory.emplace(std::move(name), factory); | ||||
| } | ||||
|  | ||||
| KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) { | ||||
|     return impl->named_ports.find(name); | ||||
| } | ||||
|  | ||||
| KernelCore::NamedPortTable::const_iterator KernelCore::FindNamedPort( | ||||
|     const std::string& name) const { | ||||
|     return impl->named_ports.find(name); | ||||
| KClientPort* KernelCore::CreateNamedServicePort(std::string name) { | ||||
|     auto search = impl->service_interface_factory.find(name); | ||||
|     if (search == impl->service_interface_factory.end()) { | ||||
|         UNIMPLEMENTED(); | ||||
|         return {}; | ||||
|     } | ||||
|     return &search->second(impl->system.ServiceManager(), impl->system); | ||||
| } | ||||
|  | ||||
| bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { | ||||
|   | ||||
| @@ -27,6 +27,10 @@ class CoreTiming; | ||||
| struct EventType; | ||||
| } // namespace Core::Timing | ||||
|  | ||||
| namespace Service::SM { | ||||
| class ServiceManager; | ||||
| } | ||||
|  | ||||
| namespace Kernel { | ||||
|  | ||||
| class KClientPort; | ||||
| @@ -51,6 +55,9 @@ class ServiceThread; | ||||
| class Synchronization; | ||||
| class TimeManager; | ||||
|  | ||||
| using ServiceInterfaceFactory = | ||||
|     std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>; | ||||
|  | ||||
| namespace Init { | ||||
| struct KSlabResourceCounts; | ||||
| } | ||||
| @@ -172,14 +179,11 @@ public: | ||||
|  | ||||
|     void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); | ||||
|  | ||||
|     /// Adds a port to the named port table | ||||
|     void AddNamedPort(std::string name, KClientPort* port); | ||||
|     /// Registers a named HLE service, passing a factory used to open a port to that service. | ||||
|     void RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory); | ||||
|  | ||||
|     /// Finds a port within the named port table with the given name. | ||||
|     NamedPortTable::iterator FindNamedPort(const std::string& name); | ||||
|  | ||||
|     /// Finds a port within the named port table with the given name. | ||||
|     NamedPortTable::const_iterator FindNamedPort(const std::string& name) const; | ||||
|     /// Opens a port to a service previously registered with RegisterNamedService. | ||||
|     KClientPort* CreateNamedServicePort(std::string name); | ||||
|  | ||||
|     /// Determines whether or not the given port is a valid named port. | ||||
|     bool IsValidNamedPort(NamedPortTable::const_iterator port) const; | ||||
|   | ||||
| @@ -111,7 +111,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) | ||||
|     port_installed = true; | ||||
| } | ||||
|  | ||||
| void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) { | ||||
| Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) { | ||||
|     const auto guard = LockService(); | ||||
|  | ||||
|     ASSERT(!port_installed); | ||||
| @@ -119,9 +119,10 @@ void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) { | ||||
|     auto* port = Kernel::KPort::Create(kernel); | ||||
|     port->Initialize(max_sessions, false, service_name); | ||||
|     port->GetServerPort().SetHleHandler(shared_from_this()); | ||||
|     kernel.AddNamedPort(service_name, &port->GetClientPort()); | ||||
|  | ||||
|     port_installed = true; | ||||
|  | ||||
|     return port->GetClientPort(); | ||||
| } | ||||
|  | ||||
| void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { | ||||
|   | ||||
| @@ -64,10 +64,12 @@ public: | ||||
|  | ||||
|     /// Creates a port pair and registers this service with the given ServiceManager. | ||||
|     void InstallAsService(SM::ServiceManager& service_manager); | ||||
|     /// Creates a port pair and registers it on the kernel's global port registry. | ||||
|     void InstallAsNamedPort(Kernel::KernelCore& kernel); | ||||
|     /// Invokes a service request routine. | ||||
|  | ||||
|     /// Invokes a service request routine using the HIPC protocol. | ||||
|     void InvokeRequest(Kernel::HLERequestContext& ctx); | ||||
|     /// Creates a port pair and registers it on the kernel's global port registry. | ||||
|     Kernel::KClientPort& CreatePort(Kernel::KernelCore& kernel); | ||||
|  | ||||
|     /// Handles a synchronization request for the service. | ||||
|     ResultCode HandleSyncRequest(Kernel::HLERequestContext& context) override; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user