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:
bunnei 2021-05-10 15:57:59 -07:00
parent 44c763f9c6
commit c6de9657be
4 changed files with 30 additions and 22 deletions

View File

@ -44,6 +44,7 @@
#include "core/hle/kernel/time_manager.h" #include "core/hle/kernel/time_manager.h"
#include "core/hle/lock.h" #include "core/hle/lock.h"
#include "core/hle/result.h" #include "core/hle/result.h"
#include "core/hle/service/sm/sm.h"
#include "core/memory.h" #include "core/memory.h"
MICROPROFILE_DEFINE(Kernel_SVC, "Kernel", "SVC", MP_RGB(70, 200, 70)); 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 /// Map of named ports managed by the kernel, which can be retrieved using
/// the ConnectToPort SVC. /// the ConnectToPort SVC.
std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
NamedPortTable named_ports; NamedPortTable named_ports;
std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
@ -844,18 +846,17 @@ void KernelCore::PrepareReschedule(std::size_t id) {
// TODO: Reimplement, this // TODO: Reimplement, this
} }
void KernelCore::AddNamedPort(std::string name, KClientPort* port) { void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory) {
port->Open(); impl->service_interface_factory.emplace(std::move(name), factory);
impl->named_ports.emplace(std::move(name), port);
} }
KernelCore::NamedPortTable::iterator KernelCore::FindNamedPort(const std::string& name) { KClientPort* KernelCore::CreateNamedServicePort(std::string name) {
return impl->named_ports.find(name); auto search = impl->service_interface_factory.find(name);
} if (search == impl->service_interface_factory.end()) {
UNIMPLEMENTED();
KernelCore::NamedPortTable::const_iterator KernelCore::FindNamedPort( return {};
const std::string& name) const { }
return impl->named_ports.find(name); return &search->second(impl->system.ServiceManager(), impl->system);
} }
bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const {

View File

@ -27,6 +27,10 @@ class CoreTiming;
struct EventType; struct EventType;
} // namespace Core::Timing } // namespace Core::Timing
namespace Service::SM {
class ServiceManager;
}
namespace Kernel { namespace Kernel {
class KClientPort; class KClientPort;
@ -51,6 +55,9 @@ class ServiceThread;
class Synchronization; class Synchronization;
class TimeManager; class TimeManager;
using ServiceInterfaceFactory =
std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
namespace Init { namespace Init {
struct KSlabResourceCounts; struct KSlabResourceCounts;
} }
@ -172,14 +179,11 @@ public:
void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
/// Adds a port to the named port table /// Registers a named HLE service, passing a factory used to open a port to that service.
void AddNamedPort(std::string name, KClientPort* port); void RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory);
/// Finds a port within the named port table with the given name. /// Opens a port to a service previously registered with RegisterNamedService.
NamedPortTable::iterator FindNamedPort(const std::string& name); KClientPort* CreateNamedServicePort(std::string name);
/// Finds a port within the named port table with the given name.
NamedPortTable::const_iterator FindNamedPort(const std::string& name) const;
/// Determines whether or not the given port is a valid named port. /// Determines whether or not the given port is a valid named port.
bool IsValidNamedPort(NamedPortTable::const_iterator port) const; bool IsValidNamedPort(NamedPortTable::const_iterator port) const;

View File

@ -111,7 +111,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager)
port_installed = true; port_installed = true;
} }
void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) { Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) {
const auto guard = LockService(); const auto guard = LockService();
ASSERT(!port_installed); ASSERT(!port_installed);
@ -119,9 +119,10 @@ void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) {
auto* port = Kernel::KPort::Create(kernel); auto* port = Kernel::KPort::Create(kernel);
port->Initialize(max_sessions, false, service_name); port->Initialize(max_sessions, false, service_name);
port->GetServerPort().SetHleHandler(shared_from_this()); port->GetServerPort().SetHleHandler(shared_from_this());
kernel.AddNamedPort(service_name, &port->GetClientPort());
port_installed = true; port_installed = true;
return port->GetClientPort();
} }
void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {

View File

@ -64,10 +64,12 @@ public:
/// Creates a port pair and registers this service with the given ServiceManager. /// Creates a port pair and registers this service with the given ServiceManager.
void InstallAsService(SM::ServiceManager& service_manager); 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 using the HIPC protocol.
/// Invokes a service request routine.
void InvokeRequest(Kernel::HLERequestContext& ctx); 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. /// Handles a synchronization request for the service.
ResultCode HandleSyncRequest(Kernel::HLERequestContext& context) override; ResultCode HandleSyncRequest(Kernel::HLERequestContext& context) override;