فهرست منبع

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.
bunnei 5 سال پیش
والد
کامیت
c6de9657be
4فایلهای تغییر یافته به همراه30 افزوده شده و 22 حذف شده
  1. 11 10
      src/core/hle/kernel/kernel.cpp
  2. 11 7
      src/core/hle/kernel/kernel.h
  3. 3 2
      src/core/hle/service/service.cpp
  4. 5 3
      src/core/hle/service/service.h

+ 11 - 10
src/core/hle/kernel/kernel.cpp

@@ -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 {

+ 11 - 7
src/core/hle/kernel/kernel.h

@@ -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);
-
-    /// Finds a port within the named port table with the given name.
-    NamedPortTable::iterator FindNamedPort(const std::string& name);
+    /// 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::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;

+ 3 - 2
src/core/hle/service/service.cpp

@@ -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) {

+ 5 - 3
src/core/hle/service/service.h

@@ -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;