From a9369726147c7499e0016e183d5d56a7b44efe4b Mon Sep 17 00:00:00 2001 From: Liam Date: Sat, 18 Feb 2023 16:26:48 -0500 Subject: service: refactor server architecture Converts services to have their own processes --- src/core/hle/ipc_helpers.h | 12 +- src/core/hle/kernel/hle_ipc.cpp | 30 +-- src/core/hle/kernel/hle_ipc.h | 34 +-- src/core/hle/kernel/k_process.cpp | 4 - src/core/hle/kernel/k_thread.cpp | 20 ++ src/core/hle/kernel/k_thread.h | 4 + src/core/hle/kernel/kernel.cpp | 207 +++++++------- src/core/hle/kernel/kernel.h | 69 +---- src/core/hle/kernel/service_thread.cpp | 206 -------------- src/core/hle/kernel/service_thread.h | 29 -- src/core/hle/kernel/svc/svc_info.cpp | 5 + src/core/hle/kernel/svc/svc_port.cpp | 51 ++-- src/core/hle/service/acc/acc.cpp | 23 +- src/core/hle/service/acc/acc.h | 3 +- src/core/hle/service/am/am.cpp | 19 +- src/core/hle/service/am/am.h | 4 +- src/core/hle/service/aoc/aoc_u.cpp | 7 +- src/core/hle/service/aoc/aoc_u.h | 3 +- src/core/hle/service/apm/apm.cpp | 20 +- src/core/hle/service/apm/apm.h | 3 +- src/core/hle/service/audio/audin_u.cpp | 5 +- src/core/hle/service/audio/audio.cpp | 21 +- src/core/hle/service/audio/audio.h | 3 +- src/core/hle/service/audio/audout_u.cpp | 10 +- src/core/hle/service/audio/audren_u.cpp | 15 +- src/core/hle/service/bcat/bcat_module.cpp | 26 +- src/core/hle/service/bcat/bcat_module.h | 3 +- src/core/hle/service/bpc/bpc.cpp | 11 +- src/core/hle/service/bpc/bpc.h | 2 +- src/core/hle/service/btdrv/btdrv.cpp | 10 +- src/core/hle/service/btdrv/btdrv.h | 3 +- src/core/hle/service/btm/btm.cpp | 14 +- src/core/hle/service/btm/btm.h | 2 +- src/core/hle/service/caps/caps.cpp | 18 +- src/core/hle/service/caps/caps.h | 3 +- src/core/hle/service/erpt/erpt.cpp | 11 +- src/core/hle/service/erpt/erpt.h | 7 +- src/core/hle/service/es/es.cpp | 8 +- src/core/hle/service/es/es.h | 7 +- src/core/hle/service/eupld/eupld.cpp | 11 +- src/core/hle/service/eupld/eupld.h | 7 +- src/core/hle/service/fatal/fatal.cpp | 10 +- src/core/hle/service/fatal/fatal.h | 2 +- src/core/hle/service/fgm/fgm.cpp | 14 +- src/core/hle/service/fgm/fgm.h | 6 +- src/core/hle/service/filesystem/filesystem.cpp | 12 +- src/core/hle/service/filesystem/filesystem.h | 2 +- src/core/hle/service/filesystem/fsp_srv.cpp | 13 +- src/core/hle/service/friend/friend.cpp | 22 +- src/core/hle/service/friend/friend.h | 3 +- src/core/hle/service/glue/glue.cpp | 23 +- src/core/hle/service/glue/glue.h | 3 +- src/core/hle/service/grc/grc.cpp | 9 +- src/core/hle/service/grc/grc.h | 6 +- src/core/hle/service/hid/hid.cpp | 21 +- src/core/hle/service/hid/hid.h | 3 +- src/core/hle/service/jit/jit.cpp | 12 +- src/core/hle/service/jit/jit.h | 7 +- src/core/hle/service/kernel_helpers.cpp | 11 +- src/core/hle/service/kernel_helpers.h | 1 + src/core/hle/service/lbl/lbl.cpp | 8 +- src/core/hle/service/lbl/lbl.h | 6 +- src/core/hle/service/ldn/ldn.cpp | 18 +- src/core/hle/service/ldn/ldn.h | 7 +- src/core/hle/service/ldr/ldr.cpp | 18 +- src/core/hle/service/ldr/ldr.h | 7 +- src/core/hle/service/lm/lm.cpp | 8 +- src/core/hle/service/lm/lm.h | 3 +- src/core/hle/service/mig/mig.cpp | 9 +- src/core/hle/service/mig/mig.h | 6 +- src/core/hle/service/mii/mii.cpp | 12 +- src/core/hle/service/mii/mii.h | 6 +- src/core/hle/service/mm/mm_u.cpp | 8 +- src/core/hle/service/mm/mm_u.h | 7 +- src/core/hle/service/mnpp/mnpp_app.cpp | 10 +- src/core/hle/service/mnpp/mnpp_app.h | 7 +- src/core/hle/service/mutex.cpp | 43 +++ src/core/hle/service/mutex.h | 31 +++ src/core/hle/service/ncm/ncm.cpp | 11 +- src/core/hle/service/ncm/ncm.h | 6 +- src/core/hle/service/nfc/nfc.cpp | 15 +- src/core/hle/service/nfc/nfc.h | 6 +- src/core/hle/service/nfp/nfp.cpp | 8 +- src/core/hle/service/nfp/nfp.h | 2 +- src/core/hle/service/ngct/ngct.cpp | 8 +- src/core/hle/service/ngct/ngct.h | 7 +- src/core/hle/service/nifm/nifm.cpp | 15 +- src/core/hle/service/nifm/nifm.h | 7 +- src/core/hle/service/nim/nim.cpp | 15 +- src/core/hle/service/nim/nim.h | 6 +- src/core/hle/service/npns/npns.cpp | 11 +- src/core/hle/service/npns/npns.h | 6 +- src/core/hle/service/ns/ns.cpp | 38 +-- src/core/hle/service/ns/ns.h | 3 +- src/core/hle/service/nvdrv/nvdrv.cpp | 23 +- src/core/hle/service/nvdrv/nvdrv.h | 4 +- src/core/hle/service/nvdrv/nvdrv_interface.cpp | 2 +- src/core/hle/service/olsc/olsc.cpp | 9 +- src/core/hle/service/olsc/olsc.h | 7 +- src/core/hle/service/pcie/pcie.cpp | 9 +- src/core/hle/service/pcie/pcie.h | 6 +- src/core/hle/service/pctl/pctl_module.cpp | 26 +- src/core/hle/service/pctl/pctl_module.h | 3 +- src/core/hle/service/pcv/pcv.cpp | 15 +- src/core/hle/service/pcv/pcv.h | 6 +- src/core/hle/service/pm/pm.cpp | 16 +- src/core/hle/service/pm/pm.h | 3 +- src/core/hle/service/prepo/prepo.cpp | 21 +- src/core/hle/service/prepo/prepo.h | 6 +- src/core/hle/service/psc/psc.cpp | 11 +- src/core/hle/service/psc/psc.h | 2 +- src/core/hle/service/ptm/ptm.cpp | 10 +- src/core/hle/service/ptm/ptm.h | 6 +- src/core/hle/service/server_manager.cpp | 358 +++++++++++++++++++++++++ src/core/hle/service/server_manager.h | 75 ++++++ src/core/hle/service/service.cpp | 151 +++++------ src/core/hle/service/service.h | 19 +- src/core/hle/service/set/settings.cpp | 15 +- src/core/hle/service/set/settings.h | 7 +- src/core/hle/service/sm/sm.cpp | 32 +-- src/core/hle/service/sm/sm.h | 8 +- src/core/hle/service/sm/sm_controller.cpp | 7 +- src/core/hle/service/sockets/bsd.cpp | 3 +- src/core/hle/service/sockets/sockets.cpp | 19 +- src/core/hle/service/sockets/sockets.h | 7 +- src/core/hle/service/spl/spl_module.cpp | 20 +- src/core/hle/service/spl/spl_module.h | 3 +- src/core/hle/service/ssl/ssl.cpp | 9 +- src/core/hle/service/ssl/ssl.h | 7 +- src/core/hle/service/time/time.cpp | 15 +- src/core/hle/service/time/time.h | 3 +- src/core/hle/service/usb/usb.cpp | 17 +- src/core/hle/service/usb/usb.h | 6 +- src/core/hle/service/vi/vi.cpp | 24 +- src/core/hle/service/vi/vi.h | 10 +- 135 files changed, 1373 insertions(+), 1135 deletions(-) delete mode 100644 src/core/hle/kernel/service_thread.cpp delete mode 100644 src/core/hle/kernel/service_thread.h create mode 100644 src/core/hle/service/mutex.cpp create mode 100644 src/core/hle/service/mutex.h create mode 100644 src/core/hle/service/server_manager.cpp create mode 100644 src/core/hle/service/server_manager.h (limited to 'src/core/hle') 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 void PushIpcInterface(std::shared_ptr 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)); + + auto next_manager = std::make_shared( + 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(kernel)); -} - -void SessionRequestHandler::RegisterSession(KServerSession* server_session, - std::shared_ptr 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..059b21991 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 { 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 manager); - - ServiceThread& GetServiceThread() const { - return service_thread; - } - protected: KernelCore& kernel; - ServiceThread& service_thread; }; using SessionRequestHandlerWeakPtr = std::weak_ptr; @@ -102,7 +85,7 @@ using SessionRequestHandlerPtr = std::shared_ptr; */ class SessionRequestManager final { public: - explicit SessionRequestManager(KernelCore& kernel); + explicit SessionRequestManager(KernelCore& kernel, Service::ServerManager& server_manager); ~SessionRequestManager(); bool IsDomain() const { @@ -155,15 +138,15 @@ 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; + } + private: bool convert_to_domain{}; bool is_domain{}; @@ -172,6 +155,7 @@ private: private: KernelCore& kernel; + Service::ServerManager& server_manager; }; /** 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&& func, s32 prio, s32 virt_core, + KProcess* owner) { + system.Kernel().GlobalSchedulerContext().AddThread(thread); + std::function 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(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&& 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(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 object_name_global_data; - /// Map of named ports managed by the kernel, which can be retrieved using - /// the ConnectToPort SVC. - std::unordered_map service_interface_factory; - std::unordered_map service_interface_handlers; - NamedPortTable named_ports; std::unordered_set registered_objects; std::unordered_set registered_in_use_objects; + std::mutex server_lock; + std::vector> server_managers; + std::unique_ptr exclusive_monitor; std::array, Core::Hardware::NUM_CPU_CORES> cores; @@ -881,12 +823,6 @@ struct KernelCore::Impl { // Memory layout std::unique_ptr memory_layout; - // Threads used for services - std::unordered_map> service_threads; - ServiceThread* default_service_thread{}; - Common::ThreadWorker service_threads_manager; - Common::Barrier service_thread_barrier; - std::array shutdown_threads{}; std::array, 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&& 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&& 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 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 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 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 #include #include + +#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; - -using ServiceInterfaceHandlerFn = std::function; namespace Init { struct KSlabResourceCounts; @@ -80,15 +79,8 @@ struct KSlabResourceCounts; template 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; - 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&& 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 func); + + std::jthread RunOnHostCoreProcess(std::string&& process_name, std::function func); + + std::jthread RunOnHostCoreThread(std::string&& thread_name, std::function 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 -#include -#include -#include -#include - -#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 manager); - void LoopProcess(); - - void RegisterServerSession(KServerSession* session, - std::shared_ptr manager); - -private: - KernelCore& kernel; - const std::string m_service_name; - - std::jthread m_host_thread{}; - std::mutex m_session_mutex{}; - std::map> m_sessions{}; - KEvent* m_wakeup_event{}; - KThread* m_thread{}; - std::atomic m_shutdown_requested{}; -}; - -void ServiceThread::Impl::WaitAndProcessImpl() { - // Create local list of waitable sessions. - std::vector objs; - std::vector> 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(objs.size()), -1); - ASSERT(!rc.IsFailure()); - - // If this was the wakeup event, clear it and finish. - if (index >= static_cast(objs.size() - 1)) { - m_wakeup_event->Clear(); - return; - } - - // This event is from a server session. - auto* server_session = static_cast(objs[index]); - auto& manager = managers[index]; - - // Fetch the HLE request context. - std::shared_ptr 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 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 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(kernel, name)} {} - -ServiceThread::~ServiceThread() = default; - -void ServiceThread::RegisterServerSession(KServerSession* session, - std::shared_ptr 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 -#include - -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 manager); - -private: - class Impl; - std::unique_ptr 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 2f9bfcb52..ac095b338 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 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(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, @@ -77,9 +61,12 @@ 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 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 1495d64de..5eefa2e82 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 { @@ -942,18 +943,20 @@ Module::Interface::Interface(std::shared_ptr module_, Module::Interface::~Interface() = default; -void InstallInterfaces(Core::System& system) { +void LoopProcess(Core::System& system) { auto module = std::make_shared(); auto profile_manager = std::make_shared(); - - std::make_shared(module, profile_manager, system) - ->InstallAsService(system.ServiceManager()); - std::make_shared(module, profile_manager, system) - ->InstallAsService(system.ServiceManager()); - std::make_shared(module, profile_manager, system) - ->InstallAsService(system.ServiceManager()); - std::make_shared(module, profile_manager, system) - ->InstallAsService(system.ServiceManager()); + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("acc:aa", + std::make_shared(module, profile_manager, system)); + server_manager->RegisterNamedService("acc:su", + std::make_shared(module, profile_manager, system)); + server_manager->RegisterNamedService("acc:u0", + std::make_shared(module, profile_manager, system)); + server_manager->RegisterNamedService("acc:u1", + std::make_shared(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 beb2da06e..979881512 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" @@ -1828,17 +1829,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(system); // Needed on game boot message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); - std::make_shared(nvflinger, message_queue, system)->InstallAsService(service_manager); - std::make_shared(nvflinger, message_queue, system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService( + "appletAE", std::make_shared(nvflinger, message_queue, system)); + server_manager->RegisterNamedService( + "appletOE", std::make_shared(nvflinger, message_queue, system)); + server_manager->RegisterNamedService("idle:sys", std::make_shared(system)); + server_manager->RegisterNamedService("omm", std::make_shared(system)); + server_manager->RegisterNamedService("spsm", std::make_shared(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 7264f23f9..c4cd1d0d5 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 { @@ -311,8 +312,10 @@ void AOC_U::CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ct rb.PushIpcInterface(system); } -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { - std::make_shared(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + server_manager->RegisterNamedService("aoc:u", std::make_shared(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(); - std::make_shared(system, module_, system.GetAPMController(), "apm") - ->InstallAsService(system.ServiceManager()); - std::make_shared(system, module_, system.GetAPMController(), "apm:am") - ->InstallAsService(system.ServiceManager()); - std::make_shared(system, system.GetAPMController()) - ->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { + auto module = std::make_shared(); + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService( + "apm", std::make_shared(system, module, system.GetAPMController(), "apm")); + server_manager->RegisterNamedService( + "apm:am", std::make_shared(system, module, system.GetAPMController(), "apm:am")); + server_manager->RegisterNamedService( + "apm:sys", std::make_shared(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( - system_)} { + : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"}, + impl{std::make_unique(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(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("audctl", std::make_shared(system)); + server_manager->RegisterNamedService("audout:u", std::make_shared(system)); + server_manager->RegisterNamedService("audin:u", std::make_shared(system)); + server_manager->RegisterNamedService("audrec:a", std::make_shared(system)); + server_manager->RegisterNamedService("audrec:u", std::make_shared(system)); + server_manager->RegisterNamedService("audren:u", std::make_shared(system)); + server_manager->RegisterNamedService("hwopus", std::make_shared(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(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( - system_)} { + : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"}, + impl{std::make_unique(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(system_, manager, rendered_event)} { + : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"}, + rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_}, + impl{std::make_unique(system_, manager, rendered_event)} { // clang-format off static const FunctionInfo functions[] = { {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, @@ -243,10 +242,8 @@ class IAudioDevice final : public ServiceFramework { 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( - system_, applet_resource_user_id, - revision)}, + : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"}, + impl{std::make_unique(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(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 modu Module::Interface::~Interface() = default; -void InstallInterfaces(Core::System& system) { +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); auto module = std::make_shared(); - std::make_shared(system, module, system.GetFileSystemController(), "bcat:a") - ->InstallAsService(system.ServiceManager()); - std::make_shared(system, module, system.GetFileSystemController(), "bcat:m") - ->InstallAsService(system.ServiceManager()); - std::make_shared(system, module, system.GetFileSystemController(), "bcat:u") - ->InstallAsService(system.ServiceManager()); - std::make_shared(system, module, system.GetFileSystemController(), "bcat:s") - ->InstallAsService(system.ServiceManager()); + + server_manager->RegisterNamedService( + "bcat:a", + std::make_shared(system, module, system.GetFileSystemController(), "bcat:a")); + server_manager->RegisterNamedService( + "bcat:m", + std::make_shared(system, module, system.GetFileSystemController(), "bcat:m")); + server_manager->RegisterNamedService( + "bcat:u", + std::make_shared(system, module, system.GetFileSystemController(), "bcat:u")); + server_manager->RegisterNamedService( + "bcat:s", + std::make_shared(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 #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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("bpc", std::make_shared(system)); + server_manager->RegisterNamedService("bpc:r", std::make_shared(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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("btdrv", std::make_shared(system)); + server_manager->RegisterNamedService("bt", std::make_shared(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 eebf85e03..e068ea87f 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 { @@ -311,11 +312,14 @@ private: } }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("btm", std::make_shared(system)); + server_manager->RegisterNamedService("btm:dbg", std::make_shared(system)); + server_manager->RegisterNamedService("btm:sys", std::make_shared(system)); + server_manager->RegisterNamedService("btm:u", std::make_shared(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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("caps:a", std::make_shared(system)); + server_manager->RegisterNamedService("caps:c", std::make_shared(system)); + server_manager->RegisterNamedService("caps:u", std::make_shared(system)); + server_manager->RegisterNamedService("caps:sc", std::make_shared(system)); + server_manager->RegisterNamedService("caps:ss", std::make_shared(system)); + server_manager->RegisterNamedService("caps:su", std::make_shared(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 #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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("erpt:c", std::make_shared(system)); + server_manager->RegisterNamedService("erpt:r", std::make_shared(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(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("es", std::make_shared(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 #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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("eupld:c", std::make_shared(system)); + server_manager->RegisterNamedService("eupld:r", std::make_shared(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(system); auto module = std::make_shared(); - std::make_shared(module, system)->InstallAsService(service_manager); - std::make_shared(module, system)->InstallAsService(service_manager); + + server_manager->RegisterNamedService("fatal:p", std::make_shared(module, system)); + server_manager->RegisterNamedService("fatal:u", std::make_shared(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(system, "fgm")->InstallAsService(sm); - std::make_shared(system, "fgm:0")->InstallAsService(sm); - std::make_shared(system, "fgm:9")->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("fgm", std::make_shared(system, "fgm")); + server_manager->RegisterNamedService("fgm:0", std::make_shared(system, "fgm:0")); + server_manager->RegisterNamedService("fgm:9", std::make_shared(system, "fgm:9")); + server_manager->RegisterNamedService("fgm:dbg", std::make_shared(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(system)->InstallAsService(system.ServiceManager()); - std::make_shared(system)->InstallAsService(system.ServiceManager()); - std::make_shared(system)->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("fsp-ldr", std::make_shared(system)); + server_manager->RegisterNamedService("fsp:pr", std::make_shared(system)); + server_manager->RegisterNamedService("fsp-srv", std::make_shared(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 { 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 { 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& entries, const std::vec class IDirectory final : public ServiceFramework { 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 { 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_, 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(system); auto module = std::make_shared(); - std::make_shared(module, system, "friend:a")->InstallAsService(service_manager); - std::make_shared(module, system, "friend:m")->InstallAsService(service_manager); - std::make_shared(module, system, "friend:s")->InstallAsService(service_manager); - std::make_shared(module, system, "friend:u")->InstallAsService(service_manager); - std::make_shared(module, system, "friend:v")->InstallAsService(service_manager); + + server_manager->RegisterNamedService("friend:a", + std::make_shared(module, system, "friend:a")); + server_manager->RegisterNamedService("friend:m", + std::make_shared(module, system, "friend:m")); + server_manager->RegisterNamedService("friend:s", + std::make_shared(module, system, "friend:s")); + server_manager->RegisterNamedService("friend:u", + std::make_shared(module, system, "friend:u")); + server_manager->RegisterNamedService("friend:v", + std::make_shared(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(system); + // ARP - std::make_shared(system, system.GetARPManager()) - ->InstallAsService(system.ServiceManager()); - std::make_shared(system, system.GetARPManager()) - ->InstallAsService(system.ServiceManager()); + server_manager->RegisterNamedService("arp:r", + std::make_shared(system, system.GetARPManager())); + server_manager->RegisterNamedService("arp:w", + std::make_shared(system, system.GetARPManager())); // BackGround Task Controller - std::make_shared(system)->InstallAsService(system.ServiceManager()); - std::make_shared(system)->InstallAsService(system.ServiceManager()); + server_manager->RegisterNamedService("bgtc:t", std::make_shared(system)); + server_manager->RegisterNamedService("bgtc:sc", std::make_shared(system)); // Error Context - std::make_shared(system)->InstallAsService(system.ServiceManager()); + server_manager->RegisterNamedService("ectx:aw", std::make_shared(system)); // Notification Services for application - std::make_shared(system)->InstallAsService(system.ServiceManager()); + server_manager->RegisterNamedService("notif:a", std::make_shared(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 #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(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("grc:c", std::make_shared(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 eb3c45a58..5ec31950a 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" @@ -2734,16 +2735,20 @@ private: } }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); + server_manager->RegisterNamedService("hid", std::make_shared(system)); + server_manager->RegisterNamedService("hidbus", std::make_shared(system)); + server_manager->RegisterNamedService("hid:dbg", std::make_shared(system)); + server_manager->RegisterNamedService("hid:sys", std::make_shared(system)); - std::make_shared(system)->InstallAsService(service_manager); + server_manager->RegisterNamedService("irs", std::make_shared(system)); + server_manager->RegisterNamedService("irs:sys", + std::make_shared(system)); + + server_manager->RegisterNamedService("xcd:sys", std::make_shared(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 b7c2a23ef..dc3c45aba 100644 --- a/src/core/hle/service/hid/hid.h +++ b/src/core/hle/service/hid/hid.h @@ -209,7 +209,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 { 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(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("jit:u", std::make_shared(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(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("lbl", std::make_shared(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 { 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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("ldn:m", std::make_shared(system)); + server_manager->RegisterNamedService("ldn:s", std::make_shared(system)); + server_manager->RegisterNamedService("ldn:u", std::make_shared(system)); + server_manager->RegisterNamedService("lp2p:app", std::make_shared(system)); + server_manager->RegisterNamedService("lp2p:sys", std::make_shared(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 { 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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("ldr:dmnt", std::make_shared(system)); + server_manager->RegisterNamedService("ldr:pm", std::make_shared(system)); + server_manager->RegisterNamedService("ldr:shel", std::make_shared(system)); + server_manager->RegisterNamedService("ldr:ro", std::make_shared(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(system)->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("lm", std::make_shared(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 #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(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("mig:user", std::make_shared(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(system, "mii:e")->InstallAsService(sm); - std::make_shared(system, "mii:u")->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); - std::make_shared(system)->InstallAsService(sm); + server_manager->RegisterNamedService("mii:e", std::make_shared(system, "mii:e")); + server_manager->RegisterNamedService("mii:u", std::make_shared(system, "mii:u")); + server_manager->RegisterNamedService("miiimg", std::make_shared(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(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("mm:u", std::make_shared(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(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("mnpp:app", std::make_shared(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 68210a108..e8cd762ad 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 { @@ -131,9 +131,12 @@ public: } }; -void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("lr", std::make_shared(system)); + server_manager->RegisterNamedService("ncm", std::make_shared(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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("nfc:am", std::make_shared(system)); + server_manager->RegisterNamedService("nfc:mf:u", std::make_shared(system)); + server_manager->RegisterNamedService("nfc:user", std::make_shared(system)); + server_manager->RegisterNamedService("nfc:sys", std::make_shared(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 user_interface; }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { - std::make_shared(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("nfp:user", std::make_shared(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(system)->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("ngct:u", std::make_shared(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("nifm:a", system)->InstallAsService(service_manager); - std::make_shared("nifm:s", system)->InstallAsService(service_manager); - std::make_shared("nifm:u", system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("nifm:a", + std::make_shared("nifm:a", system)); + server_manager->RegisterNamedService("nifm:s", + std::make_shared("nifm:s", system)); + server_manager->RegisterNamedService("nifm:u", + std::make_shared("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 { 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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("nim", std::make_shared(system)); + server_manager->RegisterNamedService("nim:eca", std::make_shared(system)); + server_manager->RegisterNamedService("nim:shp", std::make_shared(system)); + server_manager->RegisterNamedService("ntc", std::make_shared(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 #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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("npns:s", std::make_shared(system)); + server_manager->RegisterNamedService("npns:u", std::make_shared(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 f59a1a63d..a9291ed5d 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 { @@ -777,23 +778,26 @@ private: } }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { - - std::make_shared("ns:am2", system)->InstallAsService(service_manager); - std::make_shared("ns:ec", system)->InstallAsService(service_manager); - std::make_shared("ns:rid", system)->InstallAsService(service_manager); - std::make_shared("ns:rt", system)->InstallAsService(service_manager); - std::make_shared("ns:web", system)->InstallAsService(service_manager); - std::make_shared("ns:ro", system)->InstallAsService(service_manager); - - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - - std::make_shared(system)->InstallAsService(service_manager); - - std::make_shared(system, "pl:s")->InstallAsService(service_manager); - std::make_shared(system, "pl:u")->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("ns:am2", std::make_shared("ns:am2", system)); + server_manager->RegisterNamedService("ns:ec", std::make_shared("ns:ec", system)); + server_manager->RegisterNamedService("ns:rid", std::make_shared("ns:rid", system)); + server_manager->RegisterNamedService("ns:rt", std::make_shared("ns:rt", system)); + server_manager->RegisterNamedService("ns:web", std::make_shared("ns:web", system)); + server_manager->RegisterNamedService("ns:ro", std::make_shared("ns:ro", system)); + + server_manager->RegisterNamedService("ns:dev", std::make_shared(system)); + server_manager->RegisterNamedService("ns:su", std::make_shared(system)); + server_manager->RegisterNamedService("ns:vm", std::make_shared(system)); + server_manager->RegisterNamedService("pdm:qry", std::make_shared(system)); + + server_manager->RegisterNamedService("pl:s", + std::make_shared(system, "pl:s")); + server_manager->RegisterNamedService("pl:u", + std::make_shared(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(system); - std::make_shared(system, module_, "nvdrv")->InstallAsService(service_manager); - std::make_shared(system, module_, "nvdrv:a")->InstallAsService(service_manager); - std::make_shared(system, module_, "nvdrv:s")->InstallAsService(service_manager); - std::make_shared(system, module_, "nvdrv:t")->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - nvflinger.SetNVDrvInstance(module_); +void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system) { + auto server_manager = std::make_unique(system); + auto module = std::make_shared(system); + server_manager->RegisterNamedService("nvdrv", std::make_shared(system, module, "nvdrv")); + server_manager->RegisterNamedService("nvdrv:a", + std::make_shared(system, module, "nvdrv:a")); + server_manager->RegisterNamedService("nvdrv:s", + std::make_shared(system, module, "nvdrv:s")); + server_manager->RegisterNamedService("nvdrv:t", + std::make_shared(system, module, "nvdrv:t")); + server_manager->RegisterNamedService("nvmemp", std::make_shared(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> 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 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(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("olsc:u", std::make_shared(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 #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(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("pcie", std::make_shared(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 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(system); + auto module = std::make_shared(); - std::make_shared(system, module, "pctl", - Capability::Application | Capability::SnsPost | Capability::Status | - Capability::StereoVision) - ->InstallAsService(service_manager); + server_manager->RegisterNamedService( + "pctl", std::make_shared(system, module, "pctl", + Capability::Application | Capability::SnsPost | + Capability::Status | Capability::StereoVision)); // TODO(ogniK): Implement remaining capabilities - std::make_shared(system, module, "pctl:a", Capability::None) - ->InstallAsService(service_manager); - std::make_shared(system, module, "pctl:r", Capability::None) - ->InstallAsService(service_manager); - std::make_shared(system, module, "pctl:s", Capability::None) - ->InstallAsService(service_manager); + server_manager->RegisterNamedService( + "pctl:a", std::make_shared(system, module, "pctl:a", Capability::None)); + server_manager->RegisterNamedService( + "pctl:r", std::make_shared(system, module, "pctl:r", Capability::None)); + server_manager->RegisterNamedService( + "pctl:s", std::make_shared(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(system)->InstallAsService(sm); - std::make_shared(system, "clkrst")->InstallAsService(sm); - std::make_shared(system, "clkrst:i")->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("pcv", std::make_shared(system)); + server_manager->RegisterNamedService("clkrst", std::make_shared(system, "clkrst")); + server_manager->RegisterNamedService("clkrst:i", std::make_shared(system, "clkrst:i")); + server_manager->RegisterNamedService("clkrst:a", std::make_shared(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(system)->InstallAsService(system.ServiceManager()); - std::make_shared(system)->InstallAsService(system.ServiceManager()); - std::make_shared(system, system.Kernel().GetProcessList()) - ->InstallAsService(system.ServiceManager()); - std::make_shared(system)->InstallAsService(system.ServiceManager()); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("pm:bm", std::make_shared(system)); + server_manager->RegisterNamedService("pm:dmnt", std::make_shared(system)); + server_manager->RegisterNamedService( + "pm:info", std::make_shared(system, system.Kernel().GetProcessList())); + server_manager->RegisterNamedService("pm:shell", std::make_shared(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("prepo:a", system)->InstallAsService(service_manager); - std::make_shared("prepo:a2", system)->InstallAsService(service_manager); - std::make_shared("prepo:m", system)->InstallAsService(service_manager); - std::make_shared("prepo:s", system)->InstallAsService(service_manager); - std::make_shared("prepo:u", system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("prepo:a", + std::make_shared("prepo:a", system)); + server_manager->RegisterNamedService("prepo:a2", + std::make_shared("prepo:a2", system)); + server_manager->RegisterNamedService("prepo:m", + std::make_shared("prepo:m", system)); + server_manager->RegisterNamedService("prepo:s", + std::make_shared("prepo:s", system)); + server_manager->RegisterNamedService("prepo:u", + std::make_shared("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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("psc:c", std::make_shared(system)); + server_manager->RegisterNamedService("psc:m", std::make_shared(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(system)->InstallAsService(sm); - std::make_shared(system)->InstallAsService(sm); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("psm", std::make_shared(system)); + server_manager->RegisterNamedService("ts", std::make_shared(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..55788ddeb --- /dev/null +++ b/src/core/hle/service/server_manager.cpp @@ -0,0 +1,358 @@ +// 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, + 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(); + } + + // Close event. + m_event->GetReadableEvent().Close(); + m_event->Close(); +} + +void ServerManager::RunServer(std::unique_ptr&& server_manager) { + server_manager->m_system.RunServer(std::move(server_manager)); +} + +Result ServerManager::RegisterSession(Kernel::KServerSession* session, + std::shared_ptr 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&& 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&& 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(); +} + +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 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 wait_types{}; + std::array 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 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(); + std::shared_ptr 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(); + std::shared_ptr 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::Event: { + // Clear event and finish. + R_RETURN(m_event->Clear()); + } + default: { + UNREACHABLE(); + } + } + } +} + +Result ServerManager::OnPortEvent(Kernel::KServerPort* port, + std::shared_ptr&& 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(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&& manager) { + Result rc{ResultSuccess}; + Result service_rc{ResultSuccess}; + + // Try to receive a message. + std::shared_ptr 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)); + + // Complete the request. We have exclusive access to this session. + service_rc = manager->CompleteSyncRequest(session, *context); + + // Send the reply. + rc = 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. + 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(session, std::move(manager)); + } + + // Signal the wakeup event. + m_event->Signal(); + + // We succeeded. + 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..b26557172 --- /dev/null +++ b/src/core/hle/service/server_manager.h @@ -0,0 +1,75 @@ +// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include +#include +#include +#include + +#include "common/polyfill_thread.h" +#include "core/hle/result.h" +#include "core/hle/service/mutex.h" + +namespace Core { +class System; +} + +namespace Kernel { +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 manager); + Result RegisterNamedService(const std::string& service_name, + std::shared_ptr&& handler, + u32 max_sessions = 64); + Result ManageNamedPort(const std::string& service_name, + std::shared_ptr&& handler, + u32 max_sessions = 64); + + Result LoopProcess(); + void StartAdditionalHostThreads(const char* name, size_t num_threads); + + static void RunServer(std::unique_ptr&& server); + +private: + Result LoopProcessImpl(); + Result WaitAndProcessImpl(); + Result OnPortEvent(Kernel::KServerPort* port, + std::shared_ptr&& handler); + Result OnSessionEvent(Kernel::KServerSession* session, + std::shared_ptr&& manager); + +private: + Core::System& m_system; + Mutex m_serve_mutex; + std::mutex m_list_mutex; + + // Guest state tracking + std::map> m_ports{}; + std::map> m_sessions{}; + Kernel::KEvent* m_event{}; + + // Host state tracking + std::atomic m_stopped{}; + std::vector 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, Core::System& system : hos_binder_driver_server{std::make_unique(system)}, nv_flinger{std::make_unique(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 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 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(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("set", std::make_shared(system)); + server_manager->RegisterNamedService("set:cal", std::make_shared(system)); + server_manager->RegisterNamedService("set:fd", std::make_shared(system)); + server_manager->RegisterNamedService("set:sys", std::make_shared(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..0de32b05d 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,7 +23,9 @@ 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(kernel.System()); +} ServiceManager::~ServiceManager() { for (auto& [name, port] : service_ports) { @@ -43,21 +46,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(self, system); - self.controller_interface = std::make_unique(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; @@ -75,6 +69,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,6 +84,8 @@ Result ServiceManager::UnregisterService(const std::string& name) { ResultVal 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); @@ -154,8 +151,7 @@ ResultVal SM::GetServiceImpl(Kernel::HLERequestContext& // Find the named port. auto port_result = service_manager.GetServicePort(name); - auto service = service_manager.GetService(name); - if (port_result.Failed() || !service) { + if (port_result.Failed()) { LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); return port_result.Code(); } @@ -167,7 +163,6 @@ ResultVal 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 +207,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 +227,11 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_) SM::~SM() = default; +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->ManageNamedPort("sm:", std::make_shared(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..22ca720f8 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -4,6 +4,7 @@ #pragma once #include +#include #include #include @@ -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(); @@ -78,6 +76,7 @@ private: std::unique_ptr controller_interface; /// Map of registered services, retrieved using GetServicePort. + std::mutex lock; std::unordered_map registered_services; std::unordered_map service_ports; @@ -85,4 +84,7 @@ private: Kernel::KernelCore& kernel; }; +/// 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 bdb499268..790e28504 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(system, "bsd:s")->InstallAsService(service_manager); - std::make_shared(system, "bsd:u")->InstallAsService(service_manager); - std::make_shared(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); - std::make_shared(system, "nsd:a")->InstallAsService(service_manager); - std::make_shared(system, "nsd:u")->InstallAsService(service_manager); - - std::make_shared(system)->InstallAsService(service_manager); + server_manager->RegisterNamedService("bsd:s", std::make_shared(system, "bsd:s")); + server_manager->RegisterNamedService("bsd:u", std::make_shared(system, "bsd:u")); + server_manager->RegisterNamedService("bsdcfg", std::make_shared(system)); + server_manager->RegisterNamedService("nsd:a", std::make_shared(system, "nsd:a")); + server_manager->RegisterNamedService("nsd:u", std::make_shared(system, "nsd:u")); + server_manager->RegisterNamedService("sfdnsres", std::make_shared(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 31b7dad33..c94e80ef6 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 { @@ -98,7 +94,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 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(system); auto module = std::make_shared(); - std::make_shared(system, module)->InstallAsService(service_manager); - std::make_shared(system, module)->InstallAsService(service_manager); - std::make_shared(system, module)->InstallAsService(service_manager); - std::make_shared(system, module)->InstallAsService(service_manager); - std::make_shared(system, module)->InstallAsService(service_manager); - std::make_shared(system, module)->InstallAsService(service_manager); - std::make_shared(system, module)->InstallAsService(service_manager); + + server_manager->RegisterNamedService("csrng", std::make_shared(system, module)); + server_manager->RegisterNamedService("spl", std::make_shared(system, module)); + server_manager->RegisterNamedService("spl:mig", std::make_shared(system, module)); + server_manager->RegisterNamedService("spl:fs", std::make_shared(system, module)); + server_manager->RegisterNamedService("spl:ssl", std::make_shared(system, module)); + server_manager->RegisterNamedService("spl:es", std::make_shared(system, module)); + server_manager->RegisterNamedService("spl:manu", std::make_shared(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 dcf47083f..57027bdf5 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 { @@ -173,8 +173,11 @@ private: } }; -void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { - std::make_shared(system)->InstallAsService(service_manager); +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); + + server_manager->RegisterNamedService("ssl", std::make_shared(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_, Core::System& syst Module::Interface::~Interface() = default; -void InstallInterfaces(Core::System& system) { +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique(system); auto module{std::make_shared()}; - std::make_shared