diff options
141 files changed, 1569 insertions, 1153 deletions
| diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 696a1f9ea..cdebb0bd8 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -293,8 +293,6 @@ add_library(core STATIC      hle/kernel/physical_memory.h      hle/kernel/process_capability.cpp      hle/kernel/process_capability.h -    hle/kernel/service_thread.cpp -    hle/kernel/service_thread.h      hle/kernel/slab_helpers.h      hle/kernel/svc.cpp      hle/kernel/svc.h @@ -684,6 +682,10 @@ add_library(core STATIC      hle/service/ptm/ts.h      hle/service/kernel_helpers.cpp      hle/service/kernel_helpers.h +    hle/service/mutex.cpp +    hle/service/mutex.h +    hle/service/server_manager.cpp +    hle/service/server_manager.h      hle/service/service.cpp      hle/service/service.h      hle/service/set/set.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index fb9b25d12..4a1372d15 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -380,9 +380,7 @@ struct System::Impl {              gpu_core->NotifyShutdown();          } -        kernel.ShutdownCores(); -        cpu_manager.Shutdown(); -        debugger.reset(); +        kernel.SuspendApplication(true);          if (services) {              services->KillNVNFlinger();          } @@ -398,6 +396,9 @@ struct System::Impl {          gpu_core.reset();          host1x_core.reset();          perf_stats.reset(); +        kernel.ShutdownCores(); +        cpu_manager.Shutdown(); +        debugger.reset();          kernel.Shutdown();          memory.Reset(); @@ -938,6 +939,10 @@ const Network::RoomNetwork& System::GetRoomNetwork() const {      return impl->room_network;  } +void System::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) { +    return impl->kernel.RunServer(std::move(server_manager)); +} +  void System::RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback) {      impl->execute_program_callback = std::move(callback);  } diff --git a/src/core/core.h b/src/core/core.h index 0042ac170..91e78672e 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -61,6 +61,8 @@ namespace Glue {  class ARPManager;  } +class ServerManager; +  namespace SM {  class ServiceManager;  } // namespace SM @@ -417,6 +419,9 @@ public:      /// Tells if the system debugger is enabled.      [[nodiscard]] bool DebuggerEnabled() const; +    /// Runs a server instance until shutdown. +    void RunServer(std::unique_ptr<Service::ServerManager>&& server_manager); +      /// Type used for the frontend to designate a callback for System to re-launch the application      /// using a specified program index.      using ExecuteProgramCallback = std::function<void(std::size_t)>; diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp index a9675df76..a1589fecb 100644 --- a/src/core/debugger/debugger.cpp +++ b/src/core/debugger/debugger.cpp @@ -16,6 +16,7 @@  #include "core/debugger/debugger_interface.h"  #include "core/debugger/gdbstub.h"  #include "core/hle/kernel/global_scheduler_context.h" +#include "core/hle/kernel/k_process.h"  #include "core/hle/kernel/k_scheduler.h"  template <typename Readable, typename Buffer, typename Callback> @@ -284,12 +285,12 @@ private:      void UpdateActiveThread() {          const auto& threads{ThreadList()};          if (std::find(threads.begin(), threads.end(), state->active_thread) == threads.end()) { -            state->active_thread = threads[0]; +            state->active_thread = threads.front();          }      } -    const std::vector<Kernel::KThread*>& ThreadList() { -        return system.GlobalSchedulerContext().GetThreadList(); +    const std::list<Kernel::KThread*>& ThreadList() { +        return system.ApplicationProcess()->GetThreadList();      }  private: diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 945ec528e..18afe97e1 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp @@ -573,7 +573,7 @@ void GDBStub::HandleQuery(std::string_view command) {          SendReply(PaginateBuffer(buffer, command.substr(21)));      } else if (command.starts_with("fThreadInfo")) {          // beginning of list -        const auto& threads = system.GlobalSchedulerContext().GetThreadList(); +        const auto& threads = system.ApplicationProcess()->GetThreadList();          std::vector<std::string> thread_ids;          for (const auto& thread : threads) {              thread_ids.push_back(fmt::format("{:x}", thread->GetThreadID())); @@ -587,7 +587,7 @@ void GDBStub::HandleQuery(std::string_view command) {          buffer += R"(<?xml version="1.0"?>)";          buffer += "<threads>"; -        const auto& threads = system.GlobalSchedulerContext().GetThreadList(); +        const auto& threads = system.ApplicationProcess()->GetThreadList();          for (const auto* thread : threads) {              auto thread_name{GetThreadName(system, thread)};              if (!thread_name) { @@ -817,7 +817,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {  }  Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) { -    const auto& threads{system.GlobalSchedulerContext().GetThreadList()}; +    const auto& threads{system.ApplicationProcess()->GetThreadList()};      for (auto* thread : threads) {          if (thread->GetThreadID() == thread_id) {              return thread; diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h index 38d6cfaff..f8ab55d83 100644 --- a/src/core/hle/ipc_helpers.h +++ b/src/core/hle/ipc_helpers.h @@ -15,6 +15,7 @@  #include "core/hle/kernel/k_resource_limit.h"  #include "core/hle/kernel/k_session.h"  #include "core/hle/result.h" +#include "core/hle/service/server_manager.h"  namespace IPC { @@ -145,7 +146,9 @@ public:      template <class T>      void PushIpcInterface(std::shared_ptr<T> iface) { -        if (context->GetManager()->IsDomain()) { +        auto manager{context->GetManager()}; + +        if (manager->IsDomain()) {              context->AddDomainObject(std::move(iface));          } else {              kernel.ApplicationProcess()->GetResourceLimit()->Reserve( @@ -153,8 +156,11 @@ public:              auto* session = Kernel::KSession::Create(kernel);              session->Initialize(nullptr, iface->GetServiceName()); -            iface->RegisterSession(&session->GetServerSession(), -                                   std::make_shared<Kernel::SessionRequestManager>(kernel)); + +            auto next_manager = std::make_shared<Kernel::SessionRequestManager>( +                kernel, manager->GetServerManager()); +            next_manager->SetSessionHandler(iface); +            manager->GetServerManager().RegisterSession(&session->GetServerSession(), next_manager);              context->AddMoveObject(&session->GetClientSession());          } diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp index 494151eef..876fbbe53 100644 --- a/src/core/hle/kernel/hle_ipc.cpp +++ b/src/core/hle/kernel/hle_ipc.cpp @@ -21,36 +21,18 @@  #include "core/hle/kernel/k_server_session.h"  #include "core/hle/kernel/k_thread.h"  #include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/service_thread.h"  #include "core/memory.h"  namespace Kernel { -SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_, -                                             ServiceThreadType thread_type) -    : kernel{kernel_}, service_thread{thread_type == ServiceThreadType::CreateNew -                                          ? kernel.CreateServiceThread(service_name_) -                                          : kernel.GetDefaultServiceThread()} {} +SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_) +    : kernel{kernel_} {} -SessionRequestHandler::~SessionRequestHandler() { -    kernel.ReleaseServiceThread(service_thread); -} - -void SessionRequestHandler::AcceptSession(KServerPort* server_port) { -    auto* server_session = server_port->AcceptSession(); -    ASSERT(server_session != nullptr); - -    RegisterSession(server_session, std::make_shared<SessionRequestManager>(kernel)); -} - -void SessionRequestHandler::RegisterSession(KServerSession* server_session, -                                            std::shared_ptr<SessionRequestManager> manager) { -    manager->SetSessionHandler(shared_from_this()); -    service_thread.RegisterServerSession(server_session, manager); -    server_session->Close(); -} +SessionRequestHandler::~SessionRequestHandler() = default; -SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {} +SessionRequestManager::SessionRequestManager(KernelCore& kernel_, +                                             Service::ServerManager& server_manager_) +    : kernel{kernel_}, server_manager{server_manager_} {}  SessionRequestManager::~SessionRequestManager() = default; diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h index 5bf4f171b..b4364f984 100644 --- a/src/core/hle/kernel/hle_ipc.h +++ b/src/core/hle/kernel/hle_ipc.h @@ -31,12 +31,8 @@ class ResponseBuilder;  namespace Service {  class ServiceFrameworkBase; -} - -enum class ServiceThreadType { -    Default, -    CreateNew, -}; +class ServerManager; +} // namespace Service  namespace Kernel { @@ -53,9 +49,6 @@ class KThread;  class KReadableEvent;  class KSession;  class SessionRequestManager; -class ServiceThread; - -enum class ThreadWakeupReason;  /**   * Interface implemented by HLE Session handlers. @@ -64,8 +57,7 @@ enum class ThreadWakeupReason;   */  class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> {  public: -    SessionRequestHandler(KernelCore& kernel_, const char* service_name_, -                          ServiceThreadType thread_type); +    SessionRequestHandler(KernelCore& kernel_, const char* service_name_);      virtual ~SessionRequestHandler();      /** @@ -79,17 +71,8 @@ public:      virtual Result HandleSyncRequest(Kernel::KServerSession& session,                                       Kernel::HLERequestContext& context) = 0; -    void AcceptSession(KServerPort* server_port); -    void RegisterSession(KServerSession* server_session, -                         std::shared_ptr<SessionRequestManager> manager); - -    ServiceThread& GetServiceThread() const { -        return service_thread; -    } -  protected:      KernelCore& kernel; -    ServiceThread& service_thread;  };  using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; @@ -102,7 +85,7 @@ using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;   */  class SessionRequestManager final {  public: -    explicit SessionRequestManager(KernelCore& kernel); +    explicit SessionRequestManager(KernelCore& kernel, Service::ServerManager& server_manager);      ~SessionRequestManager();      bool IsDomain() const { @@ -155,23 +138,36 @@ public:          session_handler = std::move(handler);      } -    ServiceThread& GetServiceThread() const { -        return session_handler->GetServiceThread(); -    } -      bool HasSessionRequestHandler(const HLERequestContext& context) const;      Result HandleDomainSyncRequest(KServerSession* server_session, HLERequestContext& context);      Result CompleteSyncRequest(KServerSession* server_session, HLERequestContext& context); +    Service::ServerManager& GetServerManager() { +        return server_manager; +    } + +    // TODO: remove this when sm: is implemented with the proper IUserInterface +    // abstraction, creating a new C++ handler object for each session: + +    bool GetIsInitializedForSm() const { +        return is_initialized_for_sm; +    } + +    void SetIsInitializedForSm() { +        is_initialized_for_sm = true; +    } +  private:      bool convert_to_domain{};      bool is_domain{}; +    bool is_initialized_for_sm{};      SessionRequestHandlerPtr session_handler;      std::vector<SessionRequestHandlerPtr> domain_handlers;  private:      KernelCore& kernel; +    Service::ServerManager& server_manager;  };  /** @@ -374,6 +370,14 @@ public:          return manager.lock();      } +    bool GetIsDeferred() const { +        return is_deferred; +    } + +    void SetIsDeferred(bool is_deferred_ = true) { +        is_deferred = is_deferred_; +    } +  private:      friend class IPC::ResponseBuilder; @@ -408,6 +412,7 @@ private:      u32 domain_offset{};      std::weak_ptr<SessionRequestManager> manager{}; +    bool is_deferred{false};      KernelCore& kernel;      Core::Memory::Memory& memory; diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index 0e4283a0c..d9c1a0eb3 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -119,7 +119,6 @@ void KProcess::DecrementRunningThreadCount() {      if (const auto prev = num_running_threads--; prev == 1) {          // TODO(bunnei): Process termination to be implemented when multiprocess is supported. -        UNIMPLEMENTED_MSG("KProcess termination is not implemennted!");      }  } @@ -357,9 +356,6 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:      system_resource_size = metadata.GetSystemResourceSize();      image_size = code_size; -    // We currently do not support process-specific system resource -    UNIMPLEMENTED_IF(system_resource_size != 0); -      KScopedResourceReservation memory_reservation(          resource_limit, LimitableResource::PhysicalMemoryMax, code_size + system_resource_size);      if (!memory_reservation.Succeeded()) { diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index 2d3da9d66..599d05947 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -29,6 +29,7 @@  #include "core/hle/kernel/k_thread_queue.h"  #include "core/hle/kernel/k_worker_task_manager.h"  #include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/svc.h"  #include "core/hle/kernel/svc_results.h"  #include "core/hle/kernel/svc_types.h"  #include "core/hle/result.h" @@ -298,6 +299,25 @@ Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThr                                ThreadType::User, system.GetCpuManager().GetGuestThreadFunc()));  } +Result KThread::InitializeServiceThread(Core::System& system, KThread* thread, +                                        std::function<void()>&& func, s32 prio, s32 virt_core, +                                        KProcess* owner) { +    system.Kernel().GlobalSchedulerContext().AddThread(thread); +    std::function<void()> func2{[&system, func{std::move(func)}] { +        // Similar to UserModeThreadStarter. +        system.Kernel().CurrentScheduler()->OnThreadStart(); + +        // Run the guest function. +        func(); + +        // Exit. +        Svc::ExitThread(system); +    }}; + +    R_RETURN(InitializeThread(thread, {}, {}, {}, prio, virt_core, owner, ThreadType::HighPriority, +                              std::move(func2))); +} +  void KThread::PostDestroy(uintptr_t arg) {      KProcess* owner = reinterpret_cast<KProcess*>(arg & ~1ULL);      const bool resource_limit_release_hint = (arg & 1); diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h index ca82ce3b6..a04de21bc 100644 --- a/src/core/hle/kernel/k_thread.h +++ b/src/core/hle/kernel/k_thread.h @@ -434,6 +434,10 @@ public:                                                       VAddr user_stack_top, s32 prio, s32 virt_core,                                                       KProcess* owner); +    [[nodiscard]] static Result InitializeServiceThread(Core::System& system, KThread* thread, +                                                        std::function<void()>&& thread_func, +                                                        s32 prio, s32 virt_core, KProcess* owner); +  public:      struct StackParameters {          u8 svc_permission[0x10]; diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index 2ff253183..ce94d3605 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -34,14 +34,15 @@  #include "core/hle/kernel/k_process.h"  #include "core/hle/kernel/k_resource_limit.h"  #include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/k_scoped_resource_reservation.h"  #include "core/hle/kernel/k_shared_memory.h"  #include "core/hle/kernel/k_system_resource.h"  #include "core/hle/kernel/k_thread.h"  #include "core/hle/kernel/k_worker_task_manager.h"  #include "core/hle/kernel/kernel.h"  #include "core/hle/kernel/physical_core.h" -#include "core/hle/kernel/service_thread.h"  #include "core/hle/result.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/sm/sm.h"  #include "core/memory.h" @@ -55,9 +56,7 @@ struct KernelCore::Impl {      static constexpr size_t BlockInfoSlabHeapSize = 4000;      static constexpr size_t ReservedDynamicPageCount = 64; -    explicit Impl(Core::System& system_, KernelCore& kernel_) -        : service_threads_manager{1, "ServiceThreadsManager"}, -          service_thread_barrier{2}, system{system_} {} +    explicit Impl(Core::System& system_, KernelCore& kernel_) : system{system_} {}      void SetMulticore(bool is_multi) {          is_multicore = is_multi; @@ -98,8 +97,6 @@ struct KernelCore::Impl {          InitializeHackSharedMemory();          RegisterHostThread(nullptr); - -        default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread");      }      void InitializeCores() { @@ -140,11 +137,6 @@ struct KernelCore::Impl {          preemption_event = nullptr; -        for (auto& iter : named_ports) { -            iter.second->Close(); -        } -        named_ports.clear(); -          exclusive_monitor.reset();          // Cleanup persistent kernel objects @@ -207,8 +199,9 @@ struct KernelCore::Impl {      }      void CloseServices() { -        // Ensures all service threads gracefully shutdown. -        ClearServiceThreads(); +        // Ensures all servers gracefully shutdown. +        std::scoped_lock lk{server_lock}; +        server_managers.clear();      }      void InitializePhysicalCores() { @@ -761,55 +754,6 @@ struct KernelCore::Impl {                                        "HidBus:SharedMemory");      } -    KClientPort* CreateNamedServicePort(std::string name) { -        auto search = service_interface_factory.find(name); -        if (search == service_interface_factory.end()) { -            UNIMPLEMENTED(); -            return {}; -        } - -        return &search->second(system.ServiceManager(), system); -    } - -    void RegisterNamedServiceHandler(std::string name, KServerPort* server_port) { -        auto search = service_interface_handlers.find(name); -        if (search == service_interface_handlers.end()) { -            return; -        } - -        search->second(system.ServiceManager(), server_port); -    } - -    Kernel::ServiceThread& CreateServiceThread(KernelCore& kernel, const std::string& name) { -        auto* ptr = new ServiceThread(kernel, name); - -        service_threads_manager.QueueWork( -            [this, ptr]() { service_threads.emplace(ptr, std::unique_ptr<ServiceThread>(ptr)); }); - -        return *ptr; -    } - -    void ReleaseServiceThread(Kernel::ServiceThread& service_thread) { -        auto* ptr = &service_thread; - -        if (ptr == default_service_thread) { -            // Nothing to do here, the service is using default_service_thread, which will be -            // released on shutdown. -            return; -        } - -        service_threads_manager.QueueWork([this, ptr]() { service_threads.erase(ptr); }); -    } - -    void ClearServiceThreads() { -        service_threads_manager.QueueWork([this] { -            service_threads.clear(); -            default_service_thread = nullptr; -            service_thread_barrier.Sync(); -        }); -        service_thread_barrier.Sync(); -    } -      std::mutex registered_objects_lock;      std::mutex registered_in_use_objects_lock; @@ -839,14 +783,12 @@ struct KernelCore::Impl {      std::unique_ptr<KObjectNameGlobalData> object_name_global_data; -    /// 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; -    std::unordered_map<std::string, ServiceInterfaceHandlerFn> service_interface_handlers; -    NamedPortTable named_ports;      std::unordered_set<KAutoObject*> registered_objects;      std::unordered_set<KAutoObject*> registered_in_use_objects; +    std::mutex server_lock; +    std::vector<std::unique_ptr<Service::ServerManager>> server_managers; +      std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;      std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores; @@ -881,12 +823,6 @@ struct KernelCore::Impl {      // Memory layout      std::unique_ptr<KMemoryLayout> memory_layout; -    // Threads used for services -    std::unordered_map<ServiceThread*, std::unique_ptr<ServiceThread>> service_threads; -    ServiceThread* default_service_thread{}; -    Common::ThreadWorker service_threads_manager; -    Common::Barrier service_thread_barrier; -      std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads{};      std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; @@ -1050,23 +986,6 @@ void KernelCore::PrepareReschedule(std::size_t id) {      // TODO: Reimplement, this  } -void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory) { -    impl->service_interface_factory.emplace(std::move(name), factory); -} - -void KernelCore::RegisterInterfaceForNamedService(std::string name, -                                                  ServiceInterfaceHandlerFn&& handler) { -    impl->service_interface_handlers.emplace(std::move(name), handler); -} - -KClientPort* KernelCore::CreateNamedServicePort(std::string name) { -    return impl->CreateNamedServicePort(std::move(name)); -} - -void KernelCore::RegisterNamedServiceHandler(std::string name, KServerPort* server_port) { -    impl->RegisterNamedServiceHandler(std::move(name), server_port); -} -  void KernelCore::RegisterKernelObject(KAutoObject* object) {      std::scoped_lock lk{impl->registered_objects_lock};      impl->registered_objects.insert(object); @@ -1087,8 +1006,19 @@ void KernelCore::UnregisterInUseObject(KAutoObject* object) {      impl->registered_in_use_objects.erase(object);  } -bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { -    return port != impl->named_ports.cend(); +void KernelCore::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) { +    auto* manager = server_manager.get(); + +    { +        std::scoped_lock lk{impl->server_lock}; +        if (impl->is_shutting_down) { +            return; +        } + +        impl->server_managers.emplace_back(std::move(server_manager)); +    } + +    manager->LoopProcess();  }  u32 KernelCore::CreateNewObjectID() { @@ -1127,6 +1057,87 @@ void KernelCore::RegisterHostThread(KThread* existing_thread) {      }  } +static std::jthread RunHostThreadFunc(KernelCore& kernel, KProcess* process, +                                      std::string&& thread_name, std::function<void()>&& func) { +    // Reserve a new thread from the process resource limit. +    KScopedResourceReservation thread_reservation(process, LimitableResource::ThreadCountMax); +    ASSERT(thread_reservation.Succeeded()); + +    // Initialize the thread. +    KThread* thread = KThread::Create(kernel); +    ASSERT(R_SUCCEEDED(KThread::InitializeDummyThread(thread, process))); + +    // Commit the thread reservation. +    thread_reservation.Commit(); + +    return std::jthread( +        [&kernel, thread, thread_name{std::move(thread_name)}, func{std::move(func)}] { +            // Set the thread name. +            Common::SetCurrentThreadName(thread_name.c_str()); + +            // Register the thread. +            kernel.RegisterHostThread(thread); + +            // Run the callback. +            func(); + +            // Close the thread. +            // This will free the process if it is the last reference. +            thread->Close(); +        }); +} + +std::jthread KernelCore::RunOnHostCoreProcess(std::string&& process_name, +                                              std::function<void()> func) { +    // Make a new process. +    KProcess* process = KProcess::Create(*this); +    ASSERT(R_SUCCEEDED(KProcess::Initialize(process, System(), "", KProcess::ProcessType::Userland, +                                            GetSystemResourceLimit()))); + +    // Ensure that we don't hold onto any extra references. +    SCOPE_EXIT({ process->Close(); }); + +    // Run the host thread. +    return RunHostThreadFunc(*this, process, std::move(process_name), std::move(func)); +} + +std::jthread KernelCore::RunOnHostCoreThread(std::string&& thread_name, +                                             std::function<void()> func) { +    // Get the current process. +    KProcess* process = GetCurrentProcessPointer(*this); + +    // Run the host thread. +    return RunHostThreadFunc(*this, process, std::move(thread_name), std::move(func)); +} + +void KernelCore::RunOnGuestCoreProcess(std::string&& process_name, std::function<void()> func) { +    constexpr s32 ServiceThreadPriority = 16; +    constexpr s32 ServiceThreadCore = 3; + +    // Make a new process. +    KProcess* process = KProcess::Create(*this); +    ASSERT(R_SUCCEEDED(KProcess::Initialize(process, System(), "", KProcess::ProcessType::Userland, +                                            GetSystemResourceLimit()))); + +    // Ensure that we don't hold onto any extra references. +    SCOPE_EXIT({ process->Close(); }); + +    // Reserve a new thread from the process resource limit. +    KScopedResourceReservation thread_reservation(process, LimitableResource::ThreadCountMax); +    ASSERT(thread_reservation.Succeeded()); + +    // Initialize the thread. +    KThread* thread = KThread::Create(*this); +    ASSERT(R_SUCCEEDED(KThread::InitializeServiceThread( +        System(), thread, std::move(func), ServiceThreadPriority, ServiceThreadCore, process))); + +    // Commit the thread reservation. +    thread_reservation.Commit(); + +    // Begin running the thread. +    ASSERT(R_SUCCEEDED(thread->Run())); +} +  u32 KernelCore::GetCurrentHostThreadID() const {      return impl->GetCurrentHostThreadID();  } @@ -1271,18 +1282,6 @@ void KernelCore::ExitSVCProfile() {      MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);  } -Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) { -    return impl->CreateServiceThread(*this, name); -} - -Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const { -    return *impl->default_service_thread; -} - -void KernelCore::ReleaseServiceThread(Kernel::ServiceThread& service_thread) { -    impl->ReleaseServiceThread(service_thread); -} -  Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() {      return impl->slab_resource_counts;  } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index 6e0668f7f..4449f6949 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -9,6 +9,8 @@  #include <string>  #include <unordered_map>  #include <vector> + +#include "common/polyfill_thread.h"  #include "core/hardware_properties.h"  #include "core/hle/kernel/k_auto_object.h"  #include "core/hle/kernel/k_slab_heap.h" @@ -24,6 +26,10 @@ class CoreTiming;  struct EventType;  } // namespace Core::Timing +namespace Service { +class ServerManager; +} +  namespace Service::SM {  class ServiceManager;  } @@ -65,13 +71,6 @@ class KTransferMemory;  class KWorkerTaskManager;  class KCodeMemory;  class PhysicalCore; -class ServiceThread; -class Synchronization; - -using ServiceInterfaceFactory = -    std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>; - -using ServiceInterfaceHandlerFn = std::function<void(Service::SM::ServiceManager&, KServerPort*)>;  namespace Init {  struct KSlabResourceCounts; @@ -80,15 +79,8 @@ struct KSlabResourceCounts;  template <typename T>  class KSlabHeap; -using EmuThreadHandle = uintptr_t; -constexpr EmuThreadHandle EmuThreadHandleInvalid{}; -constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63}; -  /// Represents a single instance of the kernel.  class KernelCore { -private: -    using NamedPortTable = std::unordered_map<std::string, KClientPort*>; -  public:      /// Constructs an instance of the kernel using the given System      /// instance as a context for any necessary system-related state, @@ -196,18 +188,6 @@ public:      void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); -    /// Registers a named HLE service, passing a factory used to open a port to that service. -    void RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory); - -    /// Registers a setup function for the named HLE service. -    void RegisterInterfaceForNamedService(std::string name, ServiceInterfaceHandlerFn&& handler); - -    /// Opens a port to a service previously registered with RegisterNamedService. -    KClientPort* CreateNamedServicePort(std::string name); - -    /// Accepts a session on a port created by CreateNamedServicePort. -    void RegisterNamedServiceHandler(std::string name, KServerPort* server_port); -      /// Registers all kernel objects with the global emulation state, this is purely for tracking      /// leaks after emulation has been shutdown.      void RegisterKernelObject(KAutoObject* object); @@ -224,8 +204,8 @@ public:      /// destroyed during the current emulation session.      void UnregisterInUseObject(KAutoObject* object); -    /// Determines whether or not the given port is a valid named port. -    bool IsValidNamedPort(NamedPortTable::const_iterator port) const; +    // Runs the given server manager until shutdown. +    void RunServer(std::unique_ptr<Service::ServerManager>&& server_manager);      /// Gets the current host_thread/guest_thread pointer.      KThread* GetCurrentEmuThread() const; @@ -242,6 +222,12 @@ public:      /// Register the current thread as a non CPU core thread.      void RegisterHostThread(KThread* existing_thread = nullptr); +    void RunOnGuestCoreProcess(std::string&& process_name, std::function<void()> func); + +    std::jthread RunOnHostCoreProcess(std::string&& process_name, std::function<void()> func); + +    std::jthread RunOnHostCoreThread(std::string&& thread_name, std::function<void()> func); +      /// Gets global data for KObjectName.      KObjectNameGlobalData& ObjectNameGlobalData(); @@ -310,33 +296,6 @@ public:      void ExitSVCProfile(); -    /** -     * Creates a host thread to execute HLE service requests, which are used to execute service -     * routines asynchronously. While these are allocated per ServerSession, these need to be owned -     * and managed outside of ServerSession to avoid a circular dependency. In general, most -     * services can just use the default service thread, and not need their own host service thread. -     * See GetDefaultServiceThread. -     * @param name String name for the ServerSession creating this thread, used for debug -     * purposes. -     * @returns A reference to the newly created service thread. -     */ -    Kernel::ServiceThread& CreateServiceThread(const std::string& name); - -    /** -     * Gets the default host service thread, which executes HLE service requests. Unless service -     * requests need to block on the host, the default service thread should be used in favor of -     * creating a new service thread. -     * @returns A reference to the default service thread. -     */ -    Kernel::ServiceThread& GetDefaultServiceThread() const; - -    /** -     * Releases a HLE service thread, instructing KernelCore to free it. This should be called when -     * the ServerSession associated with the thread is destroyed. -     * @param service_thread Service thread to release. -     */ -    void ReleaseServiceThread(Kernel::ServiceThread& service_thread); -      /// Workaround for single-core mode when preempting threads while idle.      bool IsPhantomModeForSingleCore() const;      void SetIsPhantomModeForSingleCore(bool value); diff --git a/src/core/hle/kernel/service_thread.cpp b/src/core/hle/kernel/service_thread.cpp deleted file mode 100644 index 38afa720b..000000000 --- a/src/core/hle/kernel/service_thread.cpp +++ /dev/null @@ -1,206 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <functional> -#include <map> -#include <mutex> -#include <thread> -#include <vector> - -#include "common/polyfill_thread.h" -#include "common/scope_exit.h" -#include "common/thread.h" -#include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/hle_ipc.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/kernel/k_scoped_resource_reservation.h" -#include "core/hle/kernel/k_session.h" -#include "core/hle/kernel/k_thread.h" -#include "core/hle/kernel/kernel.h" -#include "core/hle/kernel/service_thread.h" - -namespace Kernel { - -class ServiceThread::Impl final { -public: -    explicit Impl(KernelCore& kernel, const std::string& service_name); -    ~Impl(); - -    void WaitAndProcessImpl(); -    void SessionClosed(KServerSession* server_session, -                       std::shared_ptr<SessionRequestManager> manager); -    void LoopProcess(); - -    void RegisterServerSession(KServerSession* session, -                               std::shared_ptr<SessionRequestManager> manager); - -private: -    KernelCore& kernel; -    const std::string m_service_name; - -    std::jthread m_host_thread{}; -    std::mutex m_session_mutex{}; -    std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{}; -    KEvent* m_wakeup_event{}; -    KThread* m_thread{}; -    std::atomic<bool> m_shutdown_requested{}; -}; - -void ServiceThread::Impl::WaitAndProcessImpl() { -    // Create local list of waitable sessions. -    std::vector<KSynchronizationObject*> objs; -    std::vector<std::shared_ptr<SessionRequestManager>> managers; - -    { -        // Lock to get the set. -        std::scoped_lock lk{m_session_mutex}; - -        // Reserve the needed quantity. -        objs.reserve(m_sessions.size() + 1); -        managers.reserve(m_sessions.size()); - -        // Copy to our local list. -        for (const auto& [session, manager] : m_sessions) { -            objs.push_back(session); -            managers.push_back(manager); -        } - -        // Insert the wakeup event at the end. -        objs.push_back(&m_wakeup_event->GetReadableEvent()); -    } - -    // Wait on the list of sessions. -    s32 index{-1}; -    Result rc = KSynchronizationObject::Wait(kernel, &index, objs.data(), -                                             static_cast<s32>(objs.size()), -1); -    ASSERT(!rc.IsFailure()); - -    // If this was the wakeup event, clear it and finish. -    if (index >= static_cast<s64>(objs.size() - 1)) { -        m_wakeup_event->Clear(); -        return; -    } - -    // This event is from a server session. -    auto* server_session = static_cast<KServerSession*>(objs[index]); -    auto& manager = managers[index]; - -    // Fetch the HLE request context. -    std::shared_ptr<HLERequestContext> context; -    rc = server_session->ReceiveRequest(&context, manager); - -    // If the session was closed, handle that. -    if (rc == ResultSessionClosed) { -        SessionClosed(server_session, manager); - -        // Finish. -        return; -    } - -    // TODO: handle other cases -    ASSERT(rc == ResultSuccess); - -    // Perform the request. -    Result service_rc = manager->CompleteSyncRequest(server_session, *context); - -    // Reply to the client. -    rc = server_session->SendReplyHLE(); - -    if (rc == ResultSessionClosed || service_rc == IPC::ERR_REMOTE_PROCESS_DEAD) { -        SessionClosed(server_session, manager); -        return; -    } - -    // TODO: handle other cases -    ASSERT(rc == ResultSuccess); -    ASSERT(service_rc == ResultSuccess); -} - -void ServiceThread::Impl::SessionClosed(KServerSession* server_session, -                                        std::shared_ptr<SessionRequestManager> manager) { -    { -        // Lock to get the set. -        std::scoped_lock lk{m_session_mutex}; - -        // Erase the session. -        ASSERT(m_sessions.erase(server_session) == 1); -    } - -    // Close our reference to the server session. -    server_session->Close(); -} - -void ServiceThread::Impl::LoopProcess() { -    Common::SetCurrentThreadName(m_service_name.c_str()); - -    kernel.RegisterHostThread(m_thread); - -    while (!m_shutdown_requested.load()) { -        WaitAndProcessImpl(); -    } -} - -void ServiceThread::Impl::RegisterServerSession(KServerSession* server_session, -                                                std::shared_ptr<SessionRequestManager> manager) { -    // Open the server session. -    server_session->Open(); - -    { -        // Lock to get the set. -        std::scoped_lock lk{m_session_mutex}; - -        // Insert the session and manager. -        m_sessions[server_session] = manager; -    } - -    // Signal the wakeup event. -    m_wakeup_event->Signal(); -} - -ServiceThread::Impl::~Impl() { -    // Shut down the processing thread. -    m_shutdown_requested.store(true); -    m_wakeup_event->Signal(); -    m_host_thread.join(); - -    // Close all remaining sessions. -    for (const auto& [server_session, manager] : m_sessions) { -        server_session->Close(); -    } - -    // Destroy remaining managers. -    m_sessions.clear(); - -    // Close event. -    m_wakeup_event->GetReadableEvent().Close(); -    m_wakeup_event->Close(); - -    // Close thread. -    m_thread->Close(); -} - -ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name) -    : kernel{kernel_}, m_service_name{service_name} { -    // Initialize event. -    m_wakeup_event = KEvent::Create(kernel); -    m_wakeup_event->Initialize(nullptr); - -    // Initialize thread. -    m_thread = KThread::Create(kernel); -    ASSERT(KThread::InitializeDummyThread(m_thread, nullptr).IsSuccess()); - -    // Start thread. -    m_host_thread = std::jthread([this] { LoopProcess(); }); -} - -ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name) -    : impl{std::make_unique<Impl>(kernel, name)} {} - -ServiceThread::~ServiceThread() = default; - -void ServiceThread::RegisterServerSession(KServerSession* session, -                                          std::shared_ptr<SessionRequestManager> manager) { -    impl->RegisterServerSession(session, manager); -} - -} // namespace Kernel diff --git a/src/core/hle/kernel/service_thread.h b/src/core/hle/kernel/service_thread.h deleted file mode 100644 index fb4325531..000000000 --- a/src/core/hle/kernel/service_thread.h +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include <memory> -#include <string> - -namespace Kernel { - -class HLERequestContext; -class KernelCore; -class KSession; -class SessionRequestManager; - -class ServiceThread final { -public: -    explicit ServiceThread(KernelCore& kernel, const std::string& name); -    ~ServiceThread(); - -    void RegisterServerSession(KServerSession* session, -                               std::shared_ptr<SessionRequestManager> manager); - -private: -    class Impl; -    std::unique_ptr<Impl> impl; -}; - -} // namespace Kernel diff --git a/src/core/hle/kernel/svc/svc_info.cpp b/src/core/hle/kernel/svc/svc_info.cpp index 58dc47508..cbed4dc8c 100644 --- a/src/core/hle/kernel/svc/svc_info.cpp +++ b/src/core/hle/kernel/svc/svc_info.cpp @@ -126,6 +126,11 @@ Result GetInfo(Core::System& system, u64* result, InfoType info_id_type, Handle              *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource();              return ResultSuccess; +        case InfoType::IsApplication: +            LOG_WARNING(Kernel_SVC, "(STUBBED) Assuming process is application"); +            *result = true; +            return ResultSuccess; +          case InfoType::FreeThreadCount:              *result = process->GetFreeThreadCount();              return ResultSuccess; diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp index 0b5b4ba2b..78c2a8d17 100644 --- a/src/core/hle/kernel/svc/svc_port.cpp +++ b/src/core/hle/kernel/svc/svc_port.cpp @@ -12,56 +12,40 @@  namespace Kernel::Svc { -/// Connect to an OS service given the port name, returns the handle to the port to out -Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { -    auto& memory = system.Memory(); -    if (!memory.IsValidVirtualAddress(port_name_address)) { -        LOG_ERROR(Kernel_SVC, -                  "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}", -                  port_name_address); -        return ResultNotFound; -    } +Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr user_name) { +    // Copy the provided name from user memory to kernel memory. +    auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax); -    static constexpr std::size_t PortNameMaxLength = 11; -    // Read 1 char beyond the max allowed port name to detect names that are too long. -    const std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1); -    if (port_name.size() > PortNameMaxLength) { -        LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength, -                  port_name.size()); -        return ResultOutOfRange; -    } +    std::array<char, KObjectName::NameLengthMax> name{}; +    std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1); -    LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); +    // Validate that the name is valid. +    R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange);      // Get the current handle table. -    auto& kernel = system.Kernel(); -    auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); +    auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();      // Find the client port. -    auto port = kernel.CreateNamedServicePort(port_name); -    if (!port) { -        LOG_ERROR(Kernel_SVC, "tried to connect to unknown port: {}", port_name); -        return ResultNotFound; -    } +    auto port = KObjectName::Find<KClientPort>(system.Kernel(), name.data()); +    R_UNLESS(port.IsNotNull(), ResultNotFound);      // Reserve a handle for the port.      // NOTE: Nintendo really does write directly to the output handle here.      R_TRY(handle_table.Reserve(out)); -    auto handle_guard = SCOPE_GUARD({ handle_table.Unreserve(*out); }); +    ON_RESULT_FAILURE { +        handle_table.Unreserve(*out); +    };      // Create a session. -    KClientSession* session{}; +    KClientSession* session;      R_TRY(port->CreateSession(std::addressof(session))); -    kernel.RegisterNamedServiceHandler(port_name, &port->GetParent()->GetServerPort()); -      // Register the session in the table, close the extra reference.      handle_table.Register(*out, session);      session->Close();      // We succeeded. -    handle_guard.Cancel(); -    return ResultSuccess; +    R_SUCCEED();  }  Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, @@ -78,8 +62,11 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) {  Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,                         int32_t max_sessions) {      // Copy the provided name from user memory to kernel memory. +    auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax); + +    // Copy the provided name from user memory to kernel memory.      std::array<char, KObjectName::NameLengthMax> name{}; -    system.Memory().ReadBlock(user_name, name.data(), sizeof(name)); +    std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1);      // Validate that sessions and name are valid.      R_UNLESS(max_sessions >= 0, ResultOutOfRange); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 1241fcdff..c3e5c4462 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -25,6 +25,7 @@  #include "core/hle/service/acc/errors.h"  #include "core/hle/service/acc/profile_manager.h"  #include "core/hle/service/glue/glue_manager.h" +#include "core/hle/service/server_manager.h"  #include "core/loader/loader.h"  namespace Service::Account { @@ -950,18 +951,20 @@ Module::Interface::Interface(std::shared_ptr<Module> module_,  Module::Interface::~Interface() = default; -void InstallInterfaces(Core::System& system) { +void LoopProcess(Core::System& system) {      auto module = std::make_shared<Module>();      auto profile_manager = std::make_shared<ProfileManager>(); - -    std::make_shared<ACC_AA>(module, profile_manager, system) -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<ACC_SU>(module, profile_manager, system) -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<ACC_U0>(module, profile_manager, system) -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<ACC_U1>(module, profile_manager, system) -        ->InstallAsService(system.ServiceManager()); +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("acc:aa", +                                         std::make_shared<ACC_AA>(module, profile_manager, system)); +    server_manager->RegisterNamedService("acc:su", +                                         std::make_shared<ACC_SU>(module, profile_manager, system)); +    server_manager->RegisterNamedService("acc:u0", +                                         std::make_shared<ACC_U0>(module, profile_manager, system)); +    server_manager->RegisterNamedService("acc:u1", +                                         std::make_shared<ACC_U1>(module, profile_manager, system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Account diff --git a/src/core/hle/service/acc/acc.h b/src/core/hle/service/acc/acc.h index 9411b0b92..a2fdafd82 100644 --- a/src/core/hle/service/acc/acc.h +++ b/src/core/hle/service/acc/acc.h @@ -67,7 +67,6 @@ public:      };  }; -/// Registers all ACC services with the specified service manager. -void InstallInterfaces(Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Account diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp index 9a7316e27..3cd772b83 100644 --- a/src/core/hle/service/am/am.cpp +++ b/src/core/hle/service/am/am.cpp @@ -32,6 +32,7 @@  #include "core/hle/service/ns/ns.h"  #include "core/hle/service/nvflinger/nvflinger.h"  #include "core/hle/service/pm/pm.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/sm/sm.h"  #include "core/hle/service/vi/vi.h"  #include "core/memory.h" @@ -1830,17 +1831,21 @@ void IApplicationFunctions::PrepareForJit(Kernel::HLERequestContext& ctx) {      rb.Push(ResultSuccess);  } -void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, -                       Core::System& system) { +void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system) {      auto message_queue = std::make_shared<AppletMessageQueue>(system);      // Needed on game boot      message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); -    std::make_shared<AppletAE>(nvflinger, message_queue, system)->InstallAsService(service_manager); -    std::make_shared<AppletOE>(nvflinger, message_queue, system)->InstallAsService(service_manager); -    std::make_shared<IdleSys>(system)->InstallAsService(service_manager); -    std::make_shared<OMM>(system)->InstallAsService(service_manager); -    std::make_shared<SPSM>(system)->InstallAsService(service_manager); +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService( +        "appletAE", std::make_shared<AppletAE>(nvflinger, message_queue, system)); +    server_manager->RegisterNamedService( +        "appletOE", std::make_shared<AppletOE>(nvflinger, message_queue, system)); +    server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system)); +    server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system)); +    server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) diff --git a/src/core/hle/service/am/am.h b/src/core/hle/service/am/am.h index a0fbfcfc5..79e2263d7 100644 --- a/src/core/hle/service/am/am.h +++ b/src/core/hle/service/am/am.h @@ -396,8 +396,6 @@ public:      ~IProcessWindingController() override;  }; -/// Registers all AM services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, -                       Core::System& system); +void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system);  } // namespace Service::AM diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp index 1bbf057cb..fed51cfd6 100644 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ b/src/core/hle/service/aoc/aoc_u.cpp @@ -17,6 +17,7 @@  #include "core/hle/ipc_helpers.h"  #include "core/hle/kernel/k_event.h"  #include "core/hle/service/aoc/aoc_u.h" +#include "core/hle/service/server_manager.h"  #include "core/loader/loader.h"  namespace Service::AOC { @@ -314,8 +315,10 @@ void AOC_U::CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ct      rb.PushIpcInterface<IPurchaseEventManager>(system);  } -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<AOC_U>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); +    server_manager->RegisterNamedService("aoc:u", std::make_shared<AOC_U>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::AOC diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h index 6c1ce601a..5e7087e50 100644 --- a/src/core/hle/service/aoc/aoc_u.h +++ b/src/core/hle/service/aoc/aoc_u.h @@ -40,7 +40,6 @@ private:      Kernel::KEvent* aoc_change_event;  }; -/// Registers all AOC services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::AOC diff --git a/src/core/hle/service/apm/apm.cpp b/src/core/hle/service/apm/apm.cpp index 44b2927a6..c23ff293d 100644 --- a/src/core/hle/service/apm/apm.cpp +++ b/src/core/hle/service/apm/apm.cpp @@ -4,20 +4,24 @@  #include "core/core.h"  #include "core/hle/service/apm/apm.h"  #include "core/hle/service/apm/apm_interface.h" +#include "core/hle/service/server_manager.h"  namespace Service::APM {  Module::Module() = default;  Module::~Module() = default; -void InstallInterfaces(Core::System& system) { -    auto module_ = std::make_shared<Module>(); -    std::make_shared<APM>(system, module_, system.GetAPMController(), "apm") -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:am") -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<APM_Sys>(system, system.GetAPMController()) -        ->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { +    auto module = std::make_shared<Module>(); +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService( +        "apm", std::make_shared<APM>(system, module, system.GetAPMController(), "apm")); +    server_manager->RegisterNamedService( +        "apm:am", std::make_shared<APM>(system, module, system.GetAPMController(), "apm:am")); +    server_manager->RegisterNamedService( +        "apm:sys", std::make_shared<APM_Sys>(system, system.GetAPMController())); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::APM diff --git a/src/core/hle/service/apm/apm.h b/src/core/hle/service/apm/apm.h index 0fecc766a..e188b4e44 100644 --- a/src/core/hle/service/apm/apm.h +++ b/src/core/hle/service/apm/apm.h @@ -15,7 +15,6 @@ public:      ~Module();  }; -/// Registers all AM services with the specified service manager. -void InstallInterfaces(Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::APM diff --git a/src/core/hle/service/audio/audin_u.cpp b/src/core/hle/service/audio/audin_u.cpp index 053e8f9dd..26dec7147 100644 --- a/src/core/hle/service/audio/audin_u.cpp +++ b/src/core/hle/service/audio/audin_u.cpp @@ -203,9 +203,8 @@ private:  };  AudInU::AudInU(Core::System& system_) -    : ServiceFramework{system_, "audin:u", ServiceThreadType::CreateNew}, -      service_context{system_, "AudInU"}, impl{std::make_unique<AudioCore::AudioIn::Manager>( -                                              system_)} { +    : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"}, +      impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} {      // clang-format off      static const FunctionInfo functions[] = {          {0, &AudInU::ListAudioIns, "ListAudioIns"}, diff --git a/src/core/hle/service/audio/audio.cpp b/src/core/hle/service/audio/audio.cpp index ed36e3448..dccd16309 100644 --- a/src/core/hle/service/audio/audio.cpp +++ b/src/core/hle/service/audio/audio.cpp @@ -1,6 +1,7 @@  // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project  // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/core.h"  #include "core/hle/service/audio/audctl.h"  #include "core/hle/service/audio/audin_u.h"  #include "core/hle/service/audio/audio.h" @@ -9,18 +10,22 @@  #include "core/hle/service/audio/audrec_u.h"  #include "core/hle/service/audio/audren_u.h"  #include "core/hle/service/audio/hwopus.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  namespace Service::Audio { -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<AudCtl>(system)->InstallAsService(service_manager); -    std::make_shared<AudOutU>(system)->InstallAsService(service_manager); -    std::make_shared<AudInU>(system)->InstallAsService(service_manager); -    std::make_shared<AudRecA>(system)->InstallAsService(service_manager); -    std::make_shared<AudRecU>(system)->InstallAsService(service_manager); -    std::make_shared<AudRenU>(system)->InstallAsService(service_manager); -    std::make_shared<HwOpus>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("audctl", std::make_shared<AudCtl>(system)); +    server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system)); +    server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system)); +    server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system)); +    server_manager->RegisterNamedService("audrec:u", std::make_shared<AudRecU>(system)); +    server_manager->RegisterNamedService("audren:u", std::make_shared<AudRenU>(system)); +    server_manager->RegisterNamedService("hwopus", std::make_shared<HwOpus>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audio.h b/src/core/hle/service/audio/audio.h index bbb2214e4..d70f022c7 100644 --- a/src/core/hle/service/audio/audio.h +++ b/src/core/hle/service/audio/audio.h @@ -13,7 +13,6 @@ class ServiceManager;  namespace Service::Audio { -/// Registers all Audio services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Audio diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp index 29751f075..991e30ba1 100644 --- a/src/core/hle/service/audio/audout_u.cpp +++ b/src/core/hle/service/audio/audout_u.cpp @@ -26,9 +26,8 @@ public:      explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,                         size_t session_id, const std::string& device_name,                         const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) -        : ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew}, -          service_context{system_, "IAudioOut"}, event{service_context.CreateEvent( -                                                     "AudioOutEvent")}, +        : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"}, +          event{service_context.CreateEvent("AudioOutEvent")},            impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {          // clang-format off @@ -221,9 +220,8 @@ private:  };  AudOutU::AudOutU(Core::System& system_) -    : ServiceFramework{system_, "audout:u", ServiceThreadType::CreateNew}, -      service_context{system_, "AudOutU"}, impl{std::make_unique<AudioCore::AudioOut::Manager>( -                                               system_)} { +    : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"}, +      impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} {      // clang-format off      static const FunctionInfo functions[] = {          {0, &AudOutU::ListAudioOuts, "ListAudioOuts"}, diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp index 7d730421d..6c12f00a1 100644 --- a/src/core/hle/service/audio/audren_u.cpp +++ b/src/core/hle/service/audio/audren_u.cpp @@ -35,10 +35,9 @@ public:                              AudioCore::AudioRendererParameterInternal& params,                              Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,                              u32 process_handle, u64 applet_resource_user_id, s32 session_id) -        : ServiceFramework{system_, "IAudioRenderer", ServiceThreadType::CreateNew}, -          service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent( -                                                          "IAudioRendererEvent")}, -          manager{manager_}, impl{std::make_unique<Renderer>(system_, manager, rendered_event)} { +        : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, +          rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, +          impl{std::make_unique<Renderer>(system_, manager, rendered_event)} {          // clang-format off          static const FunctionInfo functions[] = {              {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, @@ -243,10 +242,8 @@ class IAudioDevice final : public ServiceFramework<IAudioDevice> {  public:      explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision,                            u32 device_num) -        : ServiceFramework{system_, "IAudioDevice", ServiceThreadType::CreateNew}, -          service_context{system_, "IAudioDevice"}, impl{std::make_unique<AudioDevice>( -                                                        system_, applet_resource_user_id, -                                                        revision)}, +        : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"}, +          impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)},            event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} {          static const FunctionInfo functions[] = {              {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, @@ -421,7 +418,7 @@ private:  };  AudRenU::AudRenU(Core::System& system_) -    : ServiceFramework{system_, "audren:u", ServiceThreadType::CreateNew}, +    : ServiceFramework{system_, "audren:u"},        service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} {      // clang-format off      static const FunctionInfo functions[] = { diff --git a/src/core/hle/service/bcat/bcat_module.cpp b/src/core/hle/service/bcat/bcat_module.cpp index 6e6fed227..1db3f026b 100644 --- a/src/core/hle/service/bcat/bcat_module.cpp +++ b/src/core/hle/service/bcat/bcat_module.cpp @@ -15,6 +15,7 @@  #include "core/hle/service/bcat/bcat.h"  #include "core/hle/service/bcat/bcat_module.h"  #include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/server_manager.h"  namespace Service::BCAT { @@ -585,16 +586,23 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu  Module::Interface::~Interface() = default; -void InstallInterfaces(Core::System& system) { +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system);      auto module = std::make_shared<Module>(); -    std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:a") -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:m") -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:u") -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:s") -        ->InstallAsService(system.ServiceManager()); + +    server_manager->RegisterNamedService( +        "bcat:a", +        std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:a")); +    server_manager->RegisterNamedService( +        "bcat:m", +        std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:m")); +    server_manager->RegisterNamedService( +        "bcat:u", +        std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:u")); +    server_manager->RegisterNamedService( +        "bcat:s", +        std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:s")); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::BCAT diff --git a/src/core/hle/service/bcat/bcat_module.h b/src/core/hle/service/bcat/bcat_module.h index b2fcf9bfb..0c134d1ff 100644 --- a/src/core/hle/service/bcat/bcat_module.h +++ b/src/core/hle/service/bcat/bcat_module.h @@ -39,8 +39,7 @@ public:      };  }; -/// Registers all BCAT services with the specified service manager. -void InstallInterfaces(Core::System& system); +void LoopProcess(Core::System& system);  } // namespace BCAT diff --git a/src/core/hle/service/bpc/bpc.cpp b/src/core/hle/service/bpc/bpc.cpp index 466163538..91b15e256 100644 --- a/src/core/hle/service/bpc/bpc.cpp +++ b/src/core/hle/service/bpc/bpc.cpp @@ -4,8 +4,8 @@  #include <memory>  #include "core/hle/service/bpc/bpc.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::BPC { @@ -54,9 +54,12 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<BPC>(system)->InstallAsService(sm); -    std::make_shared<BPC_R>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("bpc", std::make_shared<BPC>(system)); +    server_manager->RegisterNamedService("bpc:r", std::make_shared<BPC_R>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::BPC diff --git a/src/core/hle/service/bpc/bpc.h b/src/core/hle/service/bpc/bpc.h index 8adc2f962..524391ddb 100644 --- a/src/core/hle/service/bpc/bpc.h +++ b/src/core/hle/service/bpc/bpc.h @@ -13,6 +13,6 @@ class ServiceManager;  namespace Service::BPC { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::BPC diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index ec7e5320c..ed020d03f 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp @@ -7,6 +7,7 @@  #include "core/hle/kernel/k_event.h"  #include "core/hle/service/btdrv/btdrv.h"  #include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  #include "core/hle/service/sm/sm.h" @@ -196,9 +197,12 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<BtDrv>(system)->InstallAsService(sm); -    std::make_shared<Bt>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("btdrv", std::make_shared<BtDrv>(system)); +    server_manager->RegisterNamedService("bt", std::make_shared<Bt>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::BtDrv diff --git a/src/core/hle/service/btdrv/btdrv.h b/src/core/hle/service/btdrv/btdrv.h index 9cbe2926f..42713860e 100644 --- a/src/core/hle/service/btdrv/btdrv.h +++ b/src/core/hle/service/btdrv/btdrv.h @@ -13,7 +13,6 @@ class System;  namespace Service::BtDrv { -/// Registers all BtDrv services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::BtDrv diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp index 419da36c4..dbd9d6a88 100644 --- a/src/core/hle/service/btm/btm.cpp +++ b/src/core/hle/service/btm/btm.cpp @@ -9,6 +9,7 @@  #include "core/hle/kernel/k_event.h"  #include "core/hle/service/btm/btm.h"  #include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  namespace Service::BTM { @@ -315,11 +316,14 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<BTM>(system)->InstallAsService(sm); -    std::make_shared<BTM_DBG>(system)->InstallAsService(sm); -    std::make_shared<BTM_SYS>(system)->InstallAsService(sm); -    std::make_shared<BTM_USR>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("btm", std::make_shared<BTM>(system)); +    server_manager->RegisterNamedService("btm:dbg", std::make_shared<BTM_DBG>(system)); +    server_manager->RegisterNamedService("btm:sys", std::make_shared<BTM_SYS>(system)); +    server_manager->RegisterNamedService("btm:u", std::make_shared<BTM_USR>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::BTM diff --git a/src/core/hle/service/btm/btm.h b/src/core/hle/service/btm/btm.h index 9dcda1848..a99b34364 100644 --- a/src/core/hle/service/btm/btm.h +++ b/src/core/hle/service/btm/btm.h @@ -13,6 +13,6 @@ class System;  namespace Service::BTM { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::BTM diff --git a/src/core/hle/service/caps/caps.cpp b/src/core/hle/service/caps/caps.cpp index 13940a8c9..610fe9940 100644 --- a/src/core/hle/service/caps/caps.cpp +++ b/src/core/hle/service/caps/caps.cpp @@ -8,17 +8,21 @@  #include "core/hle/service/caps/caps_ss.h"  #include "core/hle/service/caps/caps_su.h"  #include "core/hle/service/caps/caps_u.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  namespace Service::Capture { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<CAPS_A>(system)->InstallAsService(sm); -    std::make_shared<CAPS_C>(system)->InstallAsService(sm); -    std::make_shared<CAPS_U>(system)->InstallAsService(sm); -    std::make_shared<CAPS_SC>(system)->InstallAsService(sm); -    std::make_shared<CAPS_SS>(system)->InstallAsService(sm); -    std::make_shared<CAPS_SU>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("caps:a", std::make_shared<CAPS_A>(system)); +    server_manager->RegisterNamedService("caps:c", std::make_shared<CAPS_C>(system)); +    server_manager->RegisterNamedService("caps:u", std::make_shared<CAPS_U>(system)); +    server_manager->RegisterNamedService("caps:sc", std::make_shared<CAPS_SC>(system)); +    server_manager->RegisterNamedService("caps:ss", std::make_shared<CAPS_SS>(system)); +    server_manager->RegisterNamedService("caps:su", std::make_shared<CAPS_SU>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Capture diff --git a/src/core/hle/service/caps/caps.h b/src/core/hle/service/caps/caps.h index 3e89c82cb..15f0ecfaa 100644 --- a/src/core/hle/service/caps/caps.h +++ b/src/core/hle/service/caps/caps.h @@ -90,7 +90,6 @@ struct ApplicationAlbumFileEntry {  static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30,                "ApplicationAlbumFileEntry has incorrect size."); -/// Registers all Capture services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Capture diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp index 923c0022a..3ea862fad 100644 --- a/src/core/hle/service/erpt/erpt.cpp +++ b/src/core/hle/service/erpt/erpt.cpp @@ -4,6 +4,7 @@  #include <memory>  #include "core/hle/service/erpt/erpt.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  #include "core/hle/service/sm/sm.h" @@ -52,9 +53,13 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<ErrorReportContext>(system)->InstallAsService(sm); -    std::make_shared<ErrorReportSession>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("erpt:c", std::make_shared<ErrorReportContext>(system)); +    server_manager->RegisterNamedService("erpt:r", std::make_shared<ErrorReportSession>(system)); + +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::ERPT diff --git a/src/core/hle/service/erpt/erpt.h b/src/core/hle/service/erpt/erpt.h index 507d626ec..60094f556 100644 --- a/src/core/hle/service/erpt/erpt.h +++ b/src/core/hle/service/erpt/erpt.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::ERPT { -/// Registers all ERPT services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::ERPT diff --git a/src/core/hle/service/es/es.cpp b/src/core/hle/service/es/es.cpp index fb8686859..d9736af4e 100644 --- a/src/core/hle/service/es/es.cpp +++ b/src/core/hle/service/es/es.cpp @@ -4,6 +4,7 @@  #include "core/crypto/key_manager.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/es/es.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  namespace Service::ES { @@ -307,8 +308,11 @@ private:      Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<ETicket>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("es", std::make_shared<ETicket>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::ES diff --git a/src/core/hle/service/es/es.h b/src/core/hle/service/es/es.h index 530563550..317680625 100644 --- a/src/core/hle/service/es/es.h +++ b/src/core/hle/service/es/es.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::ES { -/// Registers all ES services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::ES diff --git a/src/core/hle/service/eupld/eupld.cpp b/src/core/hle/service/eupld/eupld.cpp index d1553ace0..3cf27513a 100644 --- a/src/core/hle/service/eupld/eupld.cpp +++ b/src/core/hle/service/eupld/eupld.cpp @@ -4,8 +4,8 @@  #include <memory>  #include "core/hle/service/eupld/eupld.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::EUPLD { @@ -44,9 +44,12 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<ErrorUploadContext>(system)->InstallAsService(sm); -    std::make_shared<ErrorUploadRequest>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("eupld:c", std::make_shared<ErrorUploadContext>(system)); +    server_manager->RegisterNamedService("eupld:r", std::make_shared<ErrorUploadRequest>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::EUPLD diff --git a/src/core/hle/service/eupld/eupld.h b/src/core/hle/service/eupld/eupld.h index 5de8219be..8eb0a5b4f 100644 --- a/src/core/hle/service/eupld/eupld.h +++ b/src/core/hle/service/eupld/eupld.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::EUPLD { -/// Registers all EUPLD services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::EUPLD diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 2e5919330..3b7b636f3 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -13,6 +13,7 @@  #include "core/hle/service/fatal/fatal.h"  #include "core/hle/service/fatal/fatal_p.h"  #include "core/hle/service/fatal/fatal_u.h" +#include "core/hle/service/server_manager.h"  #include "core/reporter.h"  namespace Service::Fatal { @@ -163,10 +164,13 @@ void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx)      rb.Push(ResultSuccess);  } -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system);      auto module = std::make_shared<Module>(); -    std::make_shared<Fatal_P>(module, system)->InstallAsService(service_manager); -    std::make_shared<Fatal_U>(module, system)->InstallAsService(service_manager); + +    server_manager->RegisterNamedService("fatal:p", std::make_shared<Fatal_P>(module, system)); +    server_manager->RegisterNamedService("fatal:u", std::make_shared<Fatal_U>(module, system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Fatal diff --git a/src/core/hle/service/fatal/fatal.h b/src/core/hle/service/fatal/fatal.h index a7a310f7b..2e4e4c2f6 100644 --- a/src/core/hle/service/fatal/fatal.h +++ b/src/core/hle/service/fatal/fatal.h @@ -28,6 +28,6 @@ public:      };  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Fatal diff --git a/src/core/hle/service/fgm/fgm.cpp b/src/core/hle/service/fgm/fgm.cpp index 7e9fb0385..612491270 100644 --- a/src/core/hle/service/fgm/fgm.cpp +++ b/src/core/hle/service/fgm/fgm.cpp @@ -5,6 +5,7 @@  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/fgm/fgm.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  #include "core/hle/service/sm/sm.h" @@ -63,11 +64,14 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<FGM>(system, "fgm")->InstallAsService(sm); -    std::make_shared<FGM>(system, "fgm:0")->InstallAsService(sm); -    std::make_shared<FGM>(system, "fgm:9")->InstallAsService(sm); -    std::make_shared<FGM_DBG>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("fgm", std::make_shared<FGM>(system, "fgm")); +    server_manager->RegisterNamedService("fgm:0", std::make_shared<FGM>(system, "fgm:0")); +    server_manager->RegisterNamedService("fgm:9", std::make_shared<FGM>(system, "fgm:9")); +    server_manager->RegisterNamedService("fgm:dbg", std::make_shared<FGM_DBG>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::FGM diff --git a/src/core/hle/service/fgm/fgm.h b/src/core/hle/service/fgm/fgm.h index 077e48812..9d2465c0f 100644 --- a/src/core/hle/service/fgm/fgm.h +++ b/src/core/hle/service/fgm/fgm.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::FGM { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::FGM diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 177447bc1..dfcdd3ada 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -23,6 +23,7 @@  #include "core/hle/service/filesystem/fsp_ldr.h"  #include "core/hle/service/filesystem/fsp_pr.h"  #include "core/hle/service/filesystem/fsp_srv.h" +#include "core/hle/service/server_manager.h"  #include "core/loader/loader.h"  namespace Service::FileSystem { @@ -796,10 +797,13 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove      }  } -void InstallInterfaces(Core::System& system) { -    std::make_shared<FSP_LDR>(system)->InstallAsService(system.ServiceManager()); -    std::make_shared<FSP_PR>(system)->InstallAsService(system.ServiceManager()); -    std::make_shared<FSP_SRV>(system)->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("fsp-ldr", std::make_shared<FSP_LDR>(system)); +    server_manager->RegisterNamedService("fsp:pr", std::make_shared<FSP_PR>(system)); +    server_manager->RegisterNamedService("fsp-srv", std::make_shared<FSP_SRV>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::FileSystem diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h index 5b27de9fa..a5c1c9d3e 100644 --- a/src/core/hle/service/filesystem/filesystem.h +++ b/src/core/hle/service/filesystem/filesystem.h @@ -139,7 +139,7 @@ private:      Core::System& system;  }; -void InstallInterfaces(Core::System& system); +void LoopProcess(Core::System& system);  // A class that wraps a VfsDirectory with methods that return ResultVal and Result instead of  // pointers and booleans. This makes using a VfsDirectory with switch services much easier and diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp index e76346ca9..89eddb510 100644 --- a/src/core/hle/service/filesystem/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp_srv.cpp @@ -57,8 +57,7 @@ enum class FileSystemType : u8 {  class IStorage final : public ServiceFramework<IStorage> {  public:      explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_) -        : ServiceFramework{system_, "IStorage", ServiceThreadType::CreateNew}, -          backend(std::move(backend_)) { +        : ServiceFramework{system_, "IStorage"}, backend(std::move(backend_)) {          static const FunctionInfo functions[] = {              {0, &IStorage::Read, "Read"},              {1, nullptr, "Write"}, @@ -116,8 +115,7 @@ private:  class IFile final : public ServiceFramework<IFile> {  public:      explicit IFile(Core::System& system_, FileSys::VirtualFile backend_) -        : ServiceFramework{system_, "IFile", ServiceThreadType::CreateNew}, -          backend(std::move(backend_)) { +        : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) {          static const FunctionInfo functions[] = {              {0, &IFile::Read, "Read"},              {1, &IFile::Write, "Write"}, @@ -254,8 +252,7 @@ static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vec  class IDirectory final : public ServiceFramework<IDirectory> {  public:      explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_) -        : ServiceFramework{system_, "IDirectory", ServiceThreadType::CreateNew}, -          backend(std::move(backend_)) { +        : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) {          static const FunctionInfo functions[] = {              {0, &IDirectory::Read, "Read"},              {1, &IDirectory::GetEntryCount, "GetEntryCount"}, @@ -311,8 +308,8 @@ private:  class IFileSystem final : public ServiceFramework<IFileSystem> {  public:      explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_) -        : ServiceFramework{system_, "IFileSystem", ServiceThreadType::CreateNew}, -          backend{std::move(backend_)}, size{std::move(size_)} { +        : ServiceFramework{system_, "IFileSystem"}, backend{std::move(backend_)}, size{std::move( +                                                                                      size_)} {          static const FunctionInfo functions[] = {              {0, &IFileSystem::CreateFile, "CreateFile"},              {1, &IFileSystem::DeleteFile, "DeleteFile"}, diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index fad532115..fcf10bfeb 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -11,6 +11,7 @@  #include "core/hle/service/friend/friend.h"  #include "core/hle/service/friend/friend_interface.h"  #include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/server_manager.h"  namespace Service::Friend { @@ -335,13 +336,22 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst  Module::Interface::~Interface() = default; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system);      auto module = std::make_shared<Module>(); -    std::make_shared<Friend>(module, system, "friend:a")->InstallAsService(service_manager); -    std::make_shared<Friend>(module, system, "friend:m")->InstallAsService(service_manager); -    std::make_shared<Friend>(module, system, "friend:s")->InstallAsService(service_manager); -    std::make_shared<Friend>(module, system, "friend:u")->InstallAsService(service_manager); -    std::make_shared<Friend>(module, system, "friend:v")->InstallAsService(service_manager); + +    server_manager->RegisterNamedService("friend:a", +                                         std::make_shared<Friend>(module, system, "friend:a")); +    server_manager->RegisterNamedService("friend:m", +                                         std::make_shared<Friend>(module, system, "friend:m")); +    server_manager->RegisterNamedService("friend:s", +                                         std::make_shared<Friend>(module, system, "friend:s")); +    server_manager->RegisterNamedService("friend:u", +                                         std::make_shared<Friend>(module, system, "friend:u")); +    server_manager->RegisterNamedService("friend:v", +                                         std::make_shared<Friend>(module, system, "friend:v")); + +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Friend diff --git a/src/core/hle/service/friend/friend.h b/src/core/hle/service/friend/friend.h index 444da8b35..41be06a4f 100644 --- a/src/core/hle/service/friend/friend.h +++ b/src/core/hle/service/friend/friend.h @@ -27,7 +27,6 @@ public:      };  }; -/// Registers all Friend services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Friend diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp index 717f2562b..993c3d21d 100644 --- a/src/core/hle/service/glue/glue.cpp +++ b/src/core/hle/service/glue/glue.cpp @@ -8,25 +8,30 @@  #include "core/hle/service/glue/ectx.h"  #include "core/hle/service/glue/glue.h"  #include "core/hle/service/glue/notif.h" +#include "core/hle/service/server_manager.h"  namespace Service::Glue { -void InstallInterfaces(Core::System& system) { +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); +      // ARP -    std::make_shared<ARP_R>(system, system.GetARPManager()) -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<ARP_W>(system, system.GetARPManager()) -        ->InstallAsService(system.ServiceManager()); +    server_manager->RegisterNamedService("arp:r", +                                         std::make_shared<ARP_R>(system, system.GetARPManager())); +    server_manager->RegisterNamedService("arp:w", +                                         std::make_shared<ARP_W>(system, system.GetARPManager()));      // BackGround Task Controller -    std::make_shared<BGTC_T>(system)->InstallAsService(system.ServiceManager()); -    std::make_shared<BGTC_SC>(system)->InstallAsService(system.ServiceManager()); +    server_manager->RegisterNamedService("bgtc:t", std::make_shared<BGTC_T>(system)); +    server_manager->RegisterNamedService("bgtc:sc", std::make_shared<BGTC_SC>(system));      // Error Context -    std::make_shared<ECTX_AW>(system)->InstallAsService(system.ServiceManager()); +    server_manager->RegisterNamedService("ectx:aw", std::make_shared<ECTX_AW>(system));      // Notification Services for application -    std::make_shared<NOTIF_A>(system)->InstallAsService(system.ServiceManager()); +    server_manager->RegisterNamedService("notif:a", std::make_shared<NOTIF_A>(system)); + +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Glue diff --git a/src/core/hle/service/glue/glue.h b/src/core/hle/service/glue/glue.h index ae7c6d235..2a906f5ad 100644 --- a/src/core/hle/service/glue/glue.h +++ b/src/core/hle/service/glue/glue.h @@ -9,7 +9,6 @@ class System;  namespace Service::Glue { -/// Registers all Glue services with the specified service manager. -void InstallInterfaces(Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Glue diff --git a/src/core/hle/service/grc/grc.cpp b/src/core/hle/service/grc/grc.cpp index 4b684f6d0..64275da36 100644 --- a/src/core/hle/service/grc/grc.cpp +++ b/src/core/hle/service/grc/grc.cpp @@ -4,8 +4,8 @@  #include <memory>  #include "core/hle/service/grc/grc.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::GRC { @@ -26,8 +26,11 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<GRC>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("grc:c", std::make_shared<GRC>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::GRC diff --git a/src/core/hle/service/grc/grc.h b/src/core/hle/service/grc/grc.h index f8c2f8dab..a3f8a5b90 100644 --- a/src/core/hle/service/grc/grc.h +++ b/src/core/hle/service/grc/grc.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::GRC { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::GRC diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 0da67235f..4b5130469 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -18,6 +18,7 @@  #include "core/hle/service/hid/hidbus.h"  #include "core/hle/service/hid/irs.h"  #include "core/hle/service/hid/xcd.h" +#include "core/hle/service/server_manager.h"  #include "core/memory.h"  #include "core/hle/service/hid/controllers/console_sixaxis.h" @@ -2739,16 +2740,20 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<Hid>(system)->InstallAsService(service_manager); -    std::make_shared<HidBus>(system)->InstallAsService(service_manager); -    std::make_shared<HidDbg>(system)->InstallAsService(service_manager); -    std::make_shared<HidSys>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); -    std::make_shared<Service::IRS::IRS>(system)->InstallAsService(service_manager); -    std::make_shared<Service::IRS::IRS_SYS>(system)->InstallAsService(service_manager); +    server_manager->RegisterNamedService("hid", std::make_shared<Hid>(system)); +    server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system)); +    server_manager->RegisterNamedService("hid:dbg", std::make_shared<HidDbg>(system)); +    server_manager->RegisterNamedService("hid:sys", std::make_shared<HidSys>(system)); -    std::make_shared<XCD_SYS>(system)->InstallAsService(service_manager); +    server_manager->RegisterNamedService("irs", std::make_shared<Service::IRS::IRS>(system)); +    server_manager->RegisterNamedService("irs:sys", +                                         std::make_shared<Service::IRS::IRS_SYS>(system)); + +    server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system)); +    system.RunServer(std::move(server_manager));  }  } // namespace Service::HID diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h index 9ace83129..9563654b6 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -216,7 +216,6 @@ private:      KernelHelpers::ServiceContext service_context;  }; -/// Registers all HID services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::HID diff --git a/src/core/hle/service/jit/jit.cpp b/src/core/hle/service/jit/jit.cpp index 47a1277ea..005c212dc 100644 --- a/src/core/hle/service/jit/jit.cpp +++ b/src/core/hle/service/jit/jit.cpp @@ -9,6 +9,7 @@  #include "core/hle/result.h"  #include "core/hle/service/jit/jit.h"  #include "core/hle/service/jit/jit_context.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  #include "core/memory.h" @@ -23,8 +24,8 @@ class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {  public:      explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx,                               CodeRange user_ro) -        : ServiceFramework{system_, "IJitEnvironment", ServiceThreadType::CreateNew}, -          process{&process_}, context{system_.Memory()} { +        : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, context{ +                                                                                system_.Memory()} {          // clang-format off          static const FunctionInfo functions[] = {              {0, &IJitEnvironment::GenerateCode, "GenerateCode"}, @@ -397,8 +398,11 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<JITU>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("jit:u", std::make_shared<JITU>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::JIT diff --git a/src/core/hle/service/jit/jit.h b/src/core/hle/service/jit/jit.h index af0f5b4f3..19014c75a 100644 --- a/src/core/hle/service/jit/jit.h +++ b/src/core/hle/service/jit/jit.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::JIT { -/// Registers all JIT services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::JIT diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp index 42991928e..a39ce5212 100644 --- a/src/core/hle/service/kernel_helpers.cpp +++ b/src/core/hle/service/kernel_helpers.cpp @@ -15,17 +15,24 @@ namespace Service::KernelHelpers {  ServiceContext::ServiceContext(Core::System& system_, std::string name_)      : kernel(system_.Kernel()) { +    if (process = Kernel::GetCurrentProcessPointer(kernel); process != nullptr) { +        return; +    } +      // Create the process.      process = Kernel::KProcess::Create(kernel);      ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_),                                          Kernel::KProcess::ProcessType::KernelInternal,                                          kernel.GetSystemResourceLimit())                 .IsSuccess()); +    process_created = true;  }  ServiceContext::~ServiceContext() { -    process->Close(); -    process = nullptr; +    if (process_created) { +        process->Close(); +        process = nullptr; +    }  }  Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { diff --git a/src/core/hle/service/kernel_helpers.h b/src/core/hle/service/kernel_helpers.h index 6415838e5..eca9aefb5 100644 --- a/src/core/hle/service/kernel_helpers.h +++ b/src/core/hle/service/kernel_helpers.h @@ -29,6 +29,7 @@ public:  private:      Kernel::KernelCore& kernel;      Kernel::KProcess* process{}; +    bool process_created{false};  };  } // namespace Service::KernelHelpers diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp index c8415e0bf..3f3c68d80 100644 --- a/src/core/hle/service/lbl/lbl.cpp +++ b/src/core/hle/service/lbl/lbl.cpp @@ -7,6 +7,7 @@  #include "common/logging/log.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/lbl/lbl.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  #include "core/hle/service/sm/sm.h" @@ -319,8 +320,11 @@ private:      bool auto_brightness = false; // TODO(ogniK): Move to system settings  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<LBL>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("lbl", std::make_shared<LBL>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::LBL diff --git a/src/core/hle/service/lbl/lbl.h b/src/core/hle/service/lbl/lbl.h index 6484105c2..e47759c01 100644 --- a/src/core/hle/service/lbl/lbl.h +++ b/src/core/hle/service/lbl/lbl.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::LBL { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::LBL diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index e5099d61f..4c2abe7d3 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -8,6 +8,7 @@  #include "core/hle/service/ldn/ldn.h"  #include "core/hle/service/ldn/ldn_results.h"  #include "core/hle/service/ldn/ldn_types.h" +#include "core/hle/service/server_manager.h"  #include "core/internal_network/network.h"  #include "core/internal_network/network_interface.h"  #include "network/network.h" @@ -106,7 +107,7 @@ class IUserLocalCommunicationService final      : public ServiceFramework<IUserLocalCommunicationService> {  public:      explicit IUserLocalCommunicationService(Core::System& system_) -        : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew}, +        : ServiceFramework{system_, "IUserLocalCommunicationService"},            service_context{system, "IUserLocalCommunicationService"},            room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} {          // clang-format off @@ -730,12 +731,15 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<LDNM>(system)->InstallAsService(sm); -    std::make_shared<LDNS>(system)->InstallAsService(sm); -    std::make_shared<LDNU>(system)->InstallAsService(sm); -    std::make_shared<LP2PAPP>(system)->InstallAsService(sm); -    std::make_shared<LP2PSYS>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("ldn:m", std::make_shared<LDNM>(system)); +    server_manager->RegisterNamedService("ldn:s", std::make_shared<LDNS>(system)); +    server_manager->RegisterNamedService("ldn:u", std::make_shared<LDNU>(system)); +    server_manager->RegisterNamedService("lp2p:app", std::make_shared<LP2PAPP>(system)); +    server_manager->RegisterNamedService("lp2p:sys", std::make_shared<LP2PSYS>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::LDN diff --git a/src/core/hle/service/ldn/ldn.h b/src/core/hle/service/ldn/ldn.h index 6afe2ea6f..fa869fa89 100644 --- a/src/core/hle/service/ldn/ldn.h +++ b/src/core/hle/service/ldn/ldn.h @@ -13,13 +13,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::LDN { -/// Registers all LDN services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::LDN diff --git a/src/core/hle/service/ldr/ldr.cpp b/src/core/hle/service/ldr/ldr.cpp index 2d4d6fe3e..c82e189f4 100644 --- a/src/core/hle/service/ldr/ldr.cpp +++ b/src/core/hle/service/ldr/ldr.cpp @@ -14,6 +14,7 @@  #include "core/hle/kernel/svc_results.h"  #include "core/hle/kernel/svc_types.h"  #include "core/hle/service/ldr/ldr.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  #include "core/loader/nro.h"  #include "core/memory.h" @@ -159,8 +160,7 @@ public:  class RelocatableObject final : public ServiceFramework<RelocatableObject> {  public: -    explicit RelocatableObject(Core::System& system_) -        : ServiceFramework{system_, "ldr:ro", ServiceThreadType::CreateNew} { +    explicit RelocatableObject(Core::System& system_) : ServiceFramework{system_, "ldr:ro"} {          // clang-format off          static const FunctionInfo functions[] = {              {0, &RelocatableObject::LoadModule, "LoadModule"}, @@ -682,11 +682,15 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<DebugMonitor>(system)->InstallAsService(sm); -    std::make_shared<ProcessManager>(system)->InstallAsService(sm); -    std::make_shared<Shell>(system)->InstallAsService(sm); -    std::make_shared<RelocatableObject>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("ldr:dmnt", std::make_shared<DebugMonitor>(system)); +    server_manager->RegisterNamedService("ldr:pm", std::make_shared<ProcessManager>(system)); +    server_manager->RegisterNamedService("ldr:shel", std::make_shared<Shell>(system)); +    server_manager->RegisterNamedService("ldr:ro", std::make_shared<RelocatableObject>(system)); + +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::LDR diff --git a/src/core/hle/service/ldr/ldr.h b/src/core/hle/service/ldr/ldr.h index 25ffd8442..c9281dbfb 100644 --- a/src/core/hle/service/ldr/ldr.h +++ b/src/core/hle/service/ldr/ldr.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::LDR { -/// Registers all LDR services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::LDR diff --git a/src/core/hle/service/lm/lm.cpp b/src/core/hle/service/lm/lm.cpp index ef4b54046..7efd8e0ab 100644 --- a/src/core/hle/service/lm/lm.cpp +++ b/src/core/hle/service/lm/lm.cpp @@ -10,6 +10,7 @@  #include "core/core.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/lm/lm.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  namespace Service::LM { @@ -351,8 +352,11 @@ private:      }  }; -void InstallInterfaces(Core::System& system) { -    std::make_shared<LM>(system)->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("lm", std::make_shared<LM>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::LM diff --git a/src/core/hle/service/lm/lm.h b/src/core/hle/service/lm/lm.h index 266019c30..0d7c39cbc 100644 --- a/src/core/hle/service/lm/lm.h +++ b/src/core/hle/service/lm/lm.h @@ -9,7 +9,6 @@ class System;  namespace Service::LM { -/// Registers all LM services with the specified service manager. -void InstallInterfaces(Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::LM diff --git a/src/core/hle/service/mig/mig.cpp b/src/core/hle/service/mig/mig.cpp index b9fe0cecd..082e470ab 100644 --- a/src/core/hle/service/mig/mig.cpp +++ b/src/core/hle/service/mig/mig.cpp @@ -4,8 +4,8 @@  #include <memory>  #include "core/hle/service/mig/mig.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::Migration { @@ -32,8 +32,11 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<MIG_USR>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("mig:user", std::make_shared<MIG_USR>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Migration diff --git a/src/core/hle/service/mig/mig.h b/src/core/hle/service/mig/mig.h index f1641a521..c8ed732a5 100644 --- a/src/core/hle/service/mig/mig.h +++ b/src/core/hle/service/mig/mig.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::Migration { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Migration diff --git a/src/core/hle/service/mii/mii.cpp b/src/core/hle/service/mii/mii.cpp index 390514fdc..50dc0ac64 100644 --- a/src/core/hle/service/mii/mii.cpp +++ b/src/core/hle/service/mii/mii.cpp @@ -7,8 +7,8 @@  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/mii/mii.h"  #include "core/hle/service/mii/mii_manager.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::Mii { @@ -310,11 +310,13 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<MiiDBModule>(system, "mii:e")->InstallAsService(sm); -    std::make_shared<MiiDBModule>(system, "mii:u")->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); -    std::make_shared<MiiImg>(system)->InstallAsService(sm); +    server_manager->RegisterNamedService("mii:e", std::make_shared<MiiDBModule>(system, "mii:e")); +    server_manager->RegisterNamedService("mii:u", std::make_shared<MiiDBModule>(system, "mii:u")); +    server_manager->RegisterNamedService("miiimg", std::make_shared<MiiImg>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Mii diff --git a/src/core/hle/service/mii/mii.h b/src/core/hle/service/mii/mii.h index 009d80d58..ed4e3f62b 100644 --- a/src/core/hle/service/mii/mii.h +++ b/src/core/hle/service/mii/mii.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::Mii { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Mii diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp index ba8c0e230..bee72fa1b 100644 --- a/src/core/hle/service/mm/mm_u.cpp +++ b/src/core/hle/service/mm/mm_u.cpp @@ -4,6 +4,7 @@  #include "common/logging/log.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/mm/mm_u.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/sm/sm.h"  namespace Service::MM { @@ -103,8 +104,11 @@ private:      u32 id{1};  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<MM_U>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("mm:u", std::make_shared<MM_U>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::MM diff --git a/src/core/hle/service/mm/mm_u.h b/src/core/hle/service/mm/mm_u.h index b40941e35..43117c9b1 100644 --- a/src/core/hle/service/mm/mm_u.h +++ b/src/core/hle/service/mm/mm_u.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::MM { -/// Registers all MM services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::MM diff --git a/src/core/hle/service/mnpp/mnpp_app.cpp b/src/core/hle/service/mnpp/mnpp_app.cpp index c3aad5714..4ce4672b7 100644 --- a/src/core/hle/service/mnpp/mnpp_app.cpp +++ b/src/core/hle/service/mnpp/mnpp_app.cpp @@ -4,7 +4,8 @@  #include "common/logging/log.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/mnpp/mnpp_app.h" -#include "core/hle/service/sm/sm.h" +#include "core/hle/service/server_manager.h" +#include "core/hle/service/service.h"  namespace Service::MNPP { @@ -37,8 +38,11 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<MNPP_APP>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("mnpp:app", std::make_shared<MNPP_APP>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::MNPP diff --git a/src/core/hle/service/mnpp/mnpp_app.h b/src/core/hle/service/mnpp/mnpp_app.h index eec75fe0e..40d0395bd 100644 --- a/src/core/hle/service/mnpp/mnpp_app.h +++ b/src/core/hle/service/mnpp/mnpp_app.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::MNPP { -/// Registers all MNPP services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::MNPP diff --git a/src/core/hle/service/mutex.cpp b/src/core/hle/service/mutex.cpp new file mode 100644 index 000000000..07589a0f0 --- /dev/null +++ b/src/core/hle/service/mutex.cpp @@ -0,0 +1,43 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/core.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_synchronization_object.h" +#include "core/hle/service/mutex.h" + +namespace Service { + +Mutex::Mutex(Core::System& system) : m_system(system) { +    m_event = Kernel::KEvent::Create(system.Kernel()); +    m_event->Initialize(nullptr); + +    ASSERT(R_SUCCEEDED(m_event->Signal())); +} + +Mutex::~Mutex() { +    m_event->GetReadableEvent().Close(); +    m_event->Close(); +} + +void Mutex::lock() { +    // Infinitely retry until we successfully clear the event. +    while (R_FAILED(m_event->GetReadableEvent().Reset())) { +        s32 index; +        Kernel::KSynchronizationObject* obj = &m_event->GetReadableEvent(); + +        // The event was already cleared! +        // Wait for it to become signaled again. +        ASSERT(R_SUCCEEDED( +            Kernel::KSynchronizationObject::Wait(m_system.Kernel(), &index, &obj, 1, -1))); +    } + +    // We successfully cleared the event, and now have exclusive ownership. +} + +void Mutex::unlock() { +    // Unlock. +    ASSERT(R_SUCCEEDED(m_event->Signal())); +} + +} // namespace Service diff --git a/src/core/hle/service/mutex.h b/src/core/hle/service/mutex.h new file mode 100644 index 000000000..95ac9b117 --- /dev/null +++ b/src/core/hle/service/mutex.h @@ -0,0 +1,31 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/common_types.h" + +namespace Core { +class System; +} + +namespace Kernel { +class KEvent; +} + +namespace Service { + +class Mutex { +public: +    explicit Mutex(Core::System& system); +    ~Mutex(); + +    void lock(); +    void unlock(); + +private: +    Core::System& m_system; +    Kernel::KEvent* m_event{}; +}; + +} // namespace Service diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp index 4c66cfeba..5ab24dc34 100644 --- a/src/core/hle/service/ncm/ncm.cpp +++ b/src/core/hle/service/ncm/ncm.cpp @@ -6,8 +6,8 @@  #include "core/file_sys/romfs_factory.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/ncm/ncm.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::NCM { @@ -132,9 +132,12 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<LR>(system)->InstallAsService(sm); -    std::make_shared<NCM>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("lr", std::make_shared<LR>(system)); +    server_manager->RegisterNamedService("ncm", std::make_shared<NCM>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::NCM diff --git a/src/core/hle/service/ncm/ncm.h b/src/core/hle/service/ncm/ncm.h index de3971437..b78efdcd7 100644 --- a/src/core/hle/service/ncm/ncm.h +++ b/src/core/hle/service/ncm/ncm.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::NCM { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::NCM diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index b17b18ab9..34612b9df 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp @@ -9,8 +9,8 @@  #include "core/hle/service/nfc/mifare_user.h"  #include "core/hle/service/nfc/nfc.h"  #include "core/hle/service/nfc/nfc_user.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::NFC { @@ -154,11 +154,14 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<NFC_AM>(system)->InstallAsService(sm); -    std::make_shared<NFC_MF_U>(system)->InstallAsService(sm); -    std::make_shared<NFC_U>(system)->InstallAsService(sm); -    std::make_shared<NFC_SYS>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("nfc:am", std::make_shared<NFC_AM>(system)); +    server_manager->RegisterNamedService("nfc:mf:u", std::make_shared<NFC_MF_U>(system)); +    server_manager->RegisterNamedService("nfc:user", std::make_shared<NFC_U>(system)); +    server_manager->RegisterNamedService("nfc:sys", std::make_shared<NFC_SYS>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::NFC diff --git a/src/core/hle/service/nfc/nfc.h b/src/core/hle/service/nfc/nfc.h index 0107b696c..d15955b75 100644 --- a/src/core/hle/service/nfc/nfc.h +++ b/src/core/hle/service/nfc/nfc.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::NFC { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::NFC diff --git a/src/core/hle/service/nfp/nfp.cpp b/src/core/hle/service/nfp/nfp.cpp index 0cb55ca49..1b59aba8e 100644 --- a/src/core/hle/service/nfp/nfp.cpp +++ b/src/core/hle/service/nfp/nfp.cpp @@ -5,6 +5,7 @@  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/nfp/nfp.h"  #include "core/hle/service/nfp/nfp_user.h" +#include "core/hle/service/server_manager.h"  namespace Service::NFP { @@ -36,8 +37,11 @@ private:      std::shared_ptr<IUser> user_interface;  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<IUserManager>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("nfp:user", std::make_shared<IUserManager>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::NFP diff --git a/src/core/hle/service/nfp/nfp.h b/src/core/hle/service/nfp/nfp.h index a25c362b8..a5aac710b 100644 --- a/src/core/hle/service/nfp/nfp.h +++ b/src/core/hle/service/nfp/nfp.h @@ -7,6 +7,6 @@  namespace Service::NFP { -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::NFP diff --git a/src/core/hle/service/ngct/ngct.cpp b/src/core/hle/service/ngct/ngct.cpp index 8af8a835d..76897d05c 100644 --- a/src/core/hle/service/ngct/ngct.cpp +++ b/src/core/hle/service/ngct/ngct.cpp @@ -5,6 +5,7 @@  #include "core/core.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/ngct/ngct.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  namespace Service::NGCT { @@ -51,8 +52,11 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<IService>(system)->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("ngct:u", std::make_shared<IService>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::NGCT diff --git a/src/core/hle/service/ngct/ngct.h b/src/core/hle/service/ngct/ngct.h index 370bd4a25..27c34dad4 100644 --- a/src/core/hle/service/ngct/ngct.h +++ b/src/core/hle/service/ngct/ngct.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::NGCT { -/// Registers all NGCT services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::NGCT diff --git a/src/core/hle/service/nifm/nifm.cpp b/src/core/hle/service/nifm/nifm.cpp index 5d32adf64..3d176b3c2 100644 --- a/src/core/hle/service/nifm/nifm.cpp +++ b/src/core/hle/service/nifm/nifm.cpp @@ -6,6 +6,7 @@  #include "core/hle/kernel/k_event.h"  #include "core/hle/service/kernel_helpers.h"  #include "core/hle/service/nifm/nifm.h" +#include "core/hle/service/server_manager.h"  namespace { @@ -626,10 +627,16 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<NetworkInterface>("nifm:a", system)->InstallAsService(service_manager); -    std::make_shared<NetworkInterface>("nifm:s", system)->InstallAsService(service_manager); -    std::make_shared<NetworkInterface>("nifm:u", system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("nifm:a", +                                         std::make_shared<NetworkInterface>("nifm:a", system)); +    server_manager->RegisterNamedService("nifm:s", +                                         std::make_shared<NetworkInterface>("nifm:s", system)); +    server_manager->RegisterNamedService("nifm:u", +                                         std::make_shared<NetworkInterface>("nifm:u", system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::NIFM diff --git a/src/core/hle/service/nifm/nifm.h b/src/core/hle/service/nifm/nifm.h index 48161be28..b5da7ae12 100644 --- a/src/core/hle/service/nifm/nifm.h +++ b/src/core/hle/service/nifm/nifm.h @@ -12,14 +12,9 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::NIFM { -/// Registers all NIFM services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  class IGeneralService final : public ServiceFramework<IGeneralService> {  public: diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 5a8a91e0b..aff7cc5bd 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -8,8 +8,8 @@  #include "core/hle/kernel/k_event.h"  #include "core/hle/service/kernel_helpers.h"  #include "core/hle/service/nim/nim.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::NIM { @@ -418,11 +418,14 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<NIM>(system)->InstallAsService(sm); -    std::make_shared<NIM_ECA>(system)->InstallAsService(sm); -    std::make_shared<NIM_SHP>(system)->InstallAsService(sm); -    std::make_shared<NTC>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("nim", std::make_shared<NIM>(system)); +    server_manager->RegisterNamedService("nim:eca", std::make_shared<NIM_ECA>(system)); +    server_manager->RegisterNamedService("nim:shp", std::make_shared<NIM_SHP>(system)); +    server_manager->RegisterNamedService("ntc", std::make_shared<NTC>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::NIM diff --git a/src/core/hle/service/nim/nim.h b/src/core/hle/service/nim/nim.h index 8f6ff28e8..e7d599908 100644 --- a/src/core/hle/service/nim/nim.h +++ b/src/core/hle/service/nim/nim.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::NIM { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::NIM diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp index 8133711c2..a162e5c54 100644 --- a/src/core/hle/service/npns/npns.cpp +++ b/src/core/hle/service/npns/npns.cpp @@ -4,8 +4,8 @@  #include <memory>  #include "core/hle/service/npns/npns.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::NPNS { @@ -94,9 +94,12 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<NPNS_S>(system)->InstallAsService(sm); -    std::make_shared<NPNS_U>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("npns:s", std::make_shared<NPNS_S>(system)); +    server_manager->RegisterNamedService("npns:u", std::make_shared<NPNS_U>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::NPNS diff --git a/src/core/hle/service/npns/npns.h b/src/core/hle/service/npns/npns.h index 84e6ec437..0019fca76 100644 --- a/src/core/hle/service/npns/npns.h +++ b/src/core/hle/service/npns/npns.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::NPNS { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::NPNS diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index e53bdde52..062e96ef9 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp @@ -14,6 +14,7 @@  #include "core/hle/service/ns/language.h"  #include "core/hle/service/ns/ns.h"  #include "core/hle/service/ns/pdm_qry.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/set/set.h"  namespace Service::NS { @@ -785,23 +786,26 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { - -    std::make_shared<NS>("ns:am2", system)->InstallAsService(service_manager); -    std::make_shared<NS>("ns:ec", system)->InstallAsService(service_manager); -    std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager); -    std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager); -    std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager); -    std::make_shared<NS>("ns:ro", system)->InstallAsService(service_manager); - -    std::make_shared<NS_DEV>(system)->InstallAsService(service_manager); -    std::make_shared<NS_SU>(system)->InstallAsService(service_manager); -    std::make_shared<NS_VM>(system)->InstallAsService(service_manager); - -    std::make_shared<PDM_QRY>(system)->InstallAsService(service_manager); - -    std::make_shared<IPlatformServiceManager>(system, "pl:s")->InstallAsService(service_manager); -    std::make_shared<IPlatformServiceManager>(system, "pl:u")->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("ns:am2", std::make_shared<NS>("ns:am2", system)); +    server_manager->RegisterNamedService("ns:ec", std::make_shared<NS>("ns:ec", system)); +    server_manager->RegisterNamedService("ns:rid", std::make_shared<NS>("ns:rid", system)); +    server_manager->RegisterNamedService("ns:rt", std::make_shared<NS>("ns:rt", system)); +    server_manager->RegisterNamedService("ns:web", std::make_shared<NS>("ns:web", system)); +    server_manager->RegisterNamedService("ns:ro", std::make_shared<NS>("ns:ro", system)); + +    server_manager->RegisterNamedService("ns:dev", std::make_shared<NS_DEV>(system)); +    server_manager->RegisterNamedService("ns:su", std::make_shared<NS_SU>(system)); +    server_manager->RegisterNamedService("ns:vm", std::make_shared<NS_VM>(system)); +    server_manager->RegisterNamedService("pdm:qry", std::make_shared<PDM_QRY>(system)); + +    server_manager->RegisterNamedService("pl:s", +                                         std::make_shared<IPlatformServiceManager>(system, "pl:s")); +    server_manager->RegisterNamedService("pl:u", +                                         std::make_shared<IPlatformServiceManager>(system, "pl:u")); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::NS diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h index 9c18e935c..797e69a13 100644 --- a/src/core/hle/service/ns/ns.h +++ b/src/core/hle/service/ns/ns.h @@ -117,8 +117,7 @@ private:      }  }; -/// Registers all NS services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace NS  } // namespace Service diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp index 52d27e755..a70ea9385 100644 --- a/src/core/hle/service/nvdrv/nvdrv.cpp +++ b/src/core/hle/service/nvdrv/nvdrv.cpp @@ -24,6 +24,7 @@  #include "core/hle/service/nvdrv/nvdrv_interface.h"  #include "core/hle/service/nvdrv/nvmemp.h"  #include "core/hle/service/nvflinger/nvflinger.h" +#include "core/hle/service/server_manager.h"  #include "video_core/gpu.h"  namespace Service::Nvidia { @@ -41,15 +42,19 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) {      module.service_context.CloseEvent(event);  } -void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, -                       Core::System& system) { -    auto module_ = std::make_shared<Module>(system); -    std::make_shared<NVDRV>(system, module_, "nvdrv")->InstallAsService(service_manager); -    std::make_shared<NVDRV>(system, module_, "nvdrv:a")->InstallAsService(service_manager); -    std::make_shared<NVDRV>(system, module_, "nvdrv:s")->InstallAsService(service_manager); -    std::make_shared<NVDRV>(system, module_, "nvdrv:t")->InstallAsService(service_manager); -    std::make_shared<NVMEMP>(system)->InstallAsService(service_manager); -    nvflinger.SetNVDrvInstance(module_); +void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); +    auto module = std::make_shared<Module>(system); +    server_manager->RegisterNamedService("nvdrv", std::make_shared<NVDRV>(system, module, "nvdrv")); +    server_manager->RegisterNamedService("nvdrv:a", +                                         std::make_shared<NVDRV>(system, module, "nvdrv:a")); +    server_manager->RegisterNamedService("nvdrv:s", +                                         std::make_shared<NVDRV>(system, module, "nvdrv:s")); +    server_manager->RegisterNamedService("nvdrv:t", +                                         std::make_shared<NVDRV>(system, module, "nvdrv:t")); +    server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system)); +    nvflinger.SetNVDrvInstance(module); +    ServerManager::RunServer(std::move(server_manager));  }  Module::Module(Core::System& system) diff --git a/src/core/hle/service/nvdrv/nvdrv.h b/src/core/hle/service/nvdrv/nvdrv.h index b09b6e585..b2270cf76 100644 --- a/src/core/hle/service/nvdrv/nvdrv.h +++ b/src/core/hle/service/nvdrv/nvdrv.h @@ -114,8 +114,6 @@ private:      std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;  }; -/// Registers all NVDRV services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, -                       Core::System& system); +void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system);  } // namespace Service::Nvidia diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.cpp b/src/core/hle/service/nvdrv/nvdrv_interface.cpp index edbdfee43..396fa7ed5 100644 --- a/src/core/hle/service/nvdrv/nvdrv_interface.cpp +++ b/src/core/hle/service/nvdrv/nvdrv_interface.cpp @@ -222,7 +222,7 @@ void NVDRV::DumpGraphicsMemoryInfo(Kernel::HLERequestContext& ctx) {  }  NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name) -    : ServiceFramework{system_, name, ServiceThreadType::CreateNew}, nvdrv{std::move(nvdrv_)} { +    : ServiceFramework{system_, name}, nvdrv{std::move(nvdrv_)} {      static const FunctionInfo functions[] = {          {0, &NVDRV::Open, "Open"},          {1, &NVDRV::Ioctl1, "Ioctl"}, diff --git a/src/core/hle/service/olsc/olsc.cpp b/src/core/hle/service/olsc/olsc.cpp index 530e1be3b..3493f8272 100644 --- a/src/core/hle/service/olsc/olsc.cpp +++ b/src/core/hle/service/olsc/olsc.cpp @@ -3,8 +3,8 @@  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/olsc/olsc.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::OLSC { @@ -72,8 +72,11 @@ private:      bool initialized{};  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<OLSC>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("olsc:u", std::make_shared<OLSC>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::OLSC diff --git a/src/core/hle/service/olsc/olsc.h b/src/core/hle/service/olsc/olsc.h index 1522d8d32..620b634fa 100644 --- a/src/core/hle/service/olsc/olsc.h +++ b/src/core/hle/service/olsc/olsc.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::OLSC { -/// Registers all SSL services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::OLSC diff --git a/src/core/hle/service/pcie/pcie.cpp b/src/core/hle/service/pcie/pcie.cpp index 79501b9f9..c6da6eb51 100644 --- a/src/core/hle/service/pcie/pcie.cpp +++ b/src/core/hle/service/pcie/pcie.cpp @@ -4,8 +4,8 @@  #include <memory>  #include "core/hle/service/pcie/pcie.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::PCIe { @@ -59,8 +59,11 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<PCIe>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("pcie", std::make_shared<PCIe>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::PCIe diff --git a/src/core/hle/service/pcie/pcie.h b/src/core/hle/service/pcie/pcie.h index cebfd9042..5c2d4b805 100644 --- a/src/core/hle/service/pcie/pcie.h +++ b/src/core/hle/service/pcie/pcie.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::PCIe { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::PCIe diff --git a/src/core/hle/service/pctl/pctl_module.cpp b/src/core/hle/service/pctl/pctl_module.cpp index 083609b34..a4a12a78c 100644 --- a/src/core/hle/service/pctl/pctl_module.cpp +++ b/src/core/hle/service/pctl/pctl_module.cpp @@ -8,6 +8,7 @@  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/pctl/pctl.h"  #include "core/hle/service/pctl/pctl_module.h" +#include "core/hle/service/server_manager.h"  namespace Service::PCTL { @@ -393,19 +394,22 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu  Module::Interface::~Interface() = default; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); +      auto module = std::make_shared<Module>(); -    std::make_shared<PCTL>(system, module, "pctl", -                           Capability::Application | Capability::SnsPost | Capability::Status | -                               Capability::StereoVision) -        ->InstallAsService(service_manager); +    server_manager->RegisterNamedService( +        "pctl", std::make_shared<PCTL>(system, module, "pctl", +                                       Capability::Application | Capability::SnsPost | +                                           Capability::Status | Capability::StereoVision));      // TODO(ogniK): Implement remaining capabilities -    std::make_shared<PCTL>(system, module, "pctl:a", Capability::None) -        ->InstallAsService(service_manager); -    std::make_shared<PCTL>(system, module, "pctl:r", Capability::None) -        ->InstallAsService(service_manager); -    std::make_shared<PCTL>(system, module, "pctl:s", Capability::None) -        ->InstallAsService(service_manager); +    server_manager->RegisterNamedService( +        "pctl:a", std::make_shared<PCTL>(system, module, "pctl:a", Capability::None)); +    server_manager->RegisterNamedService( +        "pctl:r", std::make_shared<PCTL>(system, module, "pctl:r", Capability::None)); +    server_manager->RegisterNamedService( +        "pctl:s", std::make_shared<PCTL>(system, module, "pctl:s", Capability::None)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::PCTL diff --git a/src/core/hle/service/pctl/pctl_module.h b/src/core/hle/service/pctl/pctl_module.h index 6f584530d..4ea77ab21 100644 --- a/src/core/hle/service/pctl/pctl_module.h +++ b/src/core/hle/service/pctl/pctl_module.h @@ -42,7 +42,6 @@ public:      };  }; -/// Registers all PCTL services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::PCTL diff --git a/src/core/hle/service/pcv/pcv.cpp b/src/core/hle/service/pcv/pcv.cpp index 98037a8d4..be64b94ea 100644 --- a/src/core/hle/service/pcv/pcv.cpp +++ b/src/core/hle/service/pcv/pcv.cpp @@ -5,8 +5,8 @@  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/pcv/pcv.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::PCV { @@ -141,11 +141,14 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<PCV>(system)->InstallAsService(sm); -    std::make_shared<CLKRST>(system, "clkrst")->InstallAsService(sm); -    std::make_shared<CLKRST>(system, "clkrst:i")->InstallAsService(sm); -    std::make_shared<CLKRST_A>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("pcv", std::make_shared<PCV>(system)); +    server_manager->RegisterNamedService("clkrst", std::make_shared<CLKRST>(system, "clkrst")); +    server_manager->RegisterNamedService("clkrst:i", std::make_shared<CLKRST>(system, "clkrst:i")); +    server_manager->RegisterNamedService("clkrst:a", std::make_shared<CLKRST_A>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::PCV diff --git a/src/core/hle/service/pcv/pcv.h b/src/core/hle/service/pcv/pcv.h index 6b26b6fa7..bf541e6fe 100644 --- a/src/core/hle/service/pcv/pcv.h +++ b/src/core/hle/service/pcv/pcv.h @@ -7,10 +7,6 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::PCV {  enum class DeviceCode : u32 { @@ -104,6 +100,6 @@ enum class DeviceCode : u32 {      OscClk = 0x40000080  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::PCV diff --git a/src/core/hle/service/pm/pm.cpp b/src/core/hle/service/pm/pm.cpp index b10e86c8f..02a4ca13b 100644 --- a/src/core/hle/service/pm/pm.cpp +++ b/src/core/hle/service/pm/pm.cpp @@ -6,6 +6,7 @@  #include "core/hle/kernel/k_process.h"  #include "core/hle/kernel/kernel.h"  #include "core/hle/service/pm/pm.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  namespace Service::PM { @@ -262,12 +263,15 @@ private:      const Kernel::KernelCore& kernel;  }; -void InstallInterfaces(Core::System& system) { -    std::make_shared<BootMode>(system)->InstallAsService(system.ServiceManager()); -    std::make_shared<DebugMonitor>(system)->InstallAsService(system.ServiceManager()); -    std::make_shared<Info>(system, system.Kernel().GetProcessList()) -        ->InstallAsService(system.ServiceManager()); -    std::make_shared<Shell>(system)->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("pm:bm", std::make_shared<BootMode>(system)); +    server_manager->RegisterNamedService("pm:dmnt", std::make_shared<DebugMonitor>(system)); +    server_manager->RegisterNamedService( +        "pm:info", std::make_shared<Info>(system, system.Kernel().GetProcessList())); +    server_manager->RegisterNamedService("pm:shell", std::make_shared<Shell>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::PM diff --git a/src/core/hle/service/pm/pm.h b/src/core/hle/service/pm/pm.h index 060103928..5d4a1a171 100644 --- a/src/core/hle/service/pm/pm.h +++ b/src/core/hle/service/pm/pm.h @@ -14,7 +14,6 @@ enum class SystemBootMode {      Maintenance,  }; -/// Registers all PM services with the specified service manager. -void InstallInterfaces(Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::PM diff --git a/src/core/hle/service/prepo/prepo.cpp b/src/core/hle/service/prepo/prepo.cpp index 90c5f8756..02af311e8 100644 --- a/src/core/hle/service/prepo/prepo.cpp +++ b/src/core/hle/service/prepo/prepo.cpp @@ -7,6 +7,7 @@  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/acc/profile_manager.h"  #include "core/hle/service/prepo/prepo.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  #include "core/reporter.h" @@ -183,12 +184,20 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<PlayReport>("prepo:a", system)->InstallAsService(service_manager); -    std::make_shared<PlayReport>("prepo:a2", system)->InstallAsService(service_manager); -    std::make_shared<PlayReport>("prepo:m", system)->InstallAsService(service_manager); -    std::make_shared<PlayReport>("prepo:s", system)->InstallAsService(service_manager); -    std::make_shared<PlayReport>("prepo:u", system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("prepo:a", +                                         std::make_shared<PlayReport>("prepo:a", system)); +    server_manager->RegisterNamedService("prepo:a2", +                                         std::make_shared<PlayReport>("prepo:a2", system)); +    server_manager->RegisterNamedService("prepo:m", +                                         std::make_shared<PlayReport>("prepo:m", system)); +    server_manager->RegisterNamedService("prepo:s", +                                         std::make_shared<PlayReport>("prepo:s", system)); +    server_manager->RegisterNamedService("prepo:u", +                                         std::make_shared<PlayReport>("prepo:u", system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::PlayReport diff --git a/src/core/hle/service/prepo/prepo.h b/src/core/hle/service/prepo/prepo.h index 37ea5afad..2c2462f93 100644 --- a/src/core/hle/service/prepo/prepo.h +++ b/src/core/hle/service/prepo/prepo.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::PlayReport { -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::PlayReport diff --git a/src/core/hle/service/psc/psc.cpp b/src/core/hle/service/psc/psc.cpp index 3a9412cf5..1650d2f39 100644 --- a/src/core/hle/service/psc/psc.cpp +++ b/src/core/hle/service/psc/psc.cpp @@ -6,8 +6,8 @@  #include "common/logging/log.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/service/psc/psc.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  namespace Service::PSC { @@ -71,9 +71,12 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<PSC_C>(system)->InstallAsService(sm); -    std::make_shared<PSC_M>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("psc:c", std::make_shared<PSC_C>(system)); +    server_manager->RegisterNamedService("psc:m", std::make_shared<PSC_M>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::PSC diff --git a/src/core/hle/service/psc/psc.h b/src/core/hle/service/psc/psc.h index d248372c2..459137f42 100644 --- a/src/core/hle/service/psc/psc.h +++ b/src/core/hle/service/psc/psc.h @@ -13,6 +13,6 @@ class ServiceManager;  namespace Service::PSC { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::PSC diff --git a/src/core/hle/service/ptm/ptm.cpp b/src/core/hle/service/ptm/ptm.cpp index 4bea995c6..6f0cfe04b 100644 --- a/src/core/hle/service/ptm/ptm.cpp +++ b/src/core/hle/service/ptm/ptm.cpp @@ -7,12 +7,16 @@  #include "core/hle/service/ptm/psm.h"  #include "core/hle/service/ptm/ptm.h"  #include "core/hle/service/ptm/ts.h" +#include "core/hle/service/server_manager.h"  namespace Service::PTM { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<PSM>(system)->InstallAsService(sm); -    std::make_shared<TS>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("psm", std::make_shared<PSM>(system)); +    server_manager->RegisterNamedService("ts", std::make_shared<TS>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::PTM diff --git a/src/core/hle/service/ptm/ptm.h b/src/core/hle/service/ptm/ptm.h index 06224a24e..a0ae03d28 100644 --- a/src/core/hle/service/ptm/ptm.h +++ b/src/core/hle/service/ptm/ptm.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::PTM { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::PTM diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp new file mode 100644 index 000000000..1b3db3caf --- /dev/null +++ b/src/core/hle/service/server_manager.cpp @@ -0,0 +1,448 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/scope_exit.h" + +#include "core/core.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/k_client_port.h" +#include "core/hle/kernel/k_client_session.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/kernel/k_object_name.h" +#include "core/hle/kernel/k_port.h" +#include "core/hle/kernel/k_server_port.h" +#include "core/hle/kernel/k_server_session.h" +#include "core/hle/kernel/k_synchronization_object.h" +#include "core/hle/kernel/svc_results.h" +#include "core/hle/service/server_manager.h" +#include "core/hle/service/sm/sm.h" + +namespace Service { + +constexpr size_t MaximumWaitObjects = 0x40; + +enum HandleType { +    Port, +    Session, +    DeferEvent, +    Event, +}; + +ServerManager::ServerManager(Core::System& system) : m_system{system}, m_serve_mutex{system} { +    // Initialize event. +    m_event = Kernel::KEvent::Create(system.Kernel()); +    m_event->Initialize(nullptr); +} + +ServerManager::~ServerManager() { +    // Signal stop. +    m_stop_source.request_stop(); +    m_event->Signal(); + +    // Wait for processing to stop. +    m_stopped.wait(false); +    m_threads.clear(); + +    // Clean up ports. +    for (const auto& [port, handler] : m_ports) { +        port->Close(); +    } + +    // Clean up sessions. +    for (const auto& [session, manager] : m_sessions) { +        session->Close(); +    } + +    for (const auto& request : m_deferrals) { +        request.session->Close(); +    } + +    // Close event. +    m_event->GetReadableEvent().Close(); +    m_event->Close(); + +    if (m_deferral_event) { +        m_deferral_event->GetReadableEvent().Close(); +        // Write event is owned by ServiceManager +    } +} + +void ServerManager::RunServer(std::unique_ptr<ServerManager>&& server_manager) { +    server_manager->m_system.RunServer(std::move(server_manager)); +} + +Result ServerManager::RegisterSession(Kernel::KServerSession* session, +                                      std::shared_ptr<Kernel::SessionRequestManager> manager) { +    ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); + +    // We are taking ownership of the server session, so don't open it. +    // Begin tracking the server session. +    { +        std::scoped_lock ll{m_list_mutex}; +        m_sessions.emplace(session, std::move(manager)); +    } + +    // Signal the wakeup event. +    m_event->Signal(); + +    R_SUCCEED(); +} + +Result ServerManager::RegisterNamedService(const std::string& service_name, +                                           std::shared_ptr<Kernel::SessionRequestHandler>&& handler, +                                           u32 max_sessions) { +    ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); + +    // Add the new server to sm:. +    ASSERT(R_SUCCEEDED( +        m_system.ServiceManager().RegisterService(service_name, max_sessions, handler))); + +    // Get the registered port. +    auto port = m_system.ServiceManager().GetServicePort(service_name); +    ASSERT(port.Succeeded()); + +    // Open a new reference to the server port. +    (*port)->GetServerPort().Open(); + +    // Begin tracking the server port. +    { +        std::scoped_lock ll{m_list_mutex}; +        m_ports.emplace(std::addressof((*port)->GetServerPort()), std::move(handler)); +    } + +    // Signal the wakeup event. +    m_event->Signal(); + +    R_SUCCEED(); +} + +Result ServerManager::ManageNamedPort(const std::string& service_name, +                                      std::shared_ptr<Kernel::SessionRequestHandler>&& handler, +                                      u32 max_sessions) { +    ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects); + +    // Create a new port. +    auto* port = Kernel::KPort::Create(m_system.Kernel()); +    port->Initialize(max_sessions, false, service_name); + +    // Register the port. +    Kernel::KPort::Register(m_system.Kernel(), port); + +    // Ensure that our reference to the port is closed if we fail to register it. +    SCOPE_EXIT({ +        port->GetClientPort().Close(); +        port->GetServerPort().Close(); +    }); + +    // Register the object name with the kernel. +    R_TRY(Kernel::KObjectName::NewFromName(m_system.Kernel(), std::addressof(port->GetClientPort()), +                                           service_name.c_str())); + +    // Open a new reference to the server port. +    port->GetServerPort().Open(); + +    // Begin tracking the server port. +    { +        std::scoped_lock ll{m_list_mutex}; +        m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler)); +    } + +    // We succeeded. +    R_SUCCEED(); +} + +Result ServerManager::ManageDeferral(Kernel::KEvent** out_event) { +    // Create a new event. +    m_deferral_event = Kernel::KEvent::Create(m_system.Kernel()); +    ASSERT(m_deferral_event != nullptr); + +    // Initialize the event. +    m_deferral_event->Initialize(nullptr); + +    // Set the output. +    *out_event = m_deferral_event; + +    // We succeeded. +    R_SUCCEED(); +} + +void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_threads) { +    for (size_t i = 0; i < num_threads; i++) { +        auto thread_name = fmt::format("{}:{}", name, i + 1); +        m_threads.emplace_back(m_system.Kernel().RunOnHostCoreThread( +            std::move(thread_name), [&] { this->LoopProcessImpl(); })); +    } +} + +Result ServerManager::LoopProcess() { +    SCOPE_EXIT({ +        m_stopped.store(true); +        m_stopped.notify_all(); +    }); + +    R_RETURN(this->LoopProcessImpl()); +} + +Result ServerManager::LoopProcessImpl() { +    while (!m_stop_source.stop_requested()) { +        R_TRY(this->WaitAndProcessImpl()); +    } + +    R_SUCCEED(); +} + +Result ServerManager::WaitAndProcessImpl() { +    Kernel::KScopedAutoObject<Kernel::KSynchronizationObject> wait_obj; +    HandleType wait_type{}; + +    // Ensure we are the only thread waiting for this server. +    std::unique_lock sl{m_serve_mutex}; + +    // If we're done, return before we start waiting. +    R_SUCCEED_IF(m_stop_source.stop_requested()); + +    // Wait for a tracked object to become signaled. +    { +        s32 num_objs{}; +        std::array<HandleType, MaximumWaitObjects> wait_types{}; +        std::array<Kernel::KSynchronizationObject*, MaximumWaitObjects> wait_objs{}; + +        const auto AddWaiter{ +            [&](Kernel::KSynchronizationObject* synchronization_object, HandleType type) { +                // Open a new reference to the object. +                synchronization_object->Open(); + +                // Insert into the list. +                wait_types[num_objs] = type; +                wait_objs[num_objs++] = synchronization_object; +            }}; + +        { +            std::scoped_lock ll{m_list_mutex}; + +            // Add all of our ports. +            for (const auto& [port, handler] : m_ports) { +                AddWaiter(port, HandleType::Port); +            } + +            // Add all of our sessions. +            for (const auto& [session, manager] : m_sessions) { +                AddWaiter(session, HandleType::Session); +            } +        } + +        // Add the deferral wakeup event. +        if (m_deferral_event != nullptr) { +            AddWaiter(std::addressof(m_deferral_event->GetReadableEvent()), HandleType::DeferEvent); +        } + +        // Add the wakeup event. +        AddWaiter(std::addressof(m_event->GetReadableEvent()), HandleType::Event); + +        // Clean up extra references on exit. +        SCOPE_EXIT({ +            for (s32 i = 0; i < num_objs; i++) { +                wait_objs[i]->Close(); +            } +        }); + +        // Wait for a signal. +        s32 out_index{-1}; +        R_TRY(Kernel::KSynchronizationObject::Wait(m_system.Kernel(), &out_index, wait_objs.data(), +                                                   num_objs, -1)); +        ASSERT(out_index >= 0 && out_index < num_objs); + +        // Set the output index. +        wait_obj = wait_objs[out_index]; +        wait_type = wait_types[out_index]; +    } + +    // Process what we just received, temporarily removing the object so it is +    // not processed concurrently by another thread. +    { +        switch (wait_type) { +        case HandleType::Port: { +            // Port signaled. +            auto* port = wait_obj->DynamicCast<Kernel::KServerPort*>(); +            std::shared_ptr<Kernel::SessionRequestHandler> handler; + +            // Remove from tracking. +            { +                std::scoped_lock ll{m_list_mutex}; +                ASSERT(m_ports.contains(port)); +                m_ports.at(port).swap(handler); +                m_ports.erase(port); +            } + +            // Allow other threads to serve. +            sl.unlock(); + +            // Finish. +            R_RETURN(this->OnPortEvent(port, std::move(handler))); +        } +        case HandleType::Session: { +            // Session signaled. +            auto* session = wait_obj->DynamicCast<Kernel::KServerSession*>(); +            std::shared_ptr<Kernel::SessionRequestManager> manager; + +            // Remove from tracking. +            { +                std::scoped_lock ll{m_list_mutex}; +                ASSERT(m_sessions.contains(session)); +                m_sessions.at(session).swap(manager); +                m_sessions.erase(session); +            } + +            // Allow other threads to serve. +            sl.unlock(); + +            // Finish. +            R_RETURN(this->OnSessionEvent(session, std::move(manager))); +        } +        case HandleType::DeferEvent: { +            // Clear event. +            ASSERT(R_SUCCEEDED(m_deferral_event->Clear())); + +            // Drain the list of deferrals while we process. +            std::list<RequestState> deferrals; +            { +                std::scoped_lock ll{m_list_mutex}; +                m_deferrals.swap(deferrals); +            } + +            // Allow other threads to serve. +            sl.unlock(); + +            // Finish. +            R_RETURN(this->OnDeferralEvent(std::move(deferrals))); +        } +        case HandleType::Event: { +            // Clear event and finish. +            R_RETURN(m_event->Clear()); +        } +        default: { +            UNREACHABLE(); +        } +        } +    } +} + +Result ServerManager::OnPortEvent(Kernel::KServerPort* port, +                                  std::shared_ptr<Kernel::SessionRequestHandler>&& handler) { +    // Accept a new server session. +    Kernel::KServerSession* session = port->AcceptSession(); +    ASSERT(session != nullptr); + +    // Create the session manager and install the handler. +    auto manager = std::make_shared<Kernel::SessionRequestManager>(m_system.Kernel(), *this); +    manager->SetSessionHandler(std::shared_ptr(handler)); + +    // Track the server session. +    { +        std::scoped_lock ll{m_list_mutex}; +        m_ports.emplace(port, std::move(handler)); +        m_sessions.emplace(session, std::move(manager)); +    } + +    // Signal the wakeup event. +    m_event->Signal(); + +    // We succeeded. +    R_SUCCEED(); +} + +Result ServerManager::OnSessionEvent(Kernel::KServerSession* session, +                                     std::shared_ptr<Kernel::SessionRequestManager>&& manager) { +    Result rc{ResultSuccess}; + +    // Try to receive a message. +    std::shared_ptr<Kernel::HLERequestContext> context; +    rc = session->ReceiveRequest(&context, manager); + +    // If the session has been closed, we're done. +    if (rc == Kernel::ResultSessionClosed) { +        // Close the session. +        session->Close(); + +        // Finish. +        R_SUCCEED(); +    } +    ASSERT(R_SUCCEEDED(rc)); + +    RequestState request{ +        .session = session, +        .context = std::move(context), +        .manager = std::move(manager), +    }; + +    // Complete the sync request with deferral handling. +    R_RETURN(this->CompleteSyncRequest(std::move(request))); +} + +Result ServerManager::CompleteSyncRequest(RequestState&& request) { +    Result rc{ResultSuccess}; +    Result service_rc{ResultSuccess}; + +    // Mark the request as not deferred. +    request.context->SetIsDeferred(false); + +    // Complete the request. We have exclusive access to this session. +    service_rc = request.manager->CompleteSyncRequest(request.session, *request.context); + +    // If we've been deferred, we're done. +    if (request.context->GetIsDeferred()) { +        // Insert into deferral list. +        std::scoped_lock ll{m_list_mutex}; +        m_deferrals.emplace_back(std::move(request)); + +        // Finish. +        R_SUCCEED(); +    } + +    // Send the reply. +    rc = request.session->SendReplyHLE(); + +    // If the session has been closed, we're done. +    if (rc == Kernel::ResultSessionClosed || service_rc == IPC::ERR_REMOTE_PROCESS_DEAD) { +        // Close the session. +        request.session->Close(); + +        // Finish. +        R_SUCCEED(); +    } + +    ASSERT(R_SUCCEEDED(rc)); +    ASSERT(R_SUCCEEDED(service_rc)); + +    // Reinsert the session. +    { +        std::scoped_lock ll{m_list_mutex}; +        m_sessions.emplace(request.session, std::move(request.manager)); +    } + +    // Signal the wakeup event. +    m_event->Signal(); + +    // We succeeded. +    R_SUCCEED(); +} + +Result ServerManager::OnDeferralEvent(std::list<RequestState>&& deferrals) { +    ON_RESULT_FAILURE { +        std::scoped_lock ll{m_list_mutex}; +        m_deferrals.splice(m_deferrals.end(), deferrals); +    }; + +    while (!deferrals.empty()) { +        RequestState request = deferrals.front(); +        deferrals.pop_front(); + +        // Try again to complete the request. +        R_TRY(this->CompleteSyncRequest(std::move(request))); +    } + +    R_SUCCEED(); +} + +} // namespace Service diff --git a/src/core/hle/service/server_manager.h b/src/core/hle/service/server_manager.h new file mode 100644 index 000000000..57b954ae8 --- /dev/null +++ b/src/core/hle/service/server_manager.h @@ -0,0 +1,91 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <atomic> +#include <functional> +#include <list> +#include <map> +#include <mutex> +#include <string_view> +#include <vector> + +#include "common/polyfill_thread.h" +#include "core/hle/result.h" +#include "core/hle/service/mutex.h" + +namespace Core { +class System; +} + +namespace Kernel { +class HLERequestContext; +class KEvent; +class KServerPort; +class KServerSession; +class KSynchronizationObject; +class SessionRequestHandler; +class SessionRequestManager; +} // namespace Kernel + +namespace Service { + +class ServerManager { +public: +    explicit ServerManager(Core::System& system); +    ~ServerManager(); + +    Result RegisterSession(Kernel::KServerSession* session, +                           std::shared_ptr<Kernel::SessionRequestManager> manager); +    Result RegisterNamedService(const std::string& service_name, +                                std::shared_ptr<Kernel::SessionRequestHandler>&& handler, +                                u32 max_sessions = 64); +    Result ManageNamedPort(const std::string& service_name, +                           std::shared_ptr<Kernel::SessionRequestHandler>&& handler, +                           u32 max_sessions = 64); +    Result ManageDeferral(Kernel::KEvent** out_event); + +    Result LoopProcess(); +    void StartAdditionalHostThreads(const char* name, size_t num_threads); + +    static void RunServer(std::unique_ptr<ServerManager>&& server); + +private: +    struct RequestState; + +    Result LoopProcessImpl(); +    Result WaitAndProcessImpl(); +    Result OnPortEvent(Kernel::KServerPort* port, +                       std::shared_ptr<Kernel::SessionRequestHandler>&& handler); +    Result OnSessionEvent(Kernel::KServerSession* session, +                          std::shared_ptr<Kernel::SessionRequestManager>&& manager); +    Result OnDeferralEvent(std::list<RequestState>&& deferrals); +    Result CompleteSyncRequest(RequestState&& state); + +private: +    Core::System& m_system; +    Mutex m_serve_mutex; +    std::mutex m_list_mutex; + +    // Guest state tracking +    std::map<Kernel::KServerPort*, std::shared_ptr<Kernel::SessionRequestHandler>> m_ports{}; +    std::map<Kernel::KServerSession*, std::shared_ptr<Kernel::SessionRequestManager>> m_sessions{}; +    Kernel::KEvent* m_event{}; +    Kernel::KEvent* m_deferral_event{}; + +    // Deferral tracking +    struct RequestState { +        Kernel::KServerSession* session; +        std::shared_ptr<Kernel::HLERequestContext> context; +        std::shared_ptr<Kernel::SessionRequestManager> manager; +    }; +    std::list<RequestState> m_deferrals{}; + +    // Host state tracking +    std::atomic<bool> m_stopped{}; +    std::vector<std::jthread> m_threads{}; +    std::stop_source m_stop_source{}; +}; + +} // namespace Service diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 1ffc1c694..31021ea03 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -90,44 +90,13 @@ namespace Service {  }  ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_, -                                           ServiceThreadType thread_type, u32 max_sessions_, -                                           InvokerFn* handler_invoker_) -    : SessionRequestHandler(system_.Kernel(), service_name_, thread_type), system{system_}, +                                           u32 max_sessions_, InvokerFn* handler_invoker_) +    : SessionRequestHandler(system_.Kernel(), service_name_), system{system_},        service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {}  ServiceFrameworkBase::~ServiceFrameworkBase() {      // Wait for other threads to release access before destroying      const auto guard = LockService(); - -    if (named_port != nullptr) { -        named_port->GetClientPort().Close(); -        named_port->GetServerPort().Close(); -        named_port = nullptr; -    } -} - -void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) { -    const auto guard = LockService(); - -    ASSERT(!service_registered); - -    service_manager.RegisterService(service_name, max_sessions, shared_from_this()); -    service_registered = true; -} - -Kernel::KClientPort& ServiceFrameworkBase::CreatePort() { -    const auto guard = LockService(); - -    if (named_port == nullptr) { -        ASSERT(!service_registered); - -        named_port = Kernel::KPort::Create(kernel); -        named_port->Initialize(max_sessions, false, service_name); - -        service_registered = true; -    } - -    return named_port->GetClientPort();  }  void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { @@ -244,67 +213,69 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system      : hos_binder_driver_server{std::make_unique<NVFlinger::HosBinderDriverServer>(system)},        nv_flinger{std::make_unique<NVFlinger::NVFlinger>(system, *hos_binder_driver_server)} { +    auto& kernel = system.Kernel(); +      // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it      // here and pass it into the respective InstallInterfaces functions. -      system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); -    system.Kernel().RegisterNamedService("sm:", SM::ServiceManager::InterfaceFactory); -    system.Kernel().RegisterInterfaceForNamedService("sm:", SM::ServiceManager::SessionHandler); - -    Account::InstallInterfaces(system); -    AM::InstallInterfaces(*sm, *nv_flinger, system); -    AOC::InstallInterfaces(*sm, system); -    APM::InstallInterfaces(system); -    Audio::InstallInterfaces(*sm, system); -    BCAT::InstallInterfaces(system); -    BPC::InstallInterfaces(*sm, system); -    BtDrv::InstallInterfaces(*sm, system); -    BTM::InstallInterfaces(*sm, system); -    Capture::InstallInterfaces(*sm, system); -    ERPT::InstallInterfaces(*sm, system); -    ES::InstallInterfaces(*sm, system); -    EUPLD::InstallInterfaces(*sm, system); -    Fatal::InstallInterfaces(*sm, system); -    FGM::InstallInterfaces(*sm, system); -    FileSystem::InstallInterfaces(system); -    Friend::InstallInterfaces(*sm, system); -    Glue::InstallInterfaces(system); -    GRC::InstallInterfaces(*sm, system); -    HID::InstallInterfaces(*sm, system); -    JIT::InstallInterfaces(*sm, system); -    LBL::InstallInterfaces(*sm, system); -    LDN::InstallInterfaces(*sm, system); -    LDR::InstallInterfaces(*sm, system); -    LM::InstallInterfaces(system); -    Migration::InstallInterfaces(*sm, system); -    Mii::InstallInterfaces(*sm, system); -    MM::InstallInterfaces(*sm, system); -    MNPP::InstallInterfaces(*sm, system); -    NCM::InstallInterfaces(*sm, system); -    NFC::InstallInterfaces(*sm, system); -    NFP::InstallInterfaces(*sm, system); -    NGCT::InstallInterfaces(*sm, system); -    NIFM::InstallInterfaces(*sm, system); -    NIM::InstallInterfaces(*sm, system); -    NPNS::InstallInterfaces(*sm, system); -    NS::InstallInterfaces(*sm, system); -    Nvidia::InstallInterfaces(*sm, *nv_flinger, system); -    OLSC::InstallInterfaces(*sm, system); -    PCIe::InstallInterfaces(*sm, system); -    PCTL::InstallInterfaces(*sm, system); -    PCV::InstallInterfaces(*sm, system); -    PlayReport::InstallInterfaces(*sm, system); -    PM::InstallInterfaces(system); -    PSC::InstallInterfaces(*sm, system); -    PTM::InstallInterfaces(*sm, system); -    Set::InstallInterfaces(*sm, system); -    Sockets::InstallInterfaces(*sm, system); -    SPL::InstallInterfaces(*sm, system); -    SSL::InstallInterfaces(*sm, system); -    Time::InstallInterfaces(system); -    USB::InstallInterfaces(*sm, system); -    VI::InstallInterfaces(*sm, system, *nv_flinger, *hos_binder_driver_server); +    // clang-format off +    kernel.RunOnHostCoreProcess("audio",      [&] { Audio::LoopProcess(system); }).detach(); +    kernel.RunOnHostCoreProcess("FS",         [&] { FileSystem::LoopProcess(system); }).detach(); +    kernel.RunOnHostCoreProcess("jit",        [&] { JIT::LoopProcess(system); }).detach(); +    kernel.RunOnHostCoreProcess("ldn",        [&] { LDN::LoopProcess(system); }).detach(); +    kernel.RunOnHostCoreProcess("Loader",     [&] { LDR::LoopProcess(system); }).detach(); +    kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(*nv_flinger, system); }).detach(); +    kernel.RunOnHostCoreProcess("bsdsocket",  [&] { Sockets::LoopProcess(system); }).detach(); +    kernel.RunOnHostCoreProcess("vi",         [&] { VI::LoopProcess(system, *nv_flinger, *hos_binder_driver_server); }).detach(); + +    kernel.RunOnGuestCoreProcess("sm",         [&] { SM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("account",    [&] { Account::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("am",         [&] { AM::LoopProcess(*nv_flinger, system); }); +    kernel.RunOnGuestCoreProcess("aoc",        [&] { AOC::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("apm",        [&] { APM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("bcat",       [&] { BCAT::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("bpc",        [&] { BPC::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("btdrv",      [&] { BtDrv::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("btm",        [&] { BTM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("capsrv",     [&] { Capture::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("erpt",       [&] { ERPT::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("es",         [&] { ES::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("eupld",      [&] { EUPLD::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("fatal",      [&] { Fatal::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("fgm",        [&] { FGM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("friends",    [&] { Friend::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("glue",       [&] { Glue::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("grc",        [&] { GRC::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("hid",        [&] { HID::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("lbl",        [&] { LBL::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("LogManager.Prod", [&] { LM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("mig",        [&] { Migration::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("mii",        [&] { Mii::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("mm",         [&] { MM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("mnpp",       [&] { MNPP::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("NCM",        [&] { NCM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("nfc",        [&] { NFC::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("nfp",        [&] { NFP::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("ngct",       [&] { NGCT::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("nifm",       [&] { NIFM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("nim",        [&] { NIM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("npns",       [&] { NPNS::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("ns",         [&] { NS::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("olsc",       [&] { OLSC::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("pcie",       [&] { PCIe::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("pctl",       [&] { PCTL::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("pcv",        [&] { PCV::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("prepo",      [&] { PlayReport::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("ProcessManager", [&] { PM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("psc",        [&] { PSC::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("ptm",        [&] { PTM::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("settings",   [&] { Set::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("spl",        [&] { SPL::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("ssl",        [&] { SSL::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("time",       [&] { Time::LoopProcess(system); }); +    kernel.RunOnGuestCoreProcess("usb",        [&] { USB::LoopProcess(system); }); +    // clang-format on  }  Services::~Services() = default; diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 22e2119d7..db3b31378 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -19,8 +19,6 @@ class System;  namespace Kernel {  class HLERequestContext; -class KClientPort; -class KPort;  class KServerSession;  class ServiceThread;  } // namespace Kernel @@ -67,18 +65,12 @@ public:          return max_sessions;      } -    /// Creates a port pair and registers this service with the given ServiceManager. -    void InstallAsService(SM::ServiceManager& service_manager); -      /// Invokes a service request routine using the HIPC protocol.      void InvokeRequest(Kernel::HLERequestContext& ctx);      /// Invokes a service request routine using the HIPC protocol.      void InvokeRequestTipc(Kernel::HLERequestContext& ctx); -    /// Creates a port pair and registers it on the kernel's global port registry. -    Kernel::KClientPort& CreatePort(); -      /// Handles a synchronization request for the service.      Result HandleSyncRequest(Kernel::KServerSession& session,                               Kernel::HLERequestContext& context) override; @@ -99,9 +91,6 @@ protected:      /// Identifier string used to connect to the service.      std::string service_name; -    /// Port used by ManageNamedPort. -    Kernel::KPort* named_port{}; -  private:      template <typename T>      friend class ServiceFramework; @@ -116,8 +105,7 @@ private:                             Kernel::HLERequestContext& ctx);      explicit ServiceFrameworkBase(Core::System& system_, const char* service_name_, -                                  ServiceThreadType thread_type, u32 max_sessions_, -                                  InvokerFn* handler_invoker_); +                                  u32 max_sessions_, InvokerFn* handler_invoker_);      ~ServiceFrameworkBase() override;      void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n); @@ -181,15 +169,12 @@ protected:       *       * @param system_ The system context to construct this service under.       * @param service_name_ Name of the service. -     * @param thread_type Specifies the thread type for this service. If this is set to CreateNew, -     *                    it creates a new thread for it, otherwise this uses the default thread.       * @param max_sessions_ Maximum number of sessions that can be connected to this service at the       * same time.       */      explicit ServiceFramework(Core::System& system_, const char* service_name_, -                              ServiceThreadType thread_type = ServiceThreadType::Default,                                u32 max_sessions_ = ServerSessionCountMax) -        : ServiceFrameworkBase(system_, service_name_, thread_type, max_sessions_, Invoker) {} +        : ServiceFrameworkBase(system_, service_name_, max_sessions_, Invoker) {}      /// Registers handlers in the service.      template <std::size_t N> diff --git a/src/core/hle/service/set/settings.cpp b/src/core/hle/service/set/settings.cpp index 4ebc2a0ec..c48844f77 100644 --- a/src/core/hle/service/set/settings.cpp +++ b/src/core/hle/service/set/settings.cpp @@ -1,20 +1,23 @@  // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project  // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/hle/service/server_manager.h"  #include "core/hle/service/set/set.h"  #include "core/hle/service/set/set_cal.h"  #include "core/hle/service/set/set_fd.h"  #include "core/hle/service/set/set_sys.h"  #include "core/hle/service/set/settings.h" -#include "core/hle/service/sm/sm.h"  namespace Service::Set { -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<SET>(system)->InstallAsService(service_manager); -    std::make_shared<SET_CAL>(system)->InstallAsService(service_manager); -    std::make_shared<SET_FD>(system)->InstallAsService(service_manager); -    std::make_shared<SET_SYS>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("set", std::make_shared<SET>(system)); +    server_manager->RegisterNamedService("set:cal", std::make_shared<SET_CAL>(system)); +    server_manager->RegisterNamedService("set:fd", std::make_shared<SET_FD>(system)); +    server_manager->RegisterNamedService("set:sys", std::make_shared<SET_SYS>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Set diff --git a/src/core/hle/service/set/settings.h b/src/core/hle/service/set/settings.h index 6cd7d634c..03cd4bb66 100644 --- a/src/core/hle/service/set/settings.h +++ b/src/core/hle/service/set/settings.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::Set { -/// Registers all Settings services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Set diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 84720094f..53c877836 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -12,6 +12,7 @@  #include "core/hle/kernel/k_scoped_resource_reservation.h"  #include "core/hle/kernel/k_server_port.h"  #include "core/hle/result.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/sm/sm.h"  #include "core/hle/service/sm/sm_controller.h" @@ -22,13 +23,19 @@ constexpr Result ERR_ALREADY_REGISTERED(ErrorModule::SM, 4);  constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6);  constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); -ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} +ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} { +    controller_interface = std::make_unique<Controller>(kernel.System()); +}  ServiceManager::~ServiceManager() {      for (auto& [name, port] : service_ports) {          port->GetClientPort().Close();          port->GetServerPort().Close();      } + +    if (deferral_event) { +        deferral_event->Close(); +    }  }  void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { @@ -43,21 +50,12 @@ static Result ValidateServiceName(const std::string& name) {      return ResultSuccess;  } -Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core::System& system) { -    self.sm_interface = std::make_shared<SM>(self, system); -    self.controller_interface = std::make_unique<Controller>(system); -    return self.sm_interface->CreatePort(); -} - -void ServiceManager::SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port) { -    self.sm_interface->AcceptSession(server_port); -} -  Result ServiceManager::RegisterService(std::string name, u32 max_sessions,                                         Kernel::SessionRequestHandlerPtr handler) {      CASCADE_CODE(ValidateServiceName(name)); +    std::scoped_lock lk{lock};      if (registered_services.find(name) != registered_services.end()) {          LOG_ERROR(Service_SM, "Service is already registered! service={}", name);          return ERR_ALREADY_REGISTERED; @@ -68,6 +66,9 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,      service_ports.emplace(name, port);      registered_services.emplace(name, handler); +    if (deferral_event) { +        deferral_event->Signal(); +    }      return ResultSuccess;  } @@ -75,6 +76,7 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,  Result ServiceManager::UnregisterService(const std::string& name) {      CASCADE_CODE(ValidateServiceName(name)); +    std::scoped_lock lk{lock};      const auto iter = registered_services.find(name);      if (iter == registered_services.end()) {          LOG_ERROR(Service_SM, "Server is not registered! service={}", name); @@ -89,9 +91,11 @@ Result ServiceManager::UnregisterService(const std::string& name) {  ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) {      CASCADE_CODE(ValidateServiceName(name)); + +    std::scoped_lock lk{lock};      auto it = service_ports.find(name);      if (it == service_ports.end()) { -        LOG_ERROR(Service_SM, "Server is not registered! service={}", name); +        LOG_WARNING(Service_SM, "Server is not registered! service={}", name);          return ERR_SERVICE_NOT_REGISTERED;      } @@ -108,7 +112,7 @@ ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name  void SM::Initialize(Kernel::HLERequestContext& ctx) {      LOG_DEBUG(Service_SM, "called"); -    is_initialized = true; +    ctx.GetManager()->SetIsInitializedForSm();      IPC::ResponseBuilder rb{ctx, 2};      rb.Push(ResultSuccess); @@ -116,6 +120,11 @@ void SM::Initialize(Kernel::HLERequestContext& ctx) {  void SM::GetService(Kernel::HLERequestContext& ctx) {      auto result = GetServiceImpl(ctx); +    if (ctx.GetIsDeferred()) { +        // Don't overwrite the command buffer. +        return; +    } +      if (result.Succeeded()) {          IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};          rb.Push(result.Code()); @@ -128,6 +137,11 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {  void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) {      auto result = GetServiceImpl(ctx); +    if (ctx.GetIsDeferred()) { +        // Don't overwrite the command buffer. +        return; +    } +      IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};      rb.Push(result.Code());      rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr); @@ -145,7 +159,7 @@ static std::string PopServiceName(IPC::RequestParser& rp) {  }  ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& ctx) { -    if (!is_initialized) { +    if (!ctx.GetManager()->GetIsInitializedForSm()) {          return ERR_NOT_INITIALIZED;      } @@ -154,10 +168,15 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&      // Find the named port.      auto port_result = service_manager.GetServicePort(name); -    auto service = service_manager.GetService<Kernel::SessionRequestHandler>(name); -    if (port_result.Failed() || !service) { -        LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); -        return port_result.Code(); +    if (port_result.Code() == ERR_INVALID_NAME) { +        LOG_ERROR(Service_SM, "Invalid service name '{}'", name); +        return ERR_INVALID_NAME; +    } + +    if (port_result.Failed()) { +        LOG_INFO(Service_SM, "Waiting for service {} to become available", name); +        ctx.SetIsDeferred(); +        return ERR_SERVICE_NOT_REGISTERED;      }      auto& port = port_result.Unwrap(); @@ -167,7 +186,6 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&          LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);          return result;      } -    service->AcceptSession(&port->GetServerPort());      LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); @@ -212,7 +230,7 @@ void SM::UnregisterService(Kernel::HLERequestContext& ctx) {  }  SM::SM(ServiceManager& service_manager_, Core::System& system_) -    : ServiceFramework{system_, "sm:", ServiceThreadType::Default, 4}, +    : ServiceFramework{system_, "sm:", 4},        service_manager{service_manager_}, kernel{system_.Kernel()} {      RegisterHandlers({          {0, &SM::Initialize, "Initialize"}, @@ -232,4 +250,16 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)  SM::~SM() = default; +void LoopProcess(Core::System& system) { +    auto& service_manager = system.ServiceManager(); +    auto server_manager = std::make_unique<ServerManager>(system); + +    Kernel::KEvent* deferral_event{}; +    server_manager->ManageDeferral(&deferral_event); +    service_manager.SetDeferralEvent(deferral_event); + +    server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system)); +    ServerManager::RunServer(std::move(server_manager)); +} +  } // namespace Service::SM diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 02a5dde9e..b7eeafdd6 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -4,6 +4,7 @@  #pragma once  #include <memory> +#include <mutex>  #include <string>  #include <unordered_map> @@ -50,9 +51,6 @@ private:  class ServiceManager {  public: -    static Kernel::KClientPort& InterfaceFactory(ServiceManager& self, Core::System& system); -    static void SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port); -      explicit ServiceManager(Kernel::KernelCore& kernel_);      ~ServiceManager(); @@ -73,16 +71,25 @@ public:      void InvokeControlRequest(Kernel::HLERequestContext& context); +    void SetDeferralEvent(Kernel::KEvent* deferral_event_) { +        deferral_event = deferral_event_; +    } +  private:      std::shared_ptr<SM> sm_interface;      std::unique_ptr<Controller> controller_interface;      /// Map of registered services, retrieved using GetServicePort. +    std::mutex lock;      std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services;      std::unordered_map<std::string, Kernel::KPort*> service_ports;      /// Kernel context      Kernel::KernelCore& kernel; +    Kernel::KEvent* deferral_event{};  }; +/// Runs SM services. +void LoopProcess(Core::System& system); +  } // namespace Service::SM diff --git a/src/core/hle/service/sm/sm_controller.cpp b/src/core/hle/service/sm/sm_controller.cpp index 1cf9dd1c4..f52522d1d 100644 --- a/src/core/hle/service/sm/sm_controller.cpp +++ b/src/core/hle/service/sm/sm_controller.cpp @@ -10,6 +10,7 @@  #include "core/hle/kernel/k_scoped_resource_reservation.h"  #include "core/hle/kernel/k_server_session.h"  #include "core/hle/kernel/k_session.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/sm/sm_controller.h"  namespace Service::SM { @@ -48,9 +49,9 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {      // Commit the session reservation.      session_reservation.Commit(); -    // Register with manager. -    session_manager->SessionHandler().RegisterSession(&session->GetServerSession(), -                                                      session_manager); +    // Register with server manager. +    session_manager->GetServerManager().RegisterSession(&session->GetServerSession(), +                                                        session_manager);      // We succeeded.      IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 330a66409..2789fa1ed 100644 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -881,8 +881,7 @@ void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {  }  BSD::BSD(Core::System& system_, const char* name) -    : ServiceFramework{system_, name, ServiceThreadType::CreateNew}, room_network{ -                                                                         system_.GetRoomNetwork()} { +    : ServiceFramework{system_, name}, room_network{system_.GetRoomNetwork()} {      // clang-format off      static const FunctionInfo functions[] = {          {0, &BSD::RegisterClient, "RegisterClient"}, diff --git a/src/core/hle/service/sockets/sockets.cpp b/src/core/hle/service/sockets/sockets.cpp index b191b5cf5..676d24e03 100644 --- a/src/core/hle/service/sockets/sockets.cpp +++ b/src/core/hle/service/sockets/sockets.cpp @@ -1,6 +1,7 @@  // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project  // SPDX-License-Identifier: GPL-2.0-or-later +#include "core/hle/service/server_manager.h"  #include "core/hle/service/sockets/bsd.h"  #include "core/hle/service/sockets/nsd.h"  #include "core/hle/service/sockets/sfdnsres.h" @@ -8,15 +9,17 @@  namespace Service::Sockets { -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<BSD>(system, "bsd:s")->InstallAsService(service_manager); -    std::make_shared<BSD>(system, "bsd:u")->InstallAsService(service_manager); -    std::make_shared<BSDCFG>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); -    std::make_shared<NSD>(system, "nsd:a")->InstallAsService(service_manager); -    std::make_shared<NSD>(system, "nsd:u")->InstallAsService(service_manager); - -    std::make_shared<SFDNSRES>(system)->InstallAsService(service_manager); +    server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s")); +    server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u")); +    server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system)); +    server_manager->RegisterNamedService("nsd:a", std::make_shared<NSD>(system, "nsd:a")); +    server_manager->RegisterNamedService("nsd:u", std::make_shared<NSD>(system, "nsd:u")); +    server_manager->RegisterNamedService("sfdnsres", std::make_shared<SFDNSRES>(system)); +    server_manager->StartAdditionalHostThreads("bsdsocket", 2); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Sockets diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h index 9840c11f9..acd2dae7b 100644 --- a/src/core/hle/service/sockets/sockets.h +++ b/src/core/hle/service/sockets/sockets.h @@ -10,10 +10,6 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::Sockets {  enum class Errno : u32 { @@ -99,7 +95,6 @@ struct Linger {      u32 linger;  }; -/// Registers all Sockets services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Sockets diff --git a/src/core/hle/service/spl/spl_module.cpp b/src/core/hle/service/spl/spl_module.cpp index 64eae1ebf..31679e1bb 100644 --- a/src/core/hle/service/spl/spl_module.cpp +++ b/src/core/hle/service/spl/spl_module.cpp @@ -9,6 +9,7 @@  #include "common/settings.h"  #include "core/hle/api_version.h"  #include "core/hle/ipc_helpers.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/spl/csrng.h"  #include "core/hle/service/spl/spl.h"  #include "core/hle/service/spl/spl_module.h" @@ -158,15 +159,18 @@ ResultVal<u64> Module::Interface::GetConfigImpl(ConfigItem config_item) const {      }  } -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system);      auto module = std::make_shared<Module>(); -    std::make_shared<CSRNG>(system, module)->InstallAsService(service_manager); -    std::make_shared<SPL>(system, module)->InstallAsService(service_manager); -    std::make_shared<SPL_MIG>(system, module)->InstallAsService(service_manager); -    std::make_shared<SPL_FS>(system, module)->InstallAsService(service_manager); -    std::make_shared<SPL_SSL>(system, module)->InstallAsService(service_manager); -    std::make_shared<SPL_ES>(system, module)->InstallAsService(service_manager); -    std::make_shared<SPL_MANU>(system, module)->InstallAsService(service_manager); + +    server_manager->RegisterNamedService("csrng", std::make_shared<CSRNG>(system, module)); +    server_manager->RegisterNamedService("spl", std::make_shared<SPL>(system, module)); +    server_manager->RegisterNamedService("spl:mig", std::make_shared<SPL_MIG>(system, module)); +    server_manager->RegisterNamedService("spl:fs", std::make_shared<SPL_FS>(system, module)); +    server_manager->RegisterNamedService("spl:ssl", std::make_shared<SPL_SSL>(system, module)); +    server_manager->RegisterNamedService("spl:es", std::make_shared<SPL_ES>(system, module)); +    server_manager->RegisterNamedService("spl:manu", std::make_shared<SPL_MANU>(system, module)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::SPL diff --git a/src/core/hle/service/spl/spl_module.h b/src/core/hle/service/spl/spl_module.h index 4c9a3c618..baed9efd7 100644 --- a/src/core/hle/service/spl/spl_module.h +++ b/src/core/hle/service/spl/spl_module.h @@ -41,7 +41,6 @@ public:      };  }; -/// Registers all SPL services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::SPL diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 015208593..c1fd1a59b 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -2,8 +2,8 @@  // SPDX-License-Identifier: GPL-2.0-or-later  #include "core/hle/ipc_helpers.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  #include "core/hle/service/ssl/ssl.h"  namespace Service::SSL { @@ -183,8 +183,11 @@ private:      }  }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { -    std::make_shared<SSL>(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("ssl", std::make_shared<SSL>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::SSL diff --git a/src/core/hle/service/ssl/ssl.h b/src/core/hle/service/ssl/ssl.h index 27b38a003..f6e21bbb3 100644 --- a/src/core/hle/service/ssl/ssl.h +++ b/src/core/hle/service/ssl/ssl.h @@ -7,13 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::SSL { -/// Registers all SSL services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::SSL diff --git a/src/core/hle/service/time/time.cpp b/src/core/hle/service/time/time.cpp index f77cdbb43..8020e407c 100644 --- a/src/core/hle/service/time/time.cpp +++ b/src/core/hle/service/time/time.cpp @@ -7,6 +7,7 @@  #include "core/hardware_properties.h"  #include "core/hle/ipc_helpers.h"  #include "core/hle/kernel/kernel.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/time/time.h"  #include "core/hle/service/time/time_interface.h"  #include "core/hle/service/time/time_manager.h" @@ -397,11 +398,17 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst  Module::Interface::~Interface() = default; -void InstallInterfaces(Core::System& system) { +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system);      auto module{std::make_shared<Module>()}; -    std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager()); -    std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager()); -    std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager()); + +    server_manager->RegisterNamedService("time:a", +                                         std::make_shared<Time>(module, system, "time:a")); +    server_manager->RegisterNamedService("time:s", +                                         std::make_shared<Time>(module, system, "time:s")); +    server_manager->RegisterNamedService("time:u", +                                         std::make_shared<Time>(module, system, "time:u")); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::Time diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h index 76a46cfc7..c9936c645 100644 --- a/src/core/hle/service/time/time.h +++ b/src/core/hle/service/time/time.h @@ -46,7 +46,6 @@ public:      };  }; -/// Registers all Time services with the specified service manager. -void InstallInterfaces(Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::Time diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp index ac46a406c..ddb73f394 100644 --- a/src/core/hle/service/usb/usb.cpp +++ b/src/core/hle/service/usb/usb.cpp @@ -5,8 +5,8 @@  #include "common/logging/log.h"  #include "core/hle/ipc_helpers.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h"  #include "core/hle/service/usb/usb.h"  namespace Service::USB { @@ -218,12 +218,15 @@ public:      }  }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { -    std::make_shared<USB_DS>(system)->InstallAsService(sm); -    std::make_shared<USB_HS>(system)->InstallAsService(sm); -    std::make_shared<USB_PD>(system)->InstallAsService(sm); -    std::make_shared<USB_PD_C>(system)->InstallAsService(sm); -    std::make_shared<USB_PM>(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService("usb:ds", std::make_shared<USB_DS>(system)); +    server_manager->RegisterNamedService("usb:hs", std::make_shared<USB_HS>(system)); +    server_manager->RegisterNamedService("usb:pd", std::make_shared<USB_PD>(system)); +    server_manager->RegisterNamedService("usb:pd:c", std::make_shared<USB_PD_C>(system)); +    server_manager->RegisterNamedService("usb:pm", std::make_shared<USB_PM>(system)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::USB diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h index b41b9684c..98376ebc0 100644 --- a/src/core/hle/service/usb/usb.h +++ b/src/core/hle/service/usb/usb.h @@ -7,12 +7,8 @@ namespace Core {  class System;  } -namespace Service::SM { -class ServiceManager; -} -  namespace Service::USB { -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); +void LoopProcess(Core::System& system);  } // namespace Service::USB diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp index 0915785d2..d9cfebd70 100644 --- a/src/core/hle/service/vi/vi.cpp +++ b/src/core/hle/service/vi/vi.cpp @@ -26,6 +26,7 @@  #include "core/hle/service/nvflinger/hos_binder_driver_server.h"  #include "core/hle/service/nvflinger/nvflinger.h"  #include "core/hle/service/nvflinger/parcel.h" +#include "core/hle/service/server_manager.h"  #include "core/hle/service/service.h"  #include "core/hle/service/vi/vi.h"  #include "core/hle/service/vi/vi_m.h" @@ -73,8 +74,7 @@ static_assert(sizeof(NativeWindow) == 0x28, "NativeWindow has wrong size");  class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> {  public:      explicit IHOSBinderDriver(Core::System& system_, NVFlinger::HosBinderDriverServer& server_) -        : ServiceFramework{system_, "IHOSBinderDriver", ServiceThreadType::CreateNew}, -          server(server_) { +        : ServiceFramework{system_, "IHOSBinderDriver"}, server(server_) {          static const FunctionInfo functions[] = {              {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},              {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, @@ -809,15 +809,17 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System&      rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger, hos_binder_driver_server);  } -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system, -                       NVFlinger::NVFlinger& nv_flinger, -                       NVFlinger::HosBinderDriverServer& hos_binder_driver_server) { -    std::make_shared<VI_M>(system, nv_flinger, hos_binder_driver_server) -        ->InstallAsService(service_manager); -    std::make_shared<VI_S>(system, nv_flinger, hos_binder_driver_server) -        ->InstallAsService(service_manager); -    std::make_shared<VI_U>(system, nv_flinger, hos_binder_driver_server) -        ->InstallAsService(service_manager); +void LoopProcess(Core::System& system, NVFlinger::NVFlinger& nv_flinger, +                 NVFlinger::HosBinderDriverServer& hos_binder_driver_server) { +    auto server_manager = std::make_unique<ServerManager>(system); + +    server_manager->RegisterNamedService( +        "vi:m", std::make_shared<VI_M>(system, nv_flinger, hos_binder_driver_server)); +    server_manager->RegisterNamedService( +        "vi:s", std::make_shared<VI_S>(system, nv_flinger, hos_binder_driver_server)); +    server_manager->RegisterNamedService( +        "vi:u", std::make_shared<VI_U>(system, nv_flinger, hos_binder_driver_server)); +    ServerManager::RunServer(std::move(server_manager));  }  } // namespace Service::VI diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h index fc2d717e7..4ed7aaf2b 100644 --- a/src/core/hle/service/vi/vi.h +++ b/src/core/hle/service/vi/vi.h @@ -18,10 +18,6 @@ class HosBinderDriverServer;  class NVFlinger;  } // namespace Service::NVFlinger -namespace Service::SM { -class ServiceManager; -} -  namespace Service::VI {  enum class DisplayResolution : u32 { @@ -52,9 +48,7 @@ void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& system,                             Permission permission);  } // namespace detail -/// Registers all VI services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system, -                       NVFlinger::NVFlinger& nv_flinger, -                       NVFlinger::HosBinderDriverServer& hos_binder_driver_server); +void LoopProcess(Core::System& system, NVFlinger::NVFlinger& nv_flinger, +                 NVFlinger::HosBinderDriverServer& hos_binder_driver_server);  } // namespace Service::VI diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp index 44ee39648..c2d96bbec 100644 --- a/src/core/memory/cheat_engine.cpp +++ b/src/core/memory/cheat_engine.cpp @@ -47,8 +47,13 @@ void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size)  }  u64 StandardVmCallbacks::HidKeysDown() { -    const auto applet_resource = -        system.ServiceManager().GetService<Service::HID::Hid>("hid")->GetAppletResource(); +    const auto hid = system.ServiceManager().GetService<Service::HID::Hid>("hid"); +    if (hid == nullptr) { +        LOG_WARNING(CheatEngine, "Attempted to read input state, but hid is not initialized!"); +        return 0; +    } + +    const auto applet_resource = hid->GetAppletResource();      if (applet_resource == nullptr) {          LOG_WARNING(CheatEngine,                      "Attempted to read input state, but applet resource is not initialized!"); | 
