summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar liamwhite2023-03-01 10:38:20 -0500
committerGravatar GitHub2023-03-01 10:38:20 -0500
commit97f7a560f3905a1dd6a4e5a0a308ea752004bf08 (patch)
treee60a69f96d16d051220b66e90906a7abeacf1064 /src
parentMerge pull request #9879 from zhaobot/tx-update-20230301024940 (diff)
parentsm:: fix lingering session initialization issues (diff)
downloadyuzu-97f7a560f3905a1dd6a4e5a0a308ea752004bf08.tar.gz
yuzu-97f7a560f3905a1dd6a4e5a0a308ea752004bf08.tar.xz
yuzu-97f7a560f3905a1dd6a4e5a0a308ea752004bf08.zip
Merge pull request #9832 from liamwhite/hle-mp
service: HLE multiprocess
Diffstat (limited to 'src')
-rw-r--r--src/core/CMakeLists.txt6
-rw-r--r--src/core/core.cpp11
-rw-r--r--src/core/core.h5
-rw-r--r--src/core/debugger/debugger.cpp7
-rw-r--r--src/core/debugger/gdbstub.cpp6
-rw-r--r--src/core/hle/ipc_helpers.h12
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp30
-rw-r--r--src/core/hle/kernel/hle_ipc.h55
-rw-r--r--src/core/hle/kernel/k_process.cpp4
-rw-r--r--src/core/hle/kernel/k_thread.cpp20
-rw-r--r--src/core/hle/kernel/k_thread.h4
-rw-r--r--src/core/hle/kernel/kernel.cpp207
-rw-r--r--src/core/hle/kernel/kernel.h69
-rw-r--r--src/core/hle/kernel/service_thread.cpp206
-rw-r--r--src/core/hle/kernel/service_thread.h29
-rw-r--r--src/core/hle/kernel/svc/svc_info.cpp5
-rw-r--r--src/core/hle/kernel/svc/svc_port.cpp51
-rw-r--r--src/core/hle/service/acc/acc.cpp23
-rw-r--r--src/core/hle/service/acc/acc.h3
-rw-r--r--src/core/hle/service/am/am.cpp19
-rw-r--r--src/core/hle/service/am/am.h4
-rw-r--r--src/core/hle/service/aoc/aoc_u.cpp7
-rw-r--r--src/core/hle/service/aoc/aoc_u.h3
-rw-r--r--src/core/hle/service/apm/apm.cpp20
-rw-r--r--src/core/hle/service/apm/apm.h3
-rw-r--r--src/core/hle/service/audio/audin_u.cpp5
-rw-r--r--src/core/hle/service/audio/audio.cpp21
-rw-r--r--src/core/hle/service/audio/audio.h3
-rw-r--r--src/core/hle/service/audio/audout_u.cpp10
-rw-r--r--src/core/hle/service/audio/audren_u.cpp15
-rw-r--r--src/core/hle/service/bcat/bcat_module.cpp26
-rw-r--r--src/core/hle/service/bcat/bcat_module.h3
-rw-r--r--src/core/hle/service/bpc/bpc.cpp11
-rw-r--r--src/core/hle/service/bpc/bpc.h2
-rw-r--r--src/core/hle/service/btdrv/btdrv.cpp10
-rw-r--r--src/core/hle/service/btdrv/btdrv.h3
-rw-r--r--src/core/hle/service/btm/btm.cpp14
-rw-r--r--src/core/hle/service/btm/btm.h2
-rw-r--r--src/core/hle/service/caps/caps.cpp18
-rw-r--r--src/core/hle/service/caps/caps.h3
-rw-r--r--src/core/hle/service/erpt/erpt.cpp11
-rw-r--r--src/core/hle/service/erpt/erpt.h7
-rw-r--r--src/core/hle/service/es/es.cpp8
-rw-r--r--src/core/hle/service/es/es.h7
-rw-r--r--src/core/hle/service/eupld/eupld.cpp11
-rw-r--r--src/core/hle/service/eupld/eupld.h7
-rw-r--r--src/core/hle/service/fatal/fatal.cpp10
-rw-r--r--src/core/hle/service/fatal/fatal.h2
-rw-r--r--src/core/hle/service/fgm/fgm.cpp14
-rw-r--r--src/core/hle/service/fgm/fgm.h6
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp12
-rw-r--r--src/core/hle/service/filesystem/filesystem.h2
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp13
-rw-r--r--src/core/hle/service/friend/friend.cpp22
-rw-r--r--src/core/hle/service/friend/friend.h3
-rw-r--r--src/core/hle/service/glue/glue.cpp23
-rw-r--r--src/core/hle/service/glue/glue.h3
-rw-r--r--src/core/hle/service/grc/grc.cpp9
-rw-r--r--src/core/hle/service/grc/grc.h6
-rw-r--r--src/core/hle/service/hid/hid.cpp21
-rw-r--r--src/core/hle/service/hid/hid.h3
-rw-r--r--src/core/hle/service/jit/jit.cpp12
-rw-r--r--src/core/hle/service/jit/jit.h7
-rw-r--r--src/core/hle/service/kernel_helpers.cpp11
-rw-r--r--src/core/hle/service/kernel_helpers.h1
-rw-r--r--src/core/hle/service/lbl/lbl.cpp8
-rw-r--r--src/core/hle/service/lbl/lbl.h6
-rw-r--r--src/core/hle/service/ldn/ldn.cpp18
-rw-r--r--src/core/hle/service/ldn/ldn.h7
-rw-r--r--src/core/hle/service/ldr/ldr.cpp18
-rw-r--r--src/core/hle/service/ldr/ldr.h7
-rw-r--r--src/core/hle/service/lm/lm.cpp8
-rw-r--r--src/core/hle/service/lm/lm.h3
-rw-r--r--src/core/hle/service/mig/mig.cpp9
-rw-r--r--src/core/hle/service/mig/mig.h6
-rw-r--r--src/core/hle/service/mii/mii.cpp12
-rw-r--r--src/core/hle/service/mii/mii.h6
-rw-r--r--src/core/hle/service/mm/mm_u.cpp8
-rw-r--r--src/core/hle/service/mm/mm_u.h7
-rw-r--r--src/core/hle/service/mnpp/mnpp_app.cpp10
-rw-r--r--src/core/hle/service/mnpp/mnpp_app.h7
-rw-r--r--src/core/hle/service/mutex.cpp43
-rw-r--r--src/core/hle/service/mutex.h31
-rw-r--r--src/core/hle/service/ncm/ncm.cpp11
-rw-r--r--src/core/hle/service/ncm/ncm.h6
-rw-r--r--src/core/hle/service/nfc/nfc.cpp15
-rw-r--r--src/core/hle/service/nfc/nfc.h6
-rw-r--r--src/core/hle/service/nfp/nfp.cpp8
-rw-r--r--src/core/hle/service/nfp/nfp.h2
-rw-r--r--src/core/hle/service/ngct/ngct.cpp8
-rw-r--r--src/core/hle/service/ngct/ngct.h7
-rw-r--r--src/core/hle/service/nifm/nifm.cpp15
-rw-r--r--src/core/hle/service/nifm/nifm.h7
-rw-r--r--src/core/hle/service/nim/nim.cpp15
-rw-r--r--src/core/hle/service/nim/nim.h6
-rw-r--r--src/core/hle/service/npns/npns.cpp11
-rw-r--r--src/core/hle/service/npns/npns.h6
-rw-r--r--src/core/hle/service/ns/ns.cpp38
-rw-r--r--src/core/hle/service/ns/ns.h3
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp23
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.h4
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.cpp2
-rw-r--r--src/core/hle/service/olsc/olsc.cpp9
-rw-r--r--src/core/hle/service/olsc/olsc.h7
-rw-r--r--src/core/hle/service/pcie/pcie.cpp9
-rw-r--r--src/core/hle/service/pcie/pcie.h6
-rw-r--r--src/core/hle/service/pctl/pctl_module.cpp26
-rw-r--r--src/core/hle/service/pctl/pctl_module.h3
-rw-r--r--src/core/hle/service/pcv/pcv.cpp15
-rw-r--r--src/core/hle/service/pcv/pcv.h6
-rw-r--r--src/core/hle/service/pm/pm.cpp16
-rw-r--r--src/core/hle/service/pm/pm.h3
-rw-r--r--src/core/hle/service/prepo/prepo.cpp21
-rw-r--r--src/core/hle/service/prepo/prepo.h6
-rw-r--r--src/core/hle/service/psc/psc.cpp11
-rw-r--r--src/core/hle/service/psc/psc.h2
-rw-r--r--src/core/hle/service/ptm/ptm.cpp10
-rw-r--r--src/core/hle/service/ptm/ptm.h6
-rw-r--r--src/core/hle/service/server_manager.cpp448
-rw-r--r--src/core/hle/service/server_manager.h91
-rw-r--r--src/core/hle/service/service.cpp151
-rw-r--r--src/core/hle/service/service.h19
-rw-r--r--src/core/hle/service/set/settings.cpp15
-rw-r--r--src/core/hle/service/set/settings.h7
-rw-r--r--src/core/hle/service/sm/sm.cpp70
-rw-r--r--src/core/hle/service/sm/sm.h13
-rw-r--r--src/core/hle/service/sm/sm_controller.cpp7
-rw-r--r--src/core/hle/service/sockets/bsd.cpp3
-rw-r--r--src/core/hle/service/sockets/sockets.cpp19
-rw-r--r--src/core/hle/service/sockets/sockets.h7
-rw-r--r--src/core/hle/service/spl/spl_module.cpp20
-rw-r--r--src/core/hle/service/spl/spl_module.h3
-rw-r--r--src/core/hle/service/ssl/ssl.cpp9
-rw-r--r--src/core/hle/service/ssl/ssl.h7
-rw-r--r--src/core/hle/service/time/time.cpp15
-rw-r--r--src/core/hle/service/time/time.h3
-rw-r--r--src/core/hle/service/usb/usb.cpp17
-rw-r--r--src/core/hle/service/usb/usb.h6
-rw-r--r--src/core/hle/service/vi/vi.cpp24
-rw-r--r--src/core/hle/service/vi/vi.h10
-rw-r--r--src/core/memory/cheat_engine.cpp9
141 files changed, 1569 insertions, 1153 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 696a1f9ea..cdebb0bd8 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -293,8 +293,6 @@ add_library(core STATIC
293 hle/kernel/physical_memory.h 293 hle/kernel/physical_memory.h
294 hle/kernel/process_capability.cpp 294 hle/kernel/process_capability.cpp
295 hle/kernel/process_capability.h 295 hle/kernel/process_capability.h
296 hle/kernel/service_thread.cpp
297 hle/kernel/service_thread.h
298 hle/kernel/slab_helpers.h 296 hle/kernel/slab_helpers.h
299 hle/kernel/svc.cpp 297 hle/kernel/svc.cpp
300 hle/kernel/svc.h 298 hle/kernel/svc.h
@@ -684,6 +682,10 @@ add_library(core STATIC
684 hle/service/ptm/ts.h 682 hle/service/ptm/ts.h
685 hle/service/kernel_helpers.cpp 683 hle/service/kernel_helpers.cpp
686 hle/service/kernel_helpers.h 684 hle/service/kernel_helpers.h
685 hle/service/mutex.cpp
686 hle/service/mutex.h
687 hle/service/server_manager.cpp
688 hle/service/server_manager.h
687 hle/service/service.cpp 689 hle/service/service.cpp
688 hle/service/service.h 690 hle/service/service.h
689 hle/service/set/set.cpp 691 hle/service/set/set.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index fb9b25d12..4a1372d15 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -380,9 +380,7 @@ struct System::Impl {
380 gpu_core->NotifyShutdown(); 380 gpu_core->NotifyShutdown();
381 } 381 }
382 382
383 kernel.ShutdownCores(); 383 kernel.SuspendApplication(true);
384 cpu_manager.Shutdown();
385 debugger.reset();
386 if (services) { 384 if (services) {
387 services->KillNVNFlinger(); 385 services->KillNVNFlinger();
388 } 386 }
@@ -398,6 +396,9 @@ struct System::Impl {
398 gpu_core.reset(); 396 gpu_core.reset();
399 host1x_core.reset(); 397 host1x_core.reset();
400 perf_stats.reset(); 398 perf_stats.reset();
399 kernel.ShutdownCores();
400 cpu_manager.Shutdown();
401 debugger.reset();
401 kernel.Shutdown(); 402 kernel.Shutdown();
402 memory.Reset(); 403 memory.Reset();
403 404
@@ -938,6 +939,10 @@ const Network::RoomNetwork& System::GetRoomNetwork() const {
938 return impl->room_network; 939 return impl->room_network;
939} 940}
940 941
942void System::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
943 return impl->kernel.RunServer(std::move(server_manager));
944}
945
941void System::RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback) { 946void System::RegisterExecuteProgramCallback(ExecuteProgramCallback&& callback) {
942 impl->execute_program_callback = std::move(callback); 947 impl->execute_program_callback = std::move(callback);
943} 948}
diff --git a/src/core/core.h b/src/core/core.h
index 0042ac170..91e78672e 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -61,6 +61,8 @@ namespace Glue {
61class ARPManager; 61class ARPManager;
62} 62}
63 63
64class ServerManager;
65
64namespace SM { 66namespace SM {
65class ServiceManager; 67class ServiceManager;
66} // namespace SM 68} // namespace SM
@@ -417,6 +419,9 @@ public:
417 /// Tells if the system debugger is enabled. 419 /// Tells if the system debugger is enabled.
418 [[nodiscard]] bool DebuggerEnabled() const; 420 [[nodiscard]] bool DebuggerEnabled() const;
419 421
422 /// Runs a server instance until shutdown.
423 void RunServer(std::unique_ptr<Service::ServerManager>&& server_manager);
424
420 /// Type used for the frontend to designate a callback for System to re-launch the application 425 /// Type used for the frontend to designate a callback for System to re-launch the application
421 /// using a specified program index. 426 /// using a specified program index.
422 using ExecuteProgramCallback = std::function<void(std::size_t)>; 427 using ExecuteProgramCallback = std::function<void(std::size_t)>;
diff --git a/src/core/debugger/debugger.cpp b/src/core/debugger/debugger.cpp
index a9675df76..a1589fecb 100644
--- a/src/core/debugger/debugger.cpp
+++ b/src/core/debugger/debugger.cpp
@@ -16,6 +16,7 @@
16#include "core/debugger/debugger_interface.h" 16#include "core/debugger/debugger_interface.h"
17#include "core/debugger/gdbstub.h" 17#include "core/debugger/gdbstub.h"
18#include "core/hle/kernel/global_scheduler_context.h" 18#include "core/hle/kernel/global_scheduler_context.h"
19#include "core/hle/kernel/k_process.h"
19#include "core/hle/kernel/k_scheduler.h" 20#include "core/hle/kernel/k_scheduler.h"
20 21
21template <typename Readable, typename Buffer, typename Callback> 22template <typename Readable, typename Buffer, typename Callback>
@@ -284,12 +285,12 @@ private:
284 void UpdateActiveThread() { 285 void UpdateActiveThread() {
285 const auto& threads{ThreadList()}; 286 const auto& threads{ThreadList()};
286 if (std::find(threads.begin(), threads.end(), state->active_thread) == threads.end()) { 287 if (std::find(threads.begin(), threads.end(), state->active_thread) == threads.end()) {
287 state->active_thread = threads[0]; 288 state->active_thread = threads.front();
288 } 289 }
289 } 290 }
290 291
291 const std::vector<Kernel::KThread*>& ThreadList() { 292 const std::list<Kernel::KThread*>& ThreadList() {
292 return system.GlobalSchedulerContext().GetThreadList(); 293 return system.ApplicationProcess()->GetThreadList();
293 } 294 }
294 295
295private: 296private:
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp
index 945ec528e..18afe97e1 100644
--- a/src/core/debugger/gdbstub.cpp
+++ b/src/core/debugger/gdbstub.cpp
@@ -573,7 +573,7 @@ void GDBStub::HandleQuery(std::string_view command) {
573 SendReply(PaginateBuffer(buffer, command.substr(21))); 573 SendReply(PaginateBuffer(buffer, command.substr(21)));
574 } else if (command.starts_with("fThreadInfo")) { 574 } else if (command.starts_with("fThreadInfo")) {
575 // beginning of list 575 // beginning of list
576 const auto& threads = system.GlobalSchedulerContext().GetThreadList(); 576 const auto& threads = system.ApplicationProcess()->GetThreadList();
577 std::vector<std::string> thread_ids; 577 std::vector<std::string> thread_ids;
578 for (const auto& thread : threads) { 578 for (const auto& thread : threads) {
579 thread_ids.push_back(fmt::format("{:x}", thread->GetThreadID())); 579 thread_ids.push_back(fmt::format("{:x}", thread->GetThreadID()));
@@ -587,7 +587,7 @@ void GDBStub::HandleQuery(std::string_view command) {
587 buffer += R"(<?xml version="1.0"?>)"; 587 buffer += R"(<?xml version="1.0"?>)";
588 buffer += "<threads>"; 588 buffer += "<threads>";
589 589
590 const auto& threads = system.GlobalSchedulerContext().GetThreadList(); 590 const auto& threads = system.ApplicationProcess()->GetThreadList();
591 for (const auto* thread : threads) { 591 for (const auto* thread : threads) {
592 auto thread_name{GetThreadName(system, thread)}; 592 auto thread_name{GetThreadName(system, thread)};
593 if (!thread_name) { 593 if (!thread_name) {
@@ -817,7 +817,7 @@ void GDBStub::HandleRcmd(const std::vector<u8>& command) {
817} 817}
818 818
819Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) { 819Kernel::KThread* GDBStub::GetThreadByID(u64 thread_id) {
820 const auto& threads{system.GlobalSchedulerContext().GetThreadList()}; 820 const auto& threads{system.ApplicationProcess()->GetThreadList()};
821 for (auto* thread : threads) { 821 for (auto* thread : threads) {
822 if (thread->GetThreadID() == thread_id) { 822 if (thread->GetThreadID() == thread_id) {
823 return thread; 823 return thread;
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index 38d6cfaff..f8ab55d83 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -15,6 +15,7 @@
15#include "core/hle/kernel/k_resource_limit.h" 15#include "core/hle/kernel/k_resource_limit.h"
16#include "core/hle/kernel/k_session.h" 16#include "core/hle/kernel/k_session.h"
17#include "core/hle/result.h" 17#include "core/hle/result.h"
18#include "core/hle/service/server_manager.h"
18 19
19namespace IPC { 20namespace IPC {
20 21
@@ -145,7 +146,9 @@ public:
145 146
146 template <class T> 147 template <class T>
147 void PushIpcInterface(std::shared_ptr<T> iface) { 148 void PushIpcInterface(std::shared_ptr<T> iface) {
148 if (context->GetManager()->IsDomain()) { 149 auto manager{context->GetManager()};
150
151 if (manager->IsDomain()) {
149 context->AddDomainObject(std::move(iface)); 152 context->AddDomainObject(std::move(iface));
150 } else { 153 } else {
151 kernel.ApplicationProcess()->GetResourceLimit()->Reserve( 154 kernel.ApplicationProcess()->GetResourceLimit()->Reserve(
@@ -153,8 +156,11 @@ public:
153 156
154 auto* session = Kernel::KSession::Create(kernel); 157 auto* session = Kernel::KSession::Create(kernel);
155 session->Initialize(nullptr, iface->GetServiceName()); 158 session->Initialize(nullptr, iface->GetServiceName());
156 iface->RegisterSession(&session->GetServerSession(), 159
157 std::make_shared<Kernel::SessionRequestManager>(kernel)); 160 auto next_manager = std::make_shared<Kernel::SessionRequestManager>(
161 kernel, manager->GetServerManager());
162 next_manager->SetSessionHandler(iface);
163 manager->GetServerManager().RegisterSession(&session->GetServerSession(), next_manager);
158 164
159 context->AddMoveObject(&session->GetClientSession()); 165 context->AddMoveObject(&session->GetClientSession());
160 } 166 }
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 @@
21#include "core/hle/kernel/k_server_session.h" 21#include "core/hle/kernel/k_server_session.h"
22#include "core/hle/kernel/k_thread.h" 22#include "core/hle/kernel/k_thread.h"
23#include "core/hle/kernel/kernel.h" 23#include "core/hle/kernel/kernel.h"
24#include "core/hle/kernel/service_thread.h"
25#include "core/memory.h" 24#include "core/memory.h"
26 25
27namespace Kernel { 26namespace Kernel {
28 27
29SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_, 28SessionRequestHandler::SessionRequestHandler(KernelCore& kernel_, const char* service_name_)
30 ServiceThreadType thread_type) 29 : kernel{kernel_} {}
31 : kernel{kernel_}, service_thread{thread_type == ServiceThreadType::CreateNew
32 ? kernel.CreateServiceThread(service_name_)
33 : kernel.GetDefaultServiceThread()} {}
34 30
35SessionRequestHandler::~SessionRequestHandler() { 31SessionRequestHandler::~SessionRequestHandler() = default;
36 kernel.ReleaseServiceThread(service_thread);
37}
38
39void SessionRequestHandler::AcceptSession(KServerPort* server_port) {
40 auto* server_session = server_port->AcceptSession();
41 ASSERT(server_session != nullptr);
42
43 RegisterSession(server_session, std::make_shared<SessionRequestManager>(kernel));
44}
45
46void SessionRequestHandler::RegisterSession(KServerSession* server_session,
47 std::shared_ptr<SessionRequestManager> manager) {
48 manager->SetSessionHandler(shared_from_this());
49 service_thread.RegisterServerSession(server_session, manager);
50 server_session->Close();
51}
52 32
53SessionRequestManager::SessionRequestManager(KernelCore& kernel_) : kernel{kernel_} {} 33SessionRequestManager::SessionRequestManager(KernelCore& kernel_,
34 Service::ServerManager& server_manager_)
35 : kernel{kernel_}, server_manager{server_manager_} {}
54 36
55SessionRequestManager::~SessionRequestManager() = default; 37SessionRequestManager::~SessionRequestManager() = default;
56 38
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 5bf4f171b..b4364f984 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -31,12 +31,8 @@ class ResponseBuilder;
31 31
32namespace Service { 32namespace Service {
33class ServiceFrameworkBase; 33class ServiceFrameworkBase;
34} 34class ServerManager;
35 35} // namespace Service
36enum class ServiceThreadType {
37 Default,
38 CreateNew,
39};
40 36
41namespace Kernel { 37namespace Kernel {
42 38
@@ -53,9 +49,6 @@ class KThread;
53class KReadableEvent; 49class KReadableEvent;
54class KSession; 50class KSession;
55class SessionRequestManager; 51class SessionRequestManager;
56class ServiceThread;
57
58enum class ThreadWakeupReason;
59 52
60/** 53/**
61 * Interface implemented by HLE Session handlers. 54 * Interface implemented by HLE Session handlers.
@@ -64,8 +57,7 @@ enum class ThreadWakeupReason;
64 */ 57 */
65class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> { 58class SessionRequestHandler : public std::enable_shared_from_this<SessionRequestHandler> {
66public: 59public:
67 SessionRequestHandler(KernelCore& kernel_, const char* service_name_, 60 SessionRequestHandler(KernelCore& kernel_, const char* service_name_);
68 ServiceThreadType thread_type);
69 virtual ~SessionRequestHandler(); 61 virtual ~SessionRequestHandler();
70 62
71 /** 63 /**
@@ -79,17 +71,8 @@ public:
79 virtual Result HandleSyncRequest(Kernel::KServerSession& session, 71 virtual Result HandleSyncRequest(Kernel::KServerSession& session,
80 Kernel::HLERequestContext& context) = 0; 72 Kernel::HLERequestContext& context) = 0;
81 73
82 void AcceptSession(KServerPort* server_port);
83 void RegisterSession(KServerSession* server_session,
84 std::shared_ptr<SessionRequestManager> manager);
85
86 ServiceThread& GetServiceThread() const {
87 return service_thread;
88 }
89
90protected: 74protected:
91 KernelCore& kernel; 75 KernelCore& kernel;
92 ServiceThread& service_thread;
93}; 76};
94 77
95using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>; 78using SessionRequestHandlerWeakPtr = std::weak_ptr<SessionRequestHandler>;
@@ -102,7 +85,7 @@ using SessionRequestHandlerPtr = std::shared_ptr<SessionRequestHandler>;
102 */ 85 */
103class SessionRequestManager final { 86class SessionRequestManager final {
104public: 87public:
105 explicit SessionRequestManager(KernelCore& kernel); 88 explicit SessionRequestManager(KernelCore& kernel, Service::ServerManager& server_manager);
106 ~SessionRequestManager(); 89 ~SessionRequestManager();
107 90
108 bool IsDomain() const { 91 bool IsDomain() const {
@@ -155,23 +138,36 @@ public:
155 session_handler = std::move(handler); 138 session_handler = std::move(handler);
156 } 139 }
157 140
158 ServiceThread& GetServiceThread() const {
159 return session_handler->GetServiceThread();
160 }
161
162 bool HasSessionRequestHandler(const HLERequestContext& context) const; 141 bool HasSessionRequestHandler(const HLERequestContext& context) const;
163 142
164 Result HandleDomainSyncRequest(KServerSession* server_session, HLERequestContext& context); 143 Result HandleDomainSyncRequest(KServerSession* server_session, HLERequestContext& context);
165 Result CompleteSyncRequest(KServerSession* server_session, HLERequestContext& context); 144 Result CompleteSyncRequest(KServerSession* server_session, HLERequestContext& context);
166 145
146 Service::ServerManager& GetServerManager() {
147 return server_manager;
148 }
149
150 // TODO: remove this when sm: is implemented with the proper IUserInterface
151 // abstraction, creating a new C++ handler object for each session:
152
153 bool GetIsInitializedForSm() const {
154 return is_initialized_for_sm;
155 }
156
157 void SetIsInitializedForSm() {
158 is_initialized_for_sm = true;
159 }
160
167private: 161private:
168 bool convert_to_domain{}; 162 bool convert_to_domain{};
169 bool is_domain{}; 163 bool is_domain{};
164 bool is_initialized_for_sm{};
170 SessionRequestHandlerPtr session_handler; 165 SessionRequestHandlerPtr session_handler;
171 std::vector<SessionRequestHandlerPtr> domain_handlers; 166 std::vector<SessionRequestHandlerPtr> domain_handlers;
172 167
173private: 168private:
174 KernelCore& kernel; 169 KernelCore& kernel;
170 Service::ServerManager& server_manager;
175}; 171};
176 172
177/** 173/**
@@ -374,6 +370,14 @@ public:
374 return manager.lock(); 370 return manager.lock();
375 } 371 }
376 372
373 bool GetIsDeferred() const {
374 return is_deferred;
375 }
376
377 void SetIsDeferred(bool is_deferred_ = true) {
378 is_deferred = is_deferred_;
379 }
380
377private: 381private:
378 friend class IPC::ResponseBuilder; 382 friend class IPC::ResponseBuilder;
379 383
@@ -408,6 +412,7 @@ private:
408 u32 domain_offset{}; 412 u32 domain_offset{};
409 413
410 std::weak_ptr<SessionRequestManager> manager{}; 414 std::weak_ptr<SessionRequestManager> manager{};
415 bool is_deferred{false};
411 416
412 KernelCore& kernel; 417 KernelCore& kernel;
413 Core::Memory::Memory& memory; 418 Core::Memory::Memory& memory;
diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp
index 0e4283a0c..d9c1a0eb3 100644
--- a/src/core/hle/kernel/k_process.cpp
+++ b/src/core/hle/kernel/k_process.cpp
@@ -119,7 +119,6 @@ void KProcess::DecrementRunningThreadCount() {
119 119
120 if (const auto prev = num_running_threads--; prev == 1) { 120 if (const auto prev = num_running_threads--; prev == 1) {
121 // TODO(bunnei): Process termination to be implemented when multiprocess is supported. 121 // TODO(bunnei): Process termination to be implemented when multiprocess is supported.
122 UNIMPLEMENTED_MSG("KProcess termination is not implemennted!");
123 } 122 }
124} 123}
125 124
@@ -357,9 +356,6 @@ Result KProcess::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, std:
357 system_resource_size = metadata.GetSystemResourceSize(); 356 system_resource_size = metadata.GetSystemResourceSize();
358 image_size = code_size; 357 image_size = code_size;
359 358
360 // We currently do not support process-specific system resource
361 UNIMPLEMENTED_IF(system_resource_size != 0);
362
363 KScopedResourceReservation memory_reservation( 359 KScopedResourceReservation memory_reservation(
364 resource_limit, LimitableResource::PhysicalMemoryMax, code_size + system_resource_size); 360 resource_limit, LimitableResource::PhysicalMemoryMax, code_size + system_resource_size);
365 if (!memory_reservation.Succeeded()) { 361 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 @@
29#include "core/hle/kernel/k_thread_queue.h" 29#include "core/hle/kernel/k_thread_queue.h"
30#include "core/hle/kernel/k_worker_task_manager.h" 30#include "core/hle/kernel/k_worker_task_manager.h"
31#include "core/hle/kernel/kernel.h" 31#include "core/hle/kernel/kernel.h"
32#include "core/hle/kernel/svc.h"
32#include "core/hle/kernel/svc_results.h" 33#include "core/hle/kernel/svc_results.h"
33#include "core/hle/kernel/svc_types.h" 34#include "core/hle/kernel/svc_types.h"
34#include "core/hle/result.h" 35#include "core/hle/result.h"
@@ -298,6 +299,25 @@ Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThr
298 ThreadType::User, system.GetCpuManager().GetGuestThreadFunc())); 299 ThreadType::User, system.GetCpuManager().GetGuestThreadFunc()));
299} 300}
300 301
302Result KThread::InitializeServiceThread(Core::System& system, KThread* thread,
303 std::function<void()>&& func, s32 prio, s32 virt_core,
304 KProcess* owner) {
305 system.Kernel().GlobalSchedulerContext().AddThread(thread);
306 std::function<void()> func2{[&system, func{std::move(func)}] {
307 // Similar to UserModeThreadStarter.
308 system.Kernel().CurrentScheduler()->OnThreadStart();
309
310 // Run the guest function.
311 func();
312
313 // Exit.
314 Svc::ExitThread(system);
315 }};
316
317 R_RETURN(InitializeThread(thread, {}, {}, {}, prio, virt_core, owner, ThreadType::HighPriority,
318 std::move(func2)));
319}
320
301void KThread::PostDestroy(uintptr_t arg) { 321void KThread::PostDestroy(uintptr_t arg) {
302 KProcess* owner = reinterpret_cast<KProcess*>(arg & ~1ULL); 322 KProcess* owner = reinterpret_cast<KProcess*>(arg & ~1ULL);
303 const bool resource_limit_release_hint = (arg & 1); 323 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:
434 VAddr user_stack_top, s32 prio, s32 virt_core, 434 VAddr user_stack_top, s32 prio, s32 virt_core,
435 KProcess* owner); 435 KProcess* owner);
436 436
437 [[nodiscard]] static Result InitializeServiceThread(Core::System& system, KThread* thread,
438 std::function<void()>&& thread_func,
439 s32 prio, s32 virt_core, KProcess* owner);
440
437public: 441public:
438 struct StackParameters { 442 struct StackParameters {
439 u8 svc_permission[0x10]; 443 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 @@
34#include "core/hle/kernel/k_process.h" 34#include "core/hle/kernel/k_process.h"
35#include "core/hle/kernel/k_resource_limit.h" 35#include "core/hle/kernel/k_resource_limit.h"
36#include "core/hle/kernel/k_scheduler.h" 36#include "core/hle/kernel/k_scheduler.h"
37#include "core/hle/kernel/k_scoped_resource_reservation.h"
37#include "core/hle/kernel/k_shared_memory.h" 38#include "core/hle/kernel/k_shared_memory.h"
38#include "core/hle/kernel/k_system_resource.h" 39#include "core/hle/kernel/k_system_resource.h"
39#include "core/hle/kernel/k_thread.h" 40#include "core/hle/kernel/k_thread.h"
40#include "core/hle/kernel/k_worker_task_manager.h" 41#include "core/hle/kernel/k_worker_task_manager.h"
41#include "core/hle/kernel/kernel.h" 42#include "core/hle/kernel/kernel.h"
42#include "core/hle/kernel/physical_core.h" 43#include "core/hle/kernel/physical_core.h"
43#include "core/hle/kernel/service_thread.h"
44#include "core/hle/result.h" 44#include "core/hle/result.h"
45#include "core/hle/service/server_manager.h"
45#include "core/hle/service/sm/sm.h" 46#include "core/hle/service/sm/sm.h"
46#include "core/memory.h" 47#include "core/memory.h"
47 48
@@ -55,9 +56,7 @@ struct KernelCore::Impl {
55 static constexpr size_t BlockInfoSlabHeapSize = 4000; 56 static constexpr size_t BlockInfoSlabHeapSize = 4000;
56 static constexpr size_t ReservedDynamicPageCount = 64; 57 static constexpr size_t ReservedDynamicPageCount = 64;
57 58
58 explicit Impl(Core::System& system_, KernelCore& kernel_) 59 explicit Impl(Core::System& system_, KernelCore& kernel_) : system{system_} {}
59 : service_threads_manager{1, "ServiceThreadsManager"},
60 service_thread_barrier{2}, system{system_} {}
61 60
62 void SetMulticore(bool is_multi) { 61 void SetMulticore(bool is_multi) {
63 is_multicore = is_multi; 62 is_multicore = is_multi;
@@ -98,8 +97,6 @@ struct KernelCore::Impl {
98 97
99 InitializeHackSharedMemory(); 98 InitializeHackSharedMemory();
100 RegisterHostThread(nullptr); 99 RegisterHostThread(nullptr);
101
102 default_service_thread = &CreateServiceThread(kernel, "DefaultServiceThread");
103 } 100 }
104 101
105 void InitializeCores() { 102 void InitializeCores() {
@@ -140,11 +137,6 @@ struct KernelCore::Impl {
140 137
141 preemption_event = nullptr; 138 preemption_event = nullptr;
142 139
143 for (auto& iter : named_ports) {
144 iter.second->Close();
145 }
146 named_ports.clear();
147
148 exclusive_monitor.reset(); 140 exclusive_monitor.reset();
149 141
150 // Cleanup persistent kernel objects 142 // Cleanup persistent kernel objects
@@ -207,8 +199,9 @@ struct KernelCore::Impl {
207 } 199 }
208 200
209 void CloseServices() { 201 void CloseServices() {
210 // Ensures all service threads gracefully shutdown. 202 // Ensures all servers gracefully shutdown.
211 ClearServiceThreads(); 203 std::scoped_lock lk{server_lock};
204 server_managers.clear();
212 } 205 }
213 206
214 void InitializePhysicalCores() { 207 void InitializePhysicalCores() {
@@ -761,55 +754,6 @@ struct KernelCore::Impl {
761 "HidBus:SharedMemory"); 754 "HidBus:SharedMemory");
762 } 755 }
763 756
764 KClientPort* CreateNamedServicePort(std::string name) {
765 auto search = service_interface_factory.find(name);
766 if (search == service_interface_factory.end()) {
767 UNIMPLEMENTED();
768 return {};
769 }
770
771 return &search->second(system.ServiceManager(), system);
772 }
773
774 void RegisterNamedServiceHandler(std::string name, KServerPort* server_port) {
775 auto search = service_interface_handlers.find(name);
776 if (search == service_interface_handlers.end()) {
777 return;
778 }
779
780 search->second(system.ServiceManager(), server_port);
781 }
782
783 Kernel::ServiceThread& CreateServiceThread(KernelCore& kernel, const std::string& name) {
784 auto* ptr = new ServiceThread(kernel, name);
785
786 service_threads_manager.QueueWork(
787 [this, ptr]() { service_threads.emplace(ptr, std::unique_ptr<ServiceThread>(ptr)); });
788
789 return *ptr;
790 }
791
792 void ReleaseServiceThread(Kernel::ServiceThread& service_thread) {
793 auto* ptr = &service_thread;
794
795 if (ptr == default_service_thread) {
796 // Nothing to do here, the service is using default_service_thread, which will be
797 // released on shutdown.
798 return;
799 }
800
801 service_threads_manager.QueueWork([this, ptr]() { service_threads.erase(ptr); });
802 }
803
804 void ClearServiceThreads() {
805 service_threads_manager.QueueWork([this] {
806 service_threads.clear();
807 default_service_thread = nullptr;
808 service_thread_barrier.Sync();
809 });
810 service_thread_barrier.Sync();
811 }
812
813 std::mutex registered_objects_lock; 757 std::mutex registered_objects_lock;
814 std::mutex registered_in_use_objects_lock; 758 std::mutex registered_in_use_objects_lock;
815 759
@@ -839,14 +783,12 @@ struct KernelCore::Impl {
839 783
840 std::unique_ptr<KObjectNameGlobalData> object_name_global_data; 784 std::unique_ptr<KObjectNameGlobalData> object_name_global_data;
841 785
842 /// Map of named ports managed by the kernel, which can be retrieved using
843 /// the ConnectToPort SVC.
844 std::unordered_map<std::string, ServiceInterfaceFactory> service_interface_factory;
845 std::unordered_map<std::string, ServiceInterfaceHandlerFn> service_interface_handlers;
846 NamedPortTable named_ports;
847 std::unordered_set<KAutoObject*> registered_objects; 786 std::unordered_set<KAutoObject*> registered_objects;
848 std::unordered_set<KAutoObject*> registered_in_use_objects; 787 std::unordered_set<KAutoObject*> registered_in_use_objects;
849 788
789 std::mutex server_lock;
790 std::vector<std::unique_ptr<Service::ServerManager>> server_managers;
791
850 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor; 792 std::unique_ptr<Core::ExclusiveMonitor> exclusive_monitor;
851 std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores; 793 std::array<std::unique_ptr<Kernel::PhysicalCore>, Core::Hardware::NUM_CPU_CORES> cores;
852 794
@@ -881,12 +823,6 @@ struct KernelCore::Impl {
881 // Memory layout 823 // Memory layout
882 std::unique_ptr<KMemoryLayout> memory_layout; 824 std::unique_ptr<KMemoryLayout> memory_layout;
883 825
884 // Threads used for services
885 std::unordered_map<ServiceThread*, std::unique_ptr<ServiceThread>> service_threads;
886 ServiceThread* default_service_thread{};
887 Common::ThreadWorker service_threads_manager;
888 Common::Barrier service_thread_barrier;
889
890 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads{}; 826 std::array<KThread*, Core::Hardware::NUM_CPU_CORES> shutdown_threads{};
891 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{}; 827 std::array<std::unique_ptr<Kernel::KScheduler>, Core::Hardware::NUM_CPU_CORES> schedulers{};
892 828
@@ -1050,23 +986,6 @@ void KernelCore::PrepareReschedule(std::size_t id) {
1050 // TODO: Reimplement, this 986 // TODO: Reimplement, this
1051} 987}
1052 988
1053void KernelCore::RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory) {
1054 impl->service_interface_factory.emplace(std::move(name), factory);
1055}
1056
1057void KernelCore::RegisterInterfaceForNamedService(std::string name,
1058 ServiceInterfaceHandlerFn&& handler) {
1059 impl->service_interface_handlers.emplace(std::move(name), handler);
1060}
1061
1062KClientPort* KernelCore::CreateNamedServicePort(std::string name) {
1063 return impl->CreateNamedServicePort(std::move(name));
1064}
1065
1066void KernelCore::RegisterNamedServiceHandler(std::string name, KServerPort* server_port) {
1067 impl->RegisterNamedServiceHandler(std::move(name), server_port);
1068}
1069
1070void KernelCore::RegisterKernelObject(KAutoObject* object) { 989void KernelCore::RegisterKernelObject(KAutoObject* object) {
1071 std::scoped_lock lk{impl->registered_objects_lock}; 990 std::scoped_lock lk{impl->registered_objects_lock};
1072 impl->registered_objects.insert(object); 991 impl->registered_objects.insert(object);
@@ -1087,8 +1006,19 @@ void KernelCore::UnregisterInUseObject(KAutoObject* object) {
1087 impl->registered_in_use_objects.erase(object); 1006 impl->registered_in_use_objects.erase(object);
1088} 1007}
1089 1008
1090bool KernelCore::IsValidNamedPort(NamedPortTable::const_iterator port) const { 1009void KernelCore::RunServer(std::unique_ptr<Service::ServerManager>&& server_manager) {
1091 return port != impl->named_ports.cend(); 1010 auto* manager = server_manager.get();
1011
1012 {
1013 std::scoped_lock lk{impl->server_lock};
1014 if (impl->is_shutting_down) {
1015 return;
1016 }
1017
1018 impl->server_managers.emplace_back(std::move(server_manager));
1019 }
1020
1021 manager->LoopProcess();
1092} 1022}
1093 1023
1094u32 KernelCore::CreateNewObjectID() { 1024u32 KernelCore::CreateNewObjectID() {
@@ -1127,6 +1057,87 @@ void KernelCore::RegisterHostThread(KThread* existing_thread) {
1127 } 1057 }
1128} 1058}
1129 1059
1060static std::jthread RunHostThreadFunc(KernelCore& kernel, KProcess* process,
1061 std::string&& thread_name, std::function<void()>&& func) {
1062 // Reserve a new thread from the process resource limit.
1063 KScopedResourceReservation thread_reservation(process, LimitableResource::ThreadCountMax);
1064 ASSERT(thread_reservation.Succeeded());
1065
1066 // Initialize the thread.
1067 KThread* thread = KThread::Create(kernel);
1068 ASSERT(R_SUCCEEDED(KThread::InitializeDummyThread(thread, process)));
1069
1070 // Commit the thread reservation.
1071 thread_reservation.Commit();
1072
1073 return std::jthread(
1074 [&kernel, thread, thread_name{std::move(thread_name)}, func{std::move(func)}] {
1075 // Set the thread name.
1076 Common::SetCurrentThreadName(thread_name.c_str());
1077
1078 // Register the thread.
1079 kernel.RegisterHostThread(thread);
1080
1081 // Run the callback.
1082 func();
1083
1084 // Close the thread.
1085 // This will free the process if it is the last reference.
1086 thread->Close();
1087 });
1088}
1089
1090std::jthread KernelCore::RunOnHostCoreProcess(std::string&& process_name,
1091 std::function<void()> func) {
1092 // Make a new process.
1093 KProcess* process = KProcess::Create(*this);
1094 ASSERT(R_SUCCEEDED(KProcess::Initialize(process, System(), "", KProcess::ProcessType::Userland,
1095 GetSystemResourceLimit())));
1096
1097 // Ensure that we don't hold onto any extra references.
1098 SCOPE_EXIT({ process->Close(); });
1099
1100 // Run the host thread.
1101 return RunHostThreadFunc(*this, process, std::move(process_name), std::move(func));
1102}
1103
1104std::jthread KernelCore::RunOnHostCoreThread(std::string&& thread_name,
1105 std::function<void()> func) {
1106 // Get the current process.
1107 KProcess* process = GetCurrentProcessPointer(*this);
1108
1109 // Run the host thread.
1110 return RunHostThreadFunc(*this, process, std::move(thread_name), std::move(func));
1111}
1112
1113void KernelCore::RunOnGuestCoreProcess(std::string&& process_name, std::function<void()> func) {
1114 constexpr s32 ServiceThreadPriority = 16;
1115 constexpr s32 ServiceThreadCore = 3;
1116
1117 // Make a new process.
1118 KProcess* process = KProcess::Create(*this);
1119 ASSERT(R_SUCCEEDED(KProcess::Initialize(process, System(), "", KProcess::ProcessType::Userland,
1120 GetSystemResourceLimit())));
1121
1122 // Ensure that we don't hold onto any extra references.
1123 SCOPE_EXIT({ process->Close(); });
1124
1125 // Reserve a new thread from the process resource limit.
1126 KScopedResourceReservation thread_reservation(process, LimitableResource::ThreadCountMax);
1127 ASSERT(thread_reservation.Succeeded());
1128
1129 // Initialize the thread.
1130 KThread* thread = KThread::Create(*this);
1131 ASSERT(R_SUCCEEDED(KThread::InitializeServiceThread(
1132 System(), thread, std::move(func), ServiceThreadPriority, ServiceThreadCore, process)));
1133
1134 // Commit the thread reservation.
1135 thread_reservation.Commit();
1136
1137 // Begin running the thread.
1138 ASSERT(R_SUCCEEDED(thread->Run()));
1139}
1140
1130u32 KernelCore::GetCurrentHostThreadID() const { 1141u32 KernelCore::GetCurrentHostThreadID() const {
1131 return impl->GetCurrentHostThreadID(); 1142 return impl->GetCurrentHostThreadID();
1132} 1143}
@@ -1271,18 +1282,6 @@ void KernelCore::ExitSVCProfile() {
1271 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]); 1282 MicroProfileLeave(MICROPROFILE_TOKEN(Kernel_SVC), impl->svc_ticks[CurrentPhysicalCoreIndex()]);
1272} 1283}
1273 1284
1274Kernel::ServiceThread& KernelCore::CreateServiceThread(const std::string& name) {
1275 return impl->CreateServiceThread(*this, name);
1276}
1277
1278Kernel::ServiceThread& KernelCore::GetDefaultServiceThread() const {
1279 return *impl->default_service_thread;
1280}
1281
1282void KernelCore::ReleaseServiceThread(Kernel::ServiceThread& service_thread) {
1283 impl->ReleaseServiceThread(service_thread);
1284}
1285
1286Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() { 1285Init::KSlabResourceCounts& KernelCore::SlabResourceCounts() {
1287 return impl->slab_resource_counts; 1286 return impl->slab_resource_counts;
1288} 1287}
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 @@
9#include <string> 9#include <string>
10#include <unordered_map> 10#include <unordered_map>
11#include <vector> 11#include <vector>
12
13#include "common/polyfill_thread.h"
12#include "core/hardware_properties.h" 14#include "core/hardware_properties.h"
13#include "core/hle/kernel/k_auto_object.h" 15#include "core/hle/kernel/k_auto_object.h"
14#include "core/hle/kernel/k_slab_heap.h" 16#include "core/hle/kernel/k_slab_heap.h"
@@ -24,6 +26,10 @@ class CoreTiming;
24struct EventType; 26struct EventType;
25} // namespace Core::Timing 27} // namespace Core::Timing
26 28
29namespace Service {
30class ServerManager;
31}
32
27namespace Service::SM { 33namespace Service::SM {
28class ServiceManager; 34class ServiceManager;
29} 35}
@@ -65,13 +71,6 @@ class KTransferMemory;
65class KWorkerTaskManager; 71class KWorkerTaskManager;
66class KCodeMemory; 72class KCodeMemory;
67class PhysicalCore; 73class PhysicalCore;
68class ServiceThread;
69class Synchronization;
70
71using ServiceInterfaceFactory =
72 std::function<KClientPort&(Service::SM::ServiceManager&, Core::System&)>;
73
74using ServiceInterfaceHandlerFn = std::function<void(Service::SM::ServiceManager&, KServerPort*)>;
75 74
76namespace Init { 75namespace Init {
77struct KSlabResourceCounts; 76struct KSlabResourceCounts;
@@ -80,15 +79,8 @@ struct KSlabResourceCounts;
80template <typename T> 79template <typename T>
81class KSlabHeap; 80class KSlabHeap;
82 81
83using EmuThreadHandle = uintptr_t;
84constexpr EmuThreadHandle EmuThreadHandleInvalid{};
85constexpr EmuThreadHandle EmuThreadHandleReserved{1ULL << 63};
86
87/// Represents a single instance of the kernel. 82/// Represents a single instance of the kernel.
88class KernelCore { 83class KernelCore {
89private:
90 using NamedPortTable = std::unordered_map<std::string, KClientPort*>;
91
92public: 84public:
93 /// Constructs an instance of the kernel using the given System 85 /// Constructs an instance of the kernel using the given System
94 /// instance as a context for any necessary system-related state, 86 /// instance as a context for any necessary system-related state,
@@ -196,18 +188,6 @@ public:
196 188
197 void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size); 189 void InvalidateCpuInstructionCacheRange(VAddr addr, std::size_t size);
198 190
199 /// Registers a named HLE service, passing a factory used to open a port to that service.
200 void RegisterNamedService(std::string name, ServiceInterfaceFactory&& factory);
201
202 /// Registers a setup function for the named HLE service.
203 void RegisterInterfaceForNamedService(std::string name, ServiceInterfaceHandlerFn&& handler);
204
205 /// Opens a port to a service previously registered with RegisterNamedService.
206 KClientPort* CreateNamedServicePort(std::string name);
207
208 /// Accepts a session on a port created by CreateNamedServicePort.
209 void RegisterNamedServiceHandler(std::string name, KServerPort* server_port);
210
211 /// Registers all kernel objects with the global emulation state, this is purely for tracking 191 /// Registers all kernel objects with the global emulation state, this is purely for tracking
212 /// leaks after emulation has been shutdown. 192 /// leaks after emulation has been shutdown.
213 void RegisterKernelObject(KAutoObject* object); 193 void RegisterKernelObject(KAutoObject* object);
@@ -224,8 +204,8 @@ public:
224 /// destroyed during the current emulation session. 204 /// destroyed during the current emulation session.
225 void UnregisterInUseObject(KAutoObject* object); 205 void UnregisterInUseObject(KAutoObject* object);
226 206
227 /// Determines whether or not the given port is a valid named port. 207 // Runs the given server manager until shutdown.
228 bool IsValidNamedPort(NamedPortTable::const_iterator port) const; 208 void RunServer(std::unique_ptr<Service::ServerManager>&& server_manager);
229 209
230 /// Gets the current host_thread/guest_thread pointer. 210 /// Gets the current host_thread/guest_thread pointer.
231 KThread* GetCurrentEmuThread() const; 211 KThread* GetCurrentEmuThread() const;
@@ -242,6 +222,12 @@ public:
242 /// Register the current thread as a non CPU core thread. 222 /// Register the current thread as a non CPU core thread.
243 void RegisterHostThread(KThread* existing_thread = nullptr); 223 void RegisterHostThread(KThread* existing_thread = nullptr);
244 224
225 void RunOnGuestCoreProcess(std::string&& process_name, std::function<void()> func);
226
227 std::jthread RunOnHostCoreProcess(std::string&& process_name, std::function<void()> func);
228
229 std::jthread RunOnHostCoreThread(std::string&& thread_name, std::function<void()> func);
230
245 /// Gets global data for KObjectName. 231 /// Gets global data for KObjectName.
246 KObjectNameGlobalData& ObjectNameGlobalData(); 232 KObjectNameGlobalData& ObjectNameGlobalData();
247 233
@@ -310,33 +296,6 @@ public:
310 296
311 void ExitSVCProfile(); 297 void ExitSVCProfile();
312 298
313 /**
314 * Creates a host thread to execute HLE service requests, which are used to execute service
315 * routines asynchronously. While these are allocated per ServerSession, these need to be owned
316 * and managed outside of ServerSession to avoid a circular dependency. In general, most
317 * services can just use the default service thread, and not need their own host service thread.
318 * See GetDefaultServiceThread.
319 * @param name String name for the ServerSession creating this thread, used for debug
320 * purposes.
321 * @returns A reference to the newly created service thread.
322 */
323 Kernel::ServiceThread& CreateServiceThread(const std::string& name);
324
325 /**
326 * Gets the default host service thread, which executes HLE service requests. Unless service
327 * requests need to block on the host, the default service thread should be used in favor of
328 * creating a new service thread.
329 * @returns A reference to the default service thread.
330 */
331 Kernel::ServiceThread& GetDefaultServiceThread() const;
332
333 /**
334 * Releases a HLE service thread, instructing KernelCore to free it. This should be called when
335 * the ServerSession associated with the thread is destroyed.
336 * @param service_thread Service thread to release.
337 */
338 void ReleaseServiceThread(Kernel::ServiceThread& service_thread);
339
340 /// Workaround for single-core mode when preempting threads while idle. 299 /// Workaround for single-core mode when preempting threads while idle.
341 bool IsPhantomModeForSingleCore() const; 300 bool IsPhantomModeForSingleCore() const;
342 void SetIsPhantomModeForSingleCore(bool value); 301 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 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <functional>
5#include <map>
6#include <mutex>
7#include <thread>
8#include <vector>
9
10#include "common/polyfill_thread.h"
11#include "common/scope_exit.h"
12#include "common/thread.h"
13#include "core/hle/ipc_helpers.h"
14#include "core/hle/kernel/hle_ipc.h"
15#include "core/hle/kernel/k_event.h"
16#include "core/hle/kernel/k_scoped_resource_reservation.h"
17#include "core/hle/kernel/k_session.h"
18#include "core/hle/kernel/k_thread.h"
19#include "core/hle/kernel/kernel.h"
20#include "core/hle/kernel/service_thread.h"
21
22namespace Kernel {
23
24class ServiceThread::Impl final {
25public:
26 explicit Impl(KernelCore& kernel, const std::string& service_name);
27 ~Impl();
28
29 void WaitAndProcessImpl();
30 void SessionClosed(KServerSession* server_session,
31 std::shared_ptr<SessionRequestManager> manager);
32 void LoopProcess();
33
34 void RegisterServerSession(KServerSession* session,
35 std::shared_ptr<SessionRequestManager> manager);
36
37private:
38 KernelCore& kernel;
39 const std::string m_service_name;
40
41 std::jthread m_host_thread{};
42 std::mutex m_session_mutex{};
43 std::map<KServerSession*, std::shared_ptr<SessionRequestManager>> m_sessions{};
44 KEvent* m_wakeup_event{};
45 KThread* m_thread{};
46 std::atomic<bool> m_shutdown_requested{};
47};
48
49void ServiceThread::Impl::WaitAndProcessImpl() {
50 // Create local list of waitable sessions.
51 std::vector<KSynchronizationObject*> objs;
52 std::vector<std::shared_ptr<SessionRequestManager>> managers;
53
54 {
55 // Lock to get the set.
56 std::scoped_lock lk{m_session_mutex};
57
58 // Reserve the needed quantity.
59 objs.reserve(m_sessions.size() + 1);
60 managers.reserve(m_sessions.size());
61
62 // Copy to our local list.
63 for (const auto& [session, manager] : m_sessions) {
64 objs.push_back(session);
65 managers.push_back(manager);
66 }
67
68 // Insert the wakeup event at the end.
69 objs.push_back(&m_wakeup_event->GetReadableEvent());
70 }
71
72 // Wait on the list of sessions.
73 s32 index{-1};
74 Result rc = KSynchronizationObject::Wait(kernel, &index, objs.data(),
75 static_cast<s32>(objs.size()), -1);
76 ASSERT(!rc.IsFailure());
77
78 // If this was the wakeup event, clear it and finish.
79 if (index >= static_cast<s64>(objs.size() - 1)) {
80 m_wakeup_event->Clear();
81 return;
82 }
83
84 // This event is from a server session.
85 auto* server_session = static_cast<KServerSession*>(objs[index]);
86 auto& manager = managers[index];
87
88 // Fetch the HLE request context.
89 std::shared_ptr<HLERequestContext> context;
90 rc = server_session->ReceiveRequest(&context, manager);
91
92 // If the session was closed, handle that.
93 if (rc == ResultSessionClosed) {
94 SessionClosed(server_session, manager);
95
96 // Finish.
97 return;
98 }
99
100 // TODO: handle other cases
101 ASSERT(rc == ResultSuccess);
102
103 // Perform the request.
104 Result service_rc = manager->CompleteSyncRequest(server_session, *context);
105
106 // Reply to the client.
107 rc = server_session->SendReplyHLE();
108
109 if (rc == ResultSessionClosed || service_rc == IPC::ERR_REMOTE_PROCESS_DEAD) {
110 SessionClosed(server_session, manager);
111 return;
112 }
113
114 // TODO: handle other cases
115 ASSERT(rc == ResultSuccess);
116 ASSERT(service_rc == ResultSuccess);
117}
118
119void ServiceThread::Impl::SessionClosed(KServerSession* server_session,
120 std::shared_ptr<SessionRequestManager> manager) {
121 {
122 // Lock to get the set.
123 std::scoped_lock lk{m_session_mutex};
124
125 // Erase the session.
126 ASSERT(m_sessions.erase(server_session) == 1);
127 }
128
129 // Close our reference to the server session.
130 server_session->Close();
131}
132
133void ServiceThread::Impl::LoopProcess() {
134 Common::SetCurrentThreadName(m_service_name.c_str());
135
136 kernel.RegisterHostThread(m_thread);
137
138 while (!m_shutdown_requested.load()) {
139 WaitAndProcessImpl();
140 }
141}
142
143void ServiceThread::Impl::RegisterServerSession(KServerSession* server_session,
144 std::shared_ptr<SessionRequestManager> manager) {
145 // Open the server session.
146 server_session->Open();
147
148 {
149 // Lock to get the set.
150 std::scoped_lock lk{m_session_mutex};
151
152 // Insert the session and manager.
153 m_sessions[server_session] = manager;
154 }
155
156 // Signal the wakeup event.
157 m_wakeup_event->Signal();
158}
159
160ServiceThread::Impl::~Impl() {
161 // Shut down the processing thread.
162 m_shutdown_requested.store(true);
163 m_wakeup_event->Signal();
164 m_host_thread.join();
165
166 // Close all remaining sessions.
167 for (const auto& [server_session, manager] : m_sessions) {
168 server_session->Close();
169 }
170
171 // Destroy remaining managers.
172 m_sessions.clear();
173
174 // Close event.
175 m_wakeup_event->GetReadableEvent().Close();
176 m_wakeup_event->Close();
177
178 // Close thread.
179 m_thread->Close();
180}
181
182ServiceThread::Impl::Impl(KernelCore& kernel_, const std::string& service_name)
183 : kernel{kernel_}, m_service_name{service_name} {
184 // Initialize event.
185 m_wakeup_event = KEvent::Create(kernel);
186 m_wakeup_event->Initialize(nullptr);
187
188 // Initialize thread.
189 m_thread = KThread::Create(kernel);
190 ASSERT(KThread::InitializeDummyThread(m_thread, nullptr).IsSuccess());
191
192 // Start thread.
193 m_host_thread = std::jthread([this] { LoopProcess(); });
194}
195
196ServiceThread::ServiceThread(KernelCore& kernel, const std::string& name)
197 : impl{std::make_unique<Impl>(kernel, name)} {}
198
199ServiceThread::~ServiceThread() = default;
200
201void ServiceThread::RegisterServerSession(KServerSession* session,
202 std::shared_ptr<SessionRequestManager> manager) {
203 impl->RegisterServerSession(session, manager);
204}
205
206} // 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 @@
1// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <memory>
7#include <string>
8
9namespace Kernel {
10
11class HLERequestContext;
12class KernelCore;
13class KSession;
14class SessionRequestManager;
15
16class ServiceThread final {
17public:
18 explicit ServiceThread(KernelCore& kernel, const std::string& name);
19 ~ServiceThread();
20
21 void RegisterServerSession(KServerSession* session,
22 std::shared_ptr<SessionRequestManager> manager);
23
24private:
25 class Impl;
26 std::unique_ptr<Impl> impl;
27};
28
29} // 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
126 *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource(); 126 *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource();
127 return ResultSuccess; 127 return ResultSuccess;
128 128
129 case InfoType::IsApplication:
130 LOG_WARNING(Kernel_SVC, "(STUBBED) Assuming process is application");
131 *result = true;
132 return ResultSuccess;
133
129 case InfoType::FreeThreadCount: 134 case InfoType::FreeThreadCount:
130 *result = process->GetFreeThreadCount(); 135 *result = process->GetFreeThreadCount();
131 return ResultSuccess; 136 return ResultSuccess;
diff --git a/src/core/hle/kernel/svc/svc_port.cpp b/src/core/hle/kernel/svc/svc_port.cpp
index 0b5b4ba2b..78c2a8d17 100644
--- a/src/core/hle/kernel/svc/svc_port.cpp
+++ b/src/core/hle/kernel/svc/svc_port.cpp
@@ -12,56 +12,40 @@
12 12
13namespace Kernel::Svc { 13namespace Kernel::Svc {
14 14
15/// Connect to an OS service given the port name, returns the handle to the port to out 15Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr user_name) {
16Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { 16 // Copy the provided name from user memory to kernel memory.
17 auto& memory = system.Memory(); 17 auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
18 if (!memory.IsValidVirtualAddress(port_name_address)) {
19 LOG_ERROR(Kernel_SVC,
20 "Port Name Address is not a valid virtual address, port_name_address=0x{:016X}",
21 port_name_address);
22 return ResultNotFound;
23 }
24 18
25 static constexpr std::size_t PortNameMaxLength = 11; 19 std::array<char, KObjectName::NameLengthMax> name{};
26 // Read 1 char beyond the max allowed port name to detect names that are too long. 20 std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1);
27 const std::string port_name = memory.ReadCString(port_name_address, PortNameMaxLength + 1);
28 if (port_name.size() > PortNameMaxLength) {
29 LOG_ERROR(Kernel_SVC, "Port name is too long, expected {} but got {}", PortNameMaxLength,
30 port_name.size());
31 return ResultOutOfRange;
32 }
33 21
34 LOG_TRACE(Kernel_SVC, "called port_name={}", port_name); 22 // Validate that the name is valid.
23 R_UNLESS(name[sizeof(name) - 1] == '\x00', ResultOutOfRange);
35 24
36 // Get the current handle table. 25 // Get the current handle table.
37 auto& kernel = system.Kernel(); 26 auto& handle_table = GetCurrentProcess(system.Kernel()).GetHandleTable();
38 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
39 27
40 // Find the client port. 28 // Find the client port.
41 auto port = kernel.CreateNamedServicePort(port_name); 29 auto port = KObjectName::Find<KClientPort>(system.Kernel(), name.data());
42 if (!port) { 30 R_UNLESS(port.IsNotNull(), ResultNotFound);
43 LOG_ERROR(Kernel_SVC, "tried to connect to unknown port: {}", port_name);
44 return ResultNotFound;
45 }
46 31
47 // Reserve a handle for the port. 32 // Reserve a handle for the port.
48 // NOTE: Nintendo really does write directly to the output handle here. 33 // NOTE: Nintendo really does write directly to the output handle here.
49 R_TRY(handle_table.Reserve(out)); 34 R_TRY(handle_table.Reserve(out));
50 auto handle_guard = SCOPE_GUARD({ handle_table.Unreserve(*out); }); 35 ON_RESULT_FAILURE {
36 handle_table.Unreserve(*out);
37 };
51 38
52 // Create a session. 39 // Create a session.
53 KClientSession* session{}; 40 KClientSession* session;
54 R_TRY(port->CreateSession(std::addressof(session))); 41 R_TRY(port->CreateSession(std::addressof(session)));
55 42
56 kernel.RegisterNamedServiceHandler(port_name, &port->GetParent()->GetServerPort());
57
58 // Register the session in the table, close the extra reference. 43 // Register the session in the table, close the extra reference.
59 handle_table.Register(*out, session); 44 handle_table.Register(*out, session);
60 session->Close(); 45 session->Close();
61 46
62 // We succeeded. 47 // We succeeded.
63 handle_guard.Cancel(); 48 R_SUCCEED();
64 return ResultSuccess;
65} 49}
66 50
67Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client, 51Result CreatePort(Core::System& system, Handle* out_server, Handle* out_client,
@@ -78,8 +62,11 @@ Result ConnectToPort(Core::System& system, Handle* out_handle, Handle port) {
78Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name, 62Result ManageNamedPort(Core::System& system, Handle* out_server_handle, uint64_t user_name,
79 int32_t max_sessions) { 63 int32_t max_sessions) {
80 // Copy the provided name from user memory to kernel memory. 64 // Copy the provided name from user memory to kernel memory.
65 auto string_name = system.Memory().ReadCString(user_name, KObjectName::NameLengthMax);
66
67 // Copy the provided name from user memory to kernel memory.
81 std::array<char, KObjectName::NameLengthMax> name{}; 68 std::array<char, KObjectName::NameLengthMax> name{};
82 system.Memory().ReadBlock(user_name, name.data(), sizeof(name)); 69 std::strncpy(name.data(), string_name.c_str(), KObjectName::NameLengthMax - 1);
83 70
84 // Validate that sessions and name are valid. 71 // Validate that sessions and name are valid.
85 R_UNLESS(max_sessions >= 0, ResultOutOfRange); 72 R_UNLESS(max_sessions >= 0, ResultOutOfRange);
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp
index 1241fcdff..c3e5c4462 100644
--- a/src/core/hle/service/acc/acc.cpp
+++ b/src/core/hle/service/acc/acc.cpp
@@ -25,6 +25,7 @@
25#include "core/hle/service/acc/errors.h" 25#include "core/hle/service/acc/errors.h"
26#include "core/hle/service/acc/profile_manager.h" 26#include "core/hle/service/acc/profile_manager.h"
27#include "core/hle/service/glue/glue_manager.h" 27#include "core/hle/service/glue/glue_manager.h"
28#include "core/hle/service/server_manager.h"
28#include "core/loader/loader.h" 29#include "core/loader/loader.h"
29 30
30namespace Service::Account { 31namespace Service::Account {
@@ -950,18 +951,20 @@ Module::Interface::Interface(std::shared_ptr<Module> module_,
950 951
951Module::Interface::~Interface() = default; 952Module::Interface::~Interface() = default;
952 953
953void InstallInterfaces(Core::System& system) { 954void LoopProcess(Core::System& system) {
954 auto module = std::make_shared<Module>(); 955 auto module = std::make_shared<Module>();
955 auto profile_manager = std::make_shared<ProfileManager>(); 956 auto profile_manager = std::make_shared<ProfileManager>();
956 957 auto server_manager = std::make_unique<ServerManager>(system);
957 std::make_shared<ACC_AA>(module, profile_manager, system) 958
958 ->InstallAsService(system.ServiceManager()); 959 server_manager->RegisterNamedService("acc:aa",
959 std::make_shared<ACC_SU>(module, profile_manager, system) 960 std::make_shared<ACC_AA>(module, profile_manager, system));
960 ->InstallAsService(system.ServiceManager()); 961 server_manager->RegisterNamedService("acc:su",
961 std::make_shared<ACC_U0>(module, profile_manager, system) 962 std::make_shared<ACC_SU>(module, profile_manager, system));
962 ->InstallAsService(system.ServiceManager()); 963 server_manager->RegisterNamedService("acc:u0",
963 std::make_shared<ACC_U1>(module, profile_manager, system) 964 std::make_shared<ACC_U0>(module, profile_manager, system));
964 ->InstallAsService(system.ServiceManager()); 965 server_manager->RegisterNamedService("acc:u1",
966 std::make_shared<ACC_U1>(module, profile_manager, system));
967 ServerManager::RunServer(std::move(server_manager));
965} 968}
966 969
967} // namespace Service::Account 970} // 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:
67 }; 67 };
68}; 68};
69 69
70/// Registers all ACC services with the specified service manager. 70void LoopProcess(Core::System& system);
71void InstallInterfaces(Core::System& system);
72 71
73} // namespace Service::Account 72} // namespace Service::Account
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 9a7316e27..3cd772b83 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -32,6 +32,7 @@
32#include "core/hle/service/ns/ns.h" 32#include "core/hle/service/ns/ns.h"
33#include "core/hle/service/nvflinger/nvflinger.h" 33#include "core/hle/service/nvflinger/nvflinger.h"
34#include "core/hle/service/pm/pm.h" 34#include "core/hle/service/pm/pm.h"
35#include "core/hle/service/server_manager.h"
35#include "core/hle/service/sm/sm.h" 36#include "core/hle/service/sm/sm.h"
36#include "core/hle/service/vi/vi.h" 37#include "core/hle/service/vi/vi.h"
37#include "core/memory.h" 38#include "core/memory.h"
@@ -1830,17 +1831,21 @@ void IApplicationFunctions::PrepareForJit(Kernel::HLERequestContext& ctx) {
1830 rb.Push(ResultSuccess); 1831 rb.Push(ResultSuccess);
1831} 1832}
1832 1833
1833void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, 1834void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system) {
1834 Core::System& system) {
1835 auto message_queue = std::make_shared<AppletMessageQueue>(system); 1835 auto message_queue = std::make_shared<AppletMessageQueue>(system);
1836 // Needed on game boot 1836 // Needed on game boot
1837 message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged); 1837 message_queue->PushMessage(AppletMessageQueue::AppletMessage::FocusStateChanged);
1838 1838
1839 std::make_shared<AppletAE>(nvflinger, message_queue, system)->InstallAsService(service_manager); 1839 auto server_manager = std::make_unique<ServerManager>(system);
1840 std::make_shared<AppletOE>(nvflinger, message_queue, system)->InstallAsService(service_manager); 1840
1841 std::make_shared<IdleSys>(system)->InstallAsService(service_manager); 1841 server_manager->RegisterNamedService(
1842 std::make_shared<OMM>(system)->InstallAsService(service_manager); 1842 "appletAE", std::make_shared<AppletAE>(nvflinger, message_queue, system));
1843 std::make_shared<SPSM>(system)->InstallAsService(service_manager); 1843 server_manager->RegisterNamedService(
1844 "appletOE", std::make_shared<AppletOE>(nvflinger, message_queue, system));
1845 server_manager->RegisterNamedService("idle:sys", std::make_shared<IdleSys>(system));
1846 server_manager->RegisterNamedService("omm", std::make_shared<OMM>(system));
1847 server_manager->RegisterNamedService("spsm", std::make_shared<SPSM>(system));
1848 ServerManager::RunServer(std::move(server_manager));
1844} 1849}
1845 1850
1846IHomeMenuFunctions::IHomeMenuFunctions(Core::System& system_) 1851IHomeMenuFunctions::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:
396 ~IProcessWindingController() override; 396 ~IProcessWindingController() override;
397}; 397};
398 398
399/// Registers all AM services with the specified service manager. 399void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system);
400void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
401 Core::System& system);
402 400
403} // namespace Service::AM 401} // namespace Service::AM
diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp
index 1bbf057cb..fed51cfd6 100644
--- a/src/core/hle/service/aoc/aoc_u.cpp
+++ b/src/core/hle/service/aoc/aoc_u.cpp
@@ -17,6 +17,7 @@
17#include "core/hle/ipc_helpers.h" 17#include "core/hle/ipc_helpers.h"
18#include "core/hle/kernel/k_event.h" 18#include "core/hle/kernel/k_event.h"
19#include "core/hle/service/aoc/aoc_u.h" 19#include "core/hle/service/aoc/aoc_u.h"
20#include "core/hle/service/server_manager.h"
20#include "core/loader/loader.h" 21#include "core/loader/loader.h"
21 22
22namespace Service::AOC { 23namespace Service::AOC {
@@ -314,8 +315,10 @@ void AOC_U::CreatePermanentEcPurchasedEventManager(Kernel::HLERequestContext& ct
314 rb.PushIpcInterface<IPurchaseEventManager>(system); 315 rb.PushIpcInterface<IPurchaseEventManager>(system);
315} 316}
316 317
317void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 318void LoopProcess(Core::System& system) {
318 std::make_shared<AOC_U>(system)->InstallAsService(service_manager); 319 auto server_manager = std::make_unique<ServerManager>(system);
320 server_manager->RegisterNamedService("aoc:u", std::make_shared<AOC_U>(system));
321 ServerManager::RunServer(std::move(server_manager));
319} 322}
320 323
321} // namespace Service::AOC 324} // 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:
40 Kernel::KEvent* aoc_change_event; 40 Kernel::KEvent* aoc_change_event;
41}; 41};
42 42
43/// Registers all AOC services with the specified service manager. 43void LoopProcess(Core::System& system);
44void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
45 44
46} // namespace Service::AOC 45} // 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 @@
4#include "core/core.h" 4#include "core/core.h"
5#include "core/hle/service/apm/apm.h" 5#include "core/hle/service/apm/apm.h"
6#include "core/hle/service/apm/apm_interface.h" 6#include "core/hle/service/apm/apm_interface.h"
7#include "core/hle/service/server_manager.h"
7 8
8namespace Service::APM { 9namespace Service::APM {
9 10
10Module::Module() = default; 11Module::Module() = default;
11Module::~Module() = default; 12Module::~Module() = default;
12 13
13void InstallInterfaces(Core::System& system) { 14void LoopProcess(Core::System& system) {
14 auto module_ = std::make_shared<Module>(); 15 auto module = std::make_shared<Module>();
15 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm") 16 auto server_manager = std::make_unique<ServerManager>(system);
16 ->InstallAsService(system.ServiceManager()); 17
17 std::make_shared<APM>(system, module_, system.GetAPMController(), "apm:am") 18 server_manager->RegisterNamedService(
18 ->InstallAsService(system.ServiceManager()); 19 "apm", std::make_shared<APM>(system, module, system.GetAPMController(), "apm"));
19 std::make_shared<APM_Sys>(system, system.GetAPMController()) 20 server_manager->RegisterNamedService(
20 ->InstallAsService(system.ServiceManager()); 21 "apm:am", std::make_shared<APM>(system, module, system.GetAPMController(), "apm:am"));
22 server_manager->RegisterNamedService(
23 "apm:sys", std::make_shared<APM_Sys>(system, system.GetAPMController()));
24 ServerManager::RunServer(std::move(server_manager));
21} 25}
22 26
23} // namespace Service::APM 27} // 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:
15 ~Module(); 15 ~Module();
16}; 16};
17 17
18/// Registers all AM services with the specified service manager. 18void LoopProcess(Core::System& system);
19void InstallInterfaces(Core::System& system);
20 19
21} // namespace Service::APM 20} // 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:
203}; 203};
204 204
205AudInU::AudInU(Core::System& system_) 205AudInU::AudInU(Core::System& system_)
206 : ServiceFramework{system_, "audin:u", ServiceThreadType::CreateNew}, 206 : ServiceFramework{system_, "audin:u"}, service_context{system_, "AudInU"},
207 service_context{system_, "AudInU"}, impl{std::make_unique<AudioCore::AudioIn::Manager>( 207 impl{std::make_unique<AudioCore::AudioIn::Manager>(system_)} {
208 system_)} {
209 // clang-format off 208 // clang-format off
210 static const FunctionInfo functions[] = { 209 static const FunctionInfo functions[] = {
211 {0, &AudInU::ListAudioIns, "ListAudioIns"}, 210 {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 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/core.h"
4#include "core/hle/service/audio/audctl.h" 5#include "core/hle/service/audio/audctl.h"
5#include "core/hle/service/audio/audin_u.h" 6#include "core/hle/service/audio/audin_u.h"
6#include "core/hle/service/audio/audio.h" 7#include "core/hle/service/audio/audio.h"
@@ -9,18 +10,22 @@
9#include "core/hle/service/audio/audrec_u.h" 10#include "core/hle/service/audio/audrec_u.h"
10#include "core/hle/service/audio/audren_u.h" 11#include "core/hle/service/audio/audren_u.h"
11#include "core/hle/service/audio/hwopus.h" 12#include "core/hle/service/audio/hwopus.h"
13#include "core/hle/service/server_manager.h"
12#include "core/hle/service/service.h" 14#include "core/hle/service/service.h"
13 15
14namespace Service::Audio { 16namespace Service::Audio {
15 17
16void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 18void LoopProcess(Core::System& system) {
17 std::make_shared<AudCtl>(system)->InstallAsService(service_manager); 19 auto server_manager = std::make_unique<ServerManager>(system);
18 std::make_shared<AudOutU>(system)->InstallAsService(service_manager); 20
19 std::make_shared<AudInU>(system)->InstallAsService(service_manager); 21 server_manager->RegisterNamedService("audctl", std::make_shared<AudCtl>(system));
20 std::make_shared<AudRecA>(system)->InstallAsService(service_manager); 22 server_manager->RegisterNamedService("audout:u", std::make_shared<AudOutU>(system));
21 std::make_shared<AudRecU>(system)->InstallAsService(service_manager); 23 server_manager->RegisterNamedService("audin:u", std::make_shared<AudInU>(system));
22 std::make_shared<AudRenU>(system)->InstallAsService(service_manager); 24 server_manager->RegisterNamedService("audrec:a", std::make_shared<AudRecA>(system));
23 std::make_shared<HwOpus>(system)->InstallAsService(service_manager); 25 server_manager->RegisterNamedService("audrec:u", std::make_shared<AudRecU>(system));
26 server_manager->RegisterNamedService("audren:u", std::make_shared<AudRenU>(system));
27 server_manager->RegisterNamedService("hwopus", std::make_shared<HwOpus>(system));
28 ServerManager::RunServer(std::move(server_manager));
24} 29}
25 30
26} // namespace Service::Audio 31} // 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;
13 13
14namespace Service::Audio { 14namespace Service::Audio {
15 15
16/// Registers all Audio services with the specified service manager. 16void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 17
19} // namespace Service::Audio 18} // 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:
26 explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager, 26 explicit IAudioOut(Core::System& system_, AudioCore::AudioOut::Manager& manager,
27 size_t session_id, const std::string& device_name, 27 size_t session_id, const std::string& device_name,
28 const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id) 28 const AudioOutParameter& in_params, u32 handle, u64 applet_resource_user_id)
29 : ServiceFramework{system_, "IAudioOut", ServiceThreadType::CreateNew}, 29 : ServiceFramework{system_, "IAudioOut"}, service_context{system_, "IAudioOut"},
30 service_context{system_, "IAudioOut"}, event{service_context.CreateEvent( 30 event{service_context.CreateEvent("AudioOutEvent")},
31 "AudioOutEvent")},
32 impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} { 31 impl{std::make_shared<AudioCore::AudioOut::Out>(system_, manager, event, session_id)} {
33 32
34 // clang-format off 33 // clang-format off
@@ -221,9 +220,8 @@ private:
221}; 220};
222 221
223AudOutU::AudOutU(Core::System& system_) 222AudOutU::AudOutU(Core::System& system_)
224 : ServiceFramework{system_, "audout:u", ServiceThreadType::CreateNew}, 223 : ServiceFramework{system_, "audout:u"}, service_context{system_, "AudOutU"},
225 service_context{system_, "AudOutU"}, impl{std::make_unique<AudioCore::AudioOut::Manager>( 224 impl{std::make_unique<AudioCore::AudioOut::Manager>(system_)} {
226 system_)} {
227 // clang-format off 225 // clang-format off
228 static const FunctionInfo functions[] = { 226 static const FunctionInfo functions[] = {
229 {0, &AudOutU::ListAudioOuts, "ListAudioOuts"}, 227 {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:
35 AudioCore::AudioRendererParameterInternal& params, 35 AudioCore::AudioRendererParameterInternal& params,
36 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size, 36 Kernel::KTransferMemory* transfer_memory, u64 transfer_memory_size,
37 u32 process_handle, u64 applet_resource_user_id, s32 session_id) 37 u32 process_handle, u64 applet_resource_user_id, s32 session_id)
38 : ServiceFramework{system_, "IAudioRenderer", ServiceThreadType::CreateNew}, 38 : ServiceFramework{system_, "IAudioRenderer"}, service_context{system_, "IAudioRenderer"},
39 service_context{system_, "IAudioRenderer"}, rendered_event{service_context.CreateEvent( 39 rendered_event{service_context.CreateEvent("IAudioRendererEvent")}, manager{manager_},
40 "IAudioRendererEvent")}, 40 impl{std::make_unique<Renderer>(system_, manager, rendered_event)} {
41 manager{manager_}, impl{std::make_unique<Renderer>(system_, manager, rendered_event)} {
42 // clang-format off 41 // clang-format off
43 static const FunctionInfo functions[] = { 42 static const FunctionInfo functions[] = {
44 {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"}, 43 {0, &IAudioRenderer::GetSampleRate, "GetSampleRate"},
@@ -243,10 +242,8 @@ class IAudioDevice final : public ServiceFramework<IAudioDevice> {
243public: 242public:
244 explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision, 243 explicit IAudioDevice(Core::System& system_, u64 applet_resource_user_id, u32 revision,
245 u32 device_num) 244 u32 device_num)
246 : ServiceFramework{system_, "IAudioDevice", ServiceThreadType::CreateNew}, 245 : ServiceFramework{system_, "IAudioDevice"}, service_context{system_, "IAudioDevice"},
247 service_context{system_, "IAudioDevice"}, impl{std::make_unique<AudioDevice>( 246 impl{std::make_unique<AudioDevice>(system_, applet_resource_user_id, revision)},
248 system_, applet_resource_user_id,
249 revision)},
250 event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} { 247 event{service_context.CreateEvent(fmt::format("IAudioDeviceEvent-{}", device_num))} {
251 static const FunctionInfo functions[] = { 248 static const FunctionInfo functions[] = {
252 {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"}, 249 {0, &IAudioDevice::ListAudioDeviceName, "ListAudioDeviceName"},
@@ -421,7 +418,7 @@ private:
421}; 418};
422 419
423AudRenU::AudRenU(Core::System& system_) 420AudRenU::AudRenU(Core::System& system_)
424 : ServiceFramework{system_, "audren:u", ServiceThreadType::CreateNew}, 421 : ServiceFramework{system_, "audren:u"},
425 service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} { 422 service_context{system_, "audren:u"}, impl{std::make_unique<Manager>(system_)} {
426 // clang-format off 423 // clang-format off
427 static const FunctionInfo functions[] = { 424 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 @@
15#include "core/hle/service/bcat/bcat.h" 15#include "core/hle/service/bcat/bcat.h"
16#include "core/hle/service/bcat/bcat_module.h" 16#include "core/hle/service/bcat/bcat_module.h"
17#include "core/hle/service/filesystem/filesystem.h" 17#include "core/hle/service/filesystem/filesystem.h"
18#include "core/hle/service/server_manager.h"
18 19
19namespace Service::BCAT { 20namespace Service::BCAT {
20 21
@@ -585,16 +586,23 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu
585 586
586Module::Interface::~Interface() = default; 587Module::Interface::~Interface() = default;
587 588
588void InstallInterfaces(Core::System& system) { 589void LoopProcess(Core::System& system) {
590 auto server_manager = std::make_unique<ServerManager>(system);
589 auto module = std::make_shared<Module>(); 591 auto module = std::make_shared<Module>();
590 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:a") 592
591 ->InstallAsService(system.ServiceManager()); 593 server_manager->RegisterNamedService(
592 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:m") 594 "bcat:a",
593 ->InstallAsService(system.ServiceManager()); 595 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:a"));
594 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:u") 596 server_manager->RegisterNamedService(
595 ->InstallAsService(system.ServiceManager()); 597 "bcat:m",
596 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:s") 598 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:m"));
597 ->InstallAsService(system.ServiceManager()); 599 server_manager->RegisterNamedService(
600 "bcat:u",
601 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:u"));
602 server_manager->RegisterNamedService(
603 "bcat:s",
604 std::make_shared<BCAT>(system, module, system.GetFileSystemController(), "bcat:s"));
605 ServerManager::RunServer(std::move(server_manager));
598} 606}
599 607
600} // namespace Service::BCAT 608} // 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:
39 }; 39 };
40}; 40};
41 41
42/// Registers all BCAT services with the specified service manager. 42void LoopProcess(Core::System& system);
43void InstallInterfaces(Core::System& system);
44 43
45} // namespace BCAT 44} // namespace BCAT
46 45
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 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/bpc/bpc.h" 6#include "core/hle/service/bpc/bpc.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::BPC { 10namespace Service::BPC {
11 11
@@ -54,9 +54,12 @@ public:
54 } 54 }
55}; 55};
56 56
57void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 57void LoopProcess(Core::System& system) {
58 std::make_shared<BPC>(system)->InstallAsService(sm); 58 auto server_manager = std::make_unique<ServerManager>(system);
59 std::make_shared<BPC_R>(system)->InstallAsService(sm); 59
60 server_manager->RegisterNamedService("bpc", std::make_shared<BPC>(system));
61 server_manager->RegisterNamedService("bpc:r", std::make_shared<BPC_R>(system));
62 ServerManager::RunServer(std::move(server_manager));
60} 63}
61 64
62} // namespace Service::BPC 65} // 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;
13 13
14namespace Service::BPC { 14namespace Service::BPC {
15 15
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 16void LoopProcess(Core::System& system);
17 17
18} // namespace Service::BPC 18} // 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 @@
7#include "core/hle/kernel/k_event.h" 7#include "core/hle/kernel/k_event.h"
8#include "core/hle/service/btdrv/btdrv.h" 8#include "core/hle/service/btdrv/btdrv.h"
9#include "core/hle/service/kernel_helpers.h" 9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h" 12#include "core/hle/service/sm/sm.h"
12 13
@@ -196,9 +197,12 @@ public:
196 } 197 }
197}; 198};
198 199
199void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 200void LoopProcess(Core::System& system) {
200 std::make_shared<BtDrv>(system)->InstallAsService(sm); 201 auto server_manager = std::make_unique<ServerManager>(system);
201 std::make_shared<Bt>(system)->InstallAsService(sm); 202
203 server_manager->RegisterNamedService("btdrv", std::make_shared<BtDrv>(system));
204 server_manager->RegisterNamedService("bt", std::make_shared<Bt>(system));
205 ServerManager::RunServer(std::move(server_manager));
202} 206}
203 207
204} // namespace Service::BtDrv 208} // 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;
13 13
14namespace Service::BtDrv { 14namespace Service::BtDrv {
15 15
16/// Registers all BtDrv services with the specified service manager. 16void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 17
19} // namespace Service::BtDrv 18} // namespace Service::BtDrv
diff --git a/src/core/hle/service/btm/btm.cpp b/src/core/hle/service/btm/btm.cpp
index 419da36c4..dbd9d6a88 100644
--- a/src/core/hle/service/btm/btm.cpp
+++ b/src/core/hle/service/btm/btm.cpp
@@ -9,6 +9,7 @@
9#include "core/hle/kernel/k_event.h" 9#include "core/hle/kernel/k_event.h"
10#include "core/hle/service/btm/btm.h" 10#include "core/hle/service/btm/btm.h"
11#include "core/hle/service/kernel_helpers.h" 11#include "core/hle/service/kernel_helpers.h"
12#include "core/hle/service/server_manager.h"
12#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
13 14
14namespace Service::BTM { 15namespace Service::BTM {
@@ -315,11 +316,14 @@ private:
315 } 316 }
316}; 317};
317 318
318void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 319void LoopProcess(Core::System& system) {
319 std::make_shared<BTM>(system)->InstallAsService(sm); 320 auto server_manager = std::make_unique<ServerManager>(system);
320 std::make_shared<BTM_DBG>(system)->InstallAsService(sm); 321
321 std::make_shared<BTM_SYS>(system)->InstallAsService(sm); 322 server_manager->RegisterNamedService("btm", std::make_shared<BTM>(system));
322 std::make_shared<BTM_USR>(system)->InstallAsService(sm); 323 server_manager->RegisterNamedService("btm:dbg", std::make_shared<BTM_DBG>(system));
324 server_manager->RegisterNamedService("btm:sys", std::make_shared<BTM_SYS>(system));
325 server_manager->RegisterNamedService("btm:u", std::make_shared<BTM_USR>(system));
326 ServerManager::RunServer(std::move(server_manager));
323} 327}
324 328
325} // namespace Service::BTM 329} // 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;
13 13
14namespace Service::BTM { 14namespace Service::BTM {
15 15
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 16void LoopProcess(Core::System& system);
17 17
18} // namespace Service::BTM 18} // 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 @@
8#include "core/hle/service/caps/caps_ss.h" 8#include "core/hle/service/caps/caps_ss.h"
9#include "core/hle/service/caps/caps_su.h" 9#include "core/hle/service/caps/caps_su.h"
10#include "core/hle/service/caps/caps_u.h" 10#include "core/hle/service/caps/caps_u.h"
11#include "core/hle/service/server_manager.h"
11#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
12 13
13namespace Service::Capture { 14namespace Service::Capture {
14 15
15void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 16void LoopProcess(Core::System& system) {
16 std::make_shared<CAPS_A>(system)->InstallAsService(sm); 17 auto server_manager = std::make_unique<ServerManager>(system);
17 std::make_shared<CAPS_C>(system)->InstallAsService(sm); 18
18 std::make_shared<CAPS_U>(system)->InstallAsService(sm); 19 server_manager->RegisterNamedService("caps:a", std::make_shared<CAPS_A>(system));
19 std::make_shared<CAPS_SC>(system)->InstallAsService(sm); 20 server_manager->RegisterNamedService("caps:c", std::make_shared<CAPS_C>(system));
20 std::make_shared<CAPS_SS>(system)->InstallAsService(sm); 21 server_manager->RegisterNamedService("caps:u", std::make_shared<CAPS_U>(system));
21 std::make_shared<CAPS_SU>(system)->InstallAsService(sm); 22 server_manager->RegisterNamedService("caps:sc", std::make_shared<CAPS_SC>(system));
23 server_manager->RegisterNamedService("caps:ss", std::make_shared<CAPS_SS>(system));
24 server_manager->RegisterNamedService("caps:su", std::make_shared<CAPS_SU>(system));
25 ServerManager::RunServer(std::move(server_manager));
22} 26}
23 27
24} // namespace Service::Capture 28} // 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 {
90static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30, 90static_assert(sizeof(ApplicationAlbumFileEntry) == 0x30,
91 "ApplicationAlbumFileEntry has incorrect size."); 91 "ApplicationAlbumFileEntry has incorrect size.");
92 92
93/// Registers all Capture services with the specified service manager. 93void LoopProcess(Core::System& system);
94void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
95 94
96} // namespace Service::Capture 95} // 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 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/erpt/erpt.h" 6#include "core/hle/service/erpt/erpt.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h" 9#include "core/hle/service/sm/sm.h"
9 10
@@ -52,9 +53,13 @@ public:
52 } 53 }
53}; 54};
54 55
55void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 56void LoopProcess(Core::System& system) {
56 std::make_shared<ErrorReportContext>(system)->InstallAsService(sm); 57 auto server_manager = std::make_unique<ServerManager>(system);
57 std::make_shared<ErrorReportSession>(system)->InstallAsService(sm); 58
59 server_manager->RegisterNamedService("erpt:c", std::make_shared<ErrorReportContext>(system));
60 server_manager->RegisterNamedService("erpt:r", std::make_shared<ErrorReportSession>(system));
61
62 ServerManager::RunServer(std::move(server_manager));
58} 63}
59 64
60} // namespace Service::ERPT 65} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::ERPT { 10namespace Service::ERPT {
15 11
16/// Registers all ERPT services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 13
19} // namespace Service::ERPT 14} // 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 @@
4#include "core/crypto/key_manager.h" 4#include "core/crypto/key_manager.h"
5#include "core/hle/ipc_helpers.h" 5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/es/es.h" 6#include "core/hle/service/es/es.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8 9
9namespace Service::ES { 10namespace Service::ES {
@@ -307,8 +308,11 @@ private:
307 Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance(); 308 Core::Crypto::KeyManager& keys = Core::Crypto::KeyManager::Instance();
308}; 309};
309 310
310void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 311void LoopProcess(Core::System& system) {
311 std::make_shared<ETicket>(system)->InstallAsService(service_manager); 312 auto server_manager = std::make_unique<ServerManager>(system);
313
314 server_manager->RegisterNamedService("es", std::make_shared<ETicket>(system));
315 ServerManager::RunServer(std::move(server_manager));
312} 316}
313 317
314} // namespace Service::ES 318} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::ES { 10namespace Service::ES {
15 11
16/// Registers all ES services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::ES 14} // 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 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/eupld/eupld.h" 6#include "core/hle/service/eupld/eupld.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::EUPLD { 10namespace Service::EUPLD {
11 11
@@ -44,9 +44,12 @@ public:
44 } 44 }
45}; 45};
46 46
47void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 47void LoopProcess(Core::System& system) {
48 std::make_shared<ErrorUploadContext>(system)->InstallAsService(sm); 48 auto server_manager = std::make_unique<ServerManager>(system);
49 std::make_shared<ErrorUploadRequest>(system)->InstallAsService(sm); 49
50 server_manager->RegisterNamedService("eupld:c", std::make_shared<ErrorUploadContext>(system));
51 server_manager->RegisterNamedService("eupld:r", std::make_shared<ErrorUploadRequest>(system));
52 ServerManager::RunServer(std::move(server_manager));
50} 53}
51 54
52} // namespace Service::EUPLD 55} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::EUPLD { 10namespace Service::EUPLD {
15 11
16/// Registers all EUPLD services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 13
19} // namespace Service::EUPLD 14} // 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 @@
13#include "core/hle/service/fatal/fatal.h" 13#include "core/hle/service/fatal/fatal.h"
14#include "core/hle/service/fatal/fatal_p.h" 14#include "core/hle/service/fatal/fatal_p.h"
15#include "core/hle/service/fatal/fatal_u.h" 15#include "core/hle/service/fatal/fatal_u.h"
16#include "core/hle/service/server_manager.h"
16#include "core/reporter.h" 17#include "core/reporter.h"
17 18
18namespace Service::Fatal { 19namespace Service::Fatal {
@@ -163,10 +164,13 @@ void Module::Interface::ThrowFatalWithCpuContext(Kernel::HLERequestContext& ctx)
163 rb.Push(ResultSuccess); 164 rb.Push(ResultSuccess);
164} 165}
165 166
166void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 167void LoopProcess(Core::System& system) {
168 auto server_manager = std::make_unique<ServerManager>(system);
167 auto module = std::make_shared<Module>(); 169 auto module = std::make_shared<Module>();
168 std::make_shared<Fatal_P>(module, system)->InstallAsService(service_manager); 170
169 std::make_shared<Fatal_U>(module, system)->InstallAsService(service_manager); 171 server_manager->RegisterNamedService("fatal:p", std::make_shared<Fatal_P>(module, system));
172 server_manager->RegisterNamedService("fatal:u", std::make_shared<Fatal_U>(module, system));
173 ServerManager::RunServer(std::move(server_manager));
170} 174}
171 175
172} // namespace Service::Fatal 176} // 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:
28 }; 28 };
29}; 29};
30 30
31void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); 31void LoopProcess(Core::System& system);
32 32
33} // namespace Service::Fatal 33} // 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 @@
5 5
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/fgm/fgm.h" 7#include "core/hle/service/fgm/fgm.h"
8#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h" 10#include "core/hle/service/sm/sm.h"
10 11
@@ -63,11 +64,14 @@ public:
63 } 64 }
64}; 65};
65 66
66void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 67void LoopProcess(Core::System& system) {
67 std::make_shared<FGM>(system, "fgm")->InstallAsService(sm); 68 auto server_manager = std::make_unique<ServerManager>(system);
68 std::make_shared<FGM>(system, "fgm:0")->InstallAsService(sm); 69
69 std::make_shared<FGM>(system, "fgm:9")->InstallAsService(sm); 70 server_manager->RegisterNamedService("fgm", std::make_shared<FGM>(system, "fgm"));
70 std::make_shared<FGM_DBG>(system)->InstallAsService(sm); 71 server_manager->RegisterNamedService("fgm:0", std::make_shared<FGM>(system, "fgm:0"));
72 server_manager->RegisterNamedService("fgm:9", std::make_shared<FGM>(system, "fgm:9"));
73 server_manager->RegisterNamedService("fgm:dbg", std::make_shared<FGM_DBG>(system));
74 ServerManager::RunServer(std::move(server_manager));
71} 75}
72 76
73} // namespace Service::FGM 77} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::FGM { 10namespace Service::FGM {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::FGM 14} // 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 @@
23#include "core/hle/service/filesystem/fsp_ldr.h" 23#include "core/hle/service/filesystem/fsp_ldr.h"
24#include "core/hle/service/filesystem/fsp_pr.h" 24#include "core/hle/service/filesystem/fsp_pr.h"
25#include "core/hle/service/filesystem/fsp_srv.h" 25#include "core/hle/service/filesystem/fsp_srv.h"
26#include "core/hle/service/server_manager.h"
26#include "core/loader/loader.h" 27#include "core/loader/loader.h"
27 28
28namespace Service::FileSystem { 29namespace Service::FileSystem {
@@ -796,10 +797,13 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove
796 } 797 }
797} 798}
798 799
799void InstallInterfaces(Core::System& system) { 800void LoopProcess(Core::System& system) {
800 std::make_shared<FSP_LDR>(system)->InstallAsService(system.ServiceManager()); 801 auto server_manager = std::make_unique<ServerManager>(system);
801 std::make_shared<FSP_PR>(system)->InstallAsService(system.ServiceManager()); 802
802 std::make_shared<FSP_SRV>(system)->InstallAsService(system.ServiceManager()); 803 server_manager->RegisterNamedService("fsp-ldr", std::make_shared<FSP_LDR>(system));
804 server_manager->RegisterNamedService("fsp:pr", std::make_shared<FSP_PR>(system));
805 server_manager->RegisterNamedService("fsp-srv", std::make_shared<FSP_SRV>(system));
806 ServerManager::RunServer(std::move(server_manager));
803} 807}
804 808
805} // namespace Service::FileSystem 809} // 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:
139 Core::System& system; 139 Core::System& system;
140}; 140};
141 141
142void InstallInterfaces(Core::System& system); 142void LoopProcess(Core::System& system);
143 143
144// A class that wraps a VfsDirectory with methods that return ResultVal and Result instead of 144// A class that wraps a VfsDirectory with methods that return ResultVal and Result instead of
145// pointers and booleans. This makes using a VfsDirectory with switch services much easier and 145// 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 {
57class IStorage final : public ServiceFramework<IStorage> { 57class IStorage final : public ServiceFramework<IStorage> {
58public: 58public:
59 explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_) 59 explicit IStorage(Core::System& system_, FileSys::VirtualFile backend_)
60 : ServiceFramework{system_, "IStorage", ServiceThreadType::CreateNew}, 60 : ServiceFramework{system_, "IStorage"}, backend(std::move(backend_)) {
61 backend(std::move(backend_)) {
62 static const FunctionInfo functions[] = { 61 static const FunctionInfo functions[] = {
63 {0, &IStorage::Read, "Read"}, 62 {0, &IStorage::Read, "Read"},
64 {1, nullptr, "Write"}, 63 {1, nullptr, "Write"},
@@ -116,8 +115,7 @@ private:
116class IFile final : public ServiceFramework<IFile> { 115class IFile final : public ServiceFramework<IFile> {
117public: 116public:
118 explicit IFile(Core::System& system_, FileSys::VirtualFile backend_) 117 explicit IFile(Core::System& system_, FileSys::VirtualFile backend_)
119 : ServiceFramework{system_, "IFile", ServiceThreadType::CreateNew}, 118 : ServiceFramework{system_, "IFile"}, backend(std::move(backend_)) {
120 backend(std::move(backend_)) {
121 static const FunctionInfo functions[] = { 119 static const FunctionInfo functions[] = {
122 {0, &IFile::Read, "Read"}, 120 {0, &IFile::Read, "Read"},
123 {1, &IFile::Write, "Write"}, 121 {1, &IFile::Write, "Write"},
@@ -254,8 +252,7 @@ static void BuildEntryIndex(std::vector<FileSys::Entry>& entries, const std::vec
254class IDirectory final : public ServiceFramework<IDirectory> { 252class IDirectory final : public ServiceFramework<IDirectory> {
255public: 253public:
256 explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_) 254 explicit IDirectory(Core::System& system_, FileSys::VirtualDir backend_)
257 : ServiceFramework{system_, "IDirectory", ServiceThreadType::CreateNew}, 255 : ServiceFramework{system_, "IDirectory"}, backend(std::move(backend_)) {
258 backend(std::move(backend_)) {
259 static const FunctionInfo functions[] = { 256 static const FunctionInfo functions[] = {
260 {0, &IDirectory::Read, "Read"}, 257 {0, &IDirectory::Read, "Read"},
261 {1, &IDirectory::GetEntryCount, "GetEntryCount"}, 258 {1, &IDirectory::GetEntryCount, "GetEntryCount"},
@@ -311,8 +308,8 @@ private:
311class IFileSystem final : public ServiceFramework<IFileSystem> { 308class IFileSystem final : public ServiceFramework<IFileSystem> {
312public: 309public:
313 explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_) 310 explicit IFileSystem(Core::System& system_, FileSys::VirtualDir backend_, SizeGetter size_)
314 : ServiceFramework{system_, "IFileSystem", ServiceThreadType::CreateNew}, 311 : ServiceFramework{system_, "IFileSystem"}, backend{std::move(backend_)}, size{std::move(
315 backend{std::move(backend_)}, size{std::move(size_)} { 312 size_)} {
316 static const FunctionInfo functions[] = { 313 static const FunctionInfo functions[] = {
317 {0, &IFileSystem::CreateFile, "CreateFile"}, 314 {0, &IFileSystem::CreateFile, "CreateFile"},
318 {1, &IFileSystem::DeleteFile, "DeleteFile"}, 315 {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 @@
11#include "core/hle/service/friend/friend.h" 11#include "core/hle/service/friend/friend.h"
12#include "core/hle/service/friend/friend_interface.h" 12#include "core/hle/service/friend/friend_interface.h"
13#include "core/hle/service/kernel_helpers.h" 13#include "core/hle/service/kernel_helpers.h"
14#include "core/hle/service/server_manager.h"
14 15
15namespace Service::Friend { 16namespace Service::Friend {
16 17
@@ -335,13 +336,22 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst
335 336
336Module::Interface::~Interface() = default; 337Module::Interface::~Interface() = default;
337 338
338void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 339void LoopProcess(Core::System& system) {
340 auto server_manager = std::make_unique<ServerManager>(system);
339 auto module = std::make_shared<Module>(); 341 auto module = std::make_shared<Module>();
340 std::make_shared<Friend>(module, system, "friend:a")->InstallAsService(service_manager); 342
341 std::make_shared<Friend>(module, system, "friend:m")->InstallAsService(service_manager); 343 server_manager->RegisterNamedService("friend:a",
342 std::make_shared<Friend>(module, system, "friend:s")->InstallAsService(service_manager); 344 std::make_shared<Friend>(module, system, "friend:a"));
343 std::make_shared<Friend>(module, system, "friend:u")->InstallAsService(service_manager); 345 server_manager->RegisterNamedService("friend:m",
344 std::make_shared<Friend>(module, system, "friend:v")->InstallAsService(service_manager); 346 std::make_shared<Friend>(module, system, "friend:m"));
347 server_manager->RegisterNamedService("friend:s",
348 std::make_shared<Friend>(module, system, "friend:s"));
349 server_manager->RegisterNamedService("friend:u",
350 std::make_shared<Friend>(module, system, "friend:u"));
351 server_manager->RegisterNamedService("friend:v",
352 std::make_shared<Friend>(module, system, "friend:v"));
353
354 ServerManager::RunServer(std::move(server_manager));
345} 355}
346 356
347} // namespace Service::Friend 357} // 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:
27 }; 27 };
28}; 28};
29 29
30/// Registers all Friend services with the specified service manager. 30void LoopProcess(Core::System& system);
31void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
32 31
33} // namespace Service::Friend 32} // 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 @@
8#include "core/hle/service/glue/ectx.h" 8#include "core/hle/service/glue/ectx.h"
9#include "core/hle/service/glue/glue.h" 9#include "core/hle/service/glue/glue.h"
10#include "core/hle/service/glue/notif.h" 10#include "core/hle/service/glue/notif.h"
11#include "core/hle/service/server_manager.h"
11 12
12namespace Service::Glue { 13namespace Service::Glue {
13 14
14void InstallInterfaces(Core::System& system) { 15void LoopProcess(Core::System& system) {
16 auto server_manager = std::make_unique<ServerManager>(system);
17
15 // ARP 18 // ARP
16 std::make_shared<ARP_R>(system, system.GetARPManager()) 19 server_manager->RegisterNamedService("arp:r",
17 ->InstallAsService(system.ServiceManager()); 20 std::make_shared<ARP_R>(system, system.GetARPManager()));
18 std::make_shared<ARP_W>(system, system.GetARPManager()) 21 server_manager->RegisterNamedService("arp:w",
19 ->InstallAsService(system.ServiceManager()); 22 std::make_shared<ARP_W>(system, system.GetARPManager()));
20 23
21 // BackGround Task Controller 24 // BackGround Task Controller
22 std::make_shared<BGTC_T>(system)->InstallAsService(system.ServiceManager()); 25 server_manager->RegisterNamedService("bgtc:t", std::make_shared<BGTC_T>(system));
23 std::make_shared<BGTC_SC>(system)->InstallAsService(system.ServiceManager()); 26 server_manager->RegisterNamedService("bgtc:sc", std::make_shared<BGTC_SC>(system));
24 27
25 // Error Context 28 // Error Context
26 std::make_shared<ECTX_AW>(system)->InstallAsService(system.ServiceManager()); 29 server_manager->RegisterNamedService("ectx:aw", std::make_shared<ECTX_AW>(system));
27 30
28 // Notification Services for application 31 // Notification Services for application
29 std::make_shared<NOTIF_A>(system)->InstallAsService(system.ServiceManager()); 32 server_manager->RegisterNamedService("notif:a", std::make_shared<NOTIF_A>(system));
33
34 ServerManager::RunServer(std::move(server_manager));
30} 35}
31 36
32} // namespace Service::Glue 37} // 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;
9 9
10namespace Service::Glue { 10namespace Service::Glue {
11 11
12/// Registers all Glue services with the specified service manager. 12void LoopProcess(Core::System& system);
13void InstallInterfaces(Core::System& system);
14 13
15} // namespace Service::Glue 14} // 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 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/grc/grc.h" 6#include "core/hle/service/grc/grc.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::GRC { 10namespace Service::GRC {
11 11
@@ -26,8 +26,11 @@ public:
26 } 26 }
27}; 27};
28 28
29void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 29void LoopProcess(Core::System& system) {
30 std::make_shared<GRC>(system)->InstallAsService(sm); 30 auto server_manager = std::make_unique<ServerManager>(system);
31
32 server_manager->RegisterNamedService("grc:c", std::make_shared<GRC>(system));
33 ServerManager::RunServer(std::move(server_manager));
31} 34}
32 35
33} // namespace Service::GRC 36} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::GRC { 10namespace Service::GRC {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::GRC 14} // namespace Service::GRC
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 0da67235f..4b5130469 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -18,6 +18,7 @@
18#include "core/hle/service/hid/hidbus.h" 18#include "core/hle/service/hid/hidbus.h"
19#include "core/hle/service/hid/irs.h" 19#include "core/hle/service/hid/irs.h"
20#include "core/hle/service/hid/xcd.h" 20#include "core/hle/service/hid/xcd.h"
21#include "core/hle/service/server_manager.h"
21#include "core/memory.h" 22#include "core/memory.h"
22 23
23#include "core/hle/service/hid/controllers/console_sixaxis.h" 24#include "core/hle/service/hid/controllers/console_sixaxis.h"
@@ -2739,16 +2740,20 @@ private:
2739 } 2740 }
2740}; 2741};
2741 2742
2742void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 2743void LoopProcess(Core::System& system) {
2743 std::make_shared<Hid>(system)->InstallAsService(service_manager); 2744 auto server_manager = std::make_unique<ServerManager>(system);
2744 std::make_shared<HidBus>(system)->InstallAsService(service_manager);
2745 std::make_shared<HidDbg>(system)->InstallAsService(service_manager);
2746 std::make_shared<HidSys>(system)->InstallAsService(service_manager);
2747 2745
2748 std::make_shared<Service::IRS::IRS>(system)->InstallAsService(service_manager); 2746 server_manager->RegisterNamedService("hid", std::make_shared<Hid>(system));
2749 std::make_shared<Service::IRS::IRS_SYS>(system)->InstallAsService(service_manager); 2747 server_manager->RegisterNamedService("hidbus", std::make_shared<HidBus>(system));
2748 server_manager->RegisterNamedService("hid:dbg", std::make_shared<HidDbg>(system));
2749 server_manager->RegisterNamedService("hid:sys", std::make_shared<HidSys>(system));
2750 2750
2751 std::make_shared<XCD_SYS>(system)->InstallAsService(service_manager); 2751 server_manager->RegisterNamedService("irs", std::make_shared<Service::IRS::IRS>(system));
2752 server_manager->RegisterNamedService("irs:sys",
2753 std::make_shared<Service::IRS::IRS_SYS>(system));
2754
2755 server_manager->RegisterNamedService("xcd:sys", std::make_shared<XCD_SYS>(system));
2756 system.RunServer(std::move(server_manager));
2752} 2757}
2753 2758
2754} // namespace Service::HID 2759} // namespace Service::HID
diff --git a/src/core/hle/service/hid/hid.h b/src/core/hle/service/hid/hid.h
index 9ace83129..9563654b6 100644
--- a/src/core/hle/service/hid/hid.h
+++ b/src/core/hle/service/hid/hid.h
@@ -216,7 +216,6 @@ private:
216 KernelHelpers::ServiceContext service_context; 216 KernelHelpers::ServiceContext service_context;
217}; 217};
218 218
219/// Registers all HID services with the specified service manager. 219void LoopProcess(Core::System& system);
220void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
221 220
222} // namespace Service::HID 221} // 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 @@
9#include "core/hle/result.h" 9#include "core/hle/result.h"
10#include "core/hle/service/jit/jit.h" 10#include "core/hle/service/jit/jit.h"
11#include "core/hle/service/jit/jit_context.h" 11#include "core/hle/service/jit/jit_context.h"
12#include "core/hle/service/server_manager.h"
12#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
13#include "core/memory.h" 14#include "core/memory.h"
14 15
@@ -23,8 +24,8 @@ class IJitEnvironment final : public ServiceFramework<IJitEnvironment> {
23public: 24public:
24 explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx, 25 explicit IJitEnvironment(Core::System& system_, Kernel::KProcess& process_, CodeRange user_rx,
25 CodeRange user_ro) 26 CodeRange user_ro)
26 : ServiceFramework{system_, "IJitEnvironment", ServiceThreadType::CreateNew}, 27 : ServiceFramework{system_, "IJitEnvironment"}, process{&process_}, context{
27 process{&process_}, context{system_.Memory()} { 28 system_.Memory()} {
28 // clang-format off 29 // clang-format off
29 static const FunctionInfo functions[] = { 30 static const FunctionInfo functions[] = {
30 {0, &IJitEnvironment::GenerateCode, "GenerateCode"}, 31 {0, &IJitEnvironment::GenerateCode, "GenerateCode"},
@@ -397,8 +398,11 @@ public:
397 } 398 }
398}; 399};
399 400
400void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 401void LoopProcess(Core::System& system) {
401 std::make_shared<JITU>(system)->InstallAsService(sm); 402 auto server_manager = std::make_unique<ServerManager>(system);
403
404 server_manager->RegisterNamedService("jit:u", std::make_shared<JITU>(system));
405 ServerManager::RunServer(std::move(server_manager));
402} 406}
403 407
404} // namespace Service::JIT 408} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::JIT { 10namespace Service::JIT {
15 11
16/// Registers all JIT services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 13
19} // namespace Service::JIT 14} // 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 {
15 15
16ServiceContext::ServiceContext(Core::System& system_, std::string name_) 16ServiceContext::ServiceContext(Core::System& system_, std::string name_)
17 : kernel(system_.Kernel()) { 17 : kernel(system_.Kernel()) {
18 if (process = Kernel::GetCurrentProcessPointer(kernel); process != nullptr) {
19 return;
20 }
21
18 // Create the process. 22 // Create the process.
19 process = Kernel::KProcess::Create(kernel); 23 process = Kernel::KProcess::Create(kernel);
20 ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_), 24 ASSERT(Kernel::KProcess::Initialize(process, system_, std::move(name_),
21 Kernel::KProcess::ProcessType::KernelInternal, 25 Kernel::KProcess::ProcessType::KernelInternal,
22 kernel.GetSystemResourceLimit()) 26 kernel.GetSystemResourceLimit())
23 .IsSuccess()); 27 .IsSuccess());
28 process_created = true;
24} 29}
25 30
26ServiceContext::~ServiceContext() { 31ServiceContext::~ServiceContext() {
27 process->Close(); 32 if (process_created) {
28 process = nullptr; 33 process->Close();
34 process = nullptr;
35 }
29} 36}
30 37
31Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) { 38Kernel::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:
29private: 29private:
30 Kernel::KernelCore& kernel; 30 Kernel::KernelCore& kernel;
31 Kernel::KProcess* process{}; 31 Kernel::KProcess* process{};
32 bool process_created{false};
32}; 33};
33 34
34} // namespace Service::KernelHelpers 35} // 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 @@
7#include "common/logging/log.h" 7#include "common/logging/log.h"
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
9#include "core/hle/service/lbl/lbl.h" 9#include "core/hle/service/lbl/lbl.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h" 12#include "core/hle/service/sm/sm.h"
12 13
@@ -319,8 +320,11 @@ private:
319 bool auto_brightness = false; // TODO(ogniK): Move to system settings 320 bool auto_brightness = false; // TODO(ogniK): Move to system settings
320}; 321};
321 322
322void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 323void LoopProcess(Core::System& system) {
323 std::make_shared<LBL>(system)->InstallAsService(sm); 324 auto server_manager = std::make_unique<ServerManager>(system);
325
326 server_manager->RegisterNamedService("lbl", std::make_shared<LBL>(system));
327 ServerManager::RunServer(std::move(server_manager));
324} 328}
325 329
326} // namespace Service::LBL 330} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::LBL { 10namespace Service::LBL {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::LBL 14} // 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 @@
8#include "core/hle/service/ldn/ldn.h" 8#include "core/hle/service/ldn/ldn.h"
9#include "core/hle/service/ldn/ldn_results.h" 9#include "core/hle/service/ldn/ldn_results.h"
10#include "core/hle/service/ldn/ldn_types.h" 10#include "core/hle/service/ldn/ldn_types.h"
11#include "core/hle/service/server_manager.h"
11#include "core/internal_network/network.h" 12#include "core/internal_network/network.h"
12#include "core/internal_network/network_interface.h" 13#include "core/internal_network/network_interface.h"
13#include "network/network.h" 14#include "network/network.h"
@@ -106,7 +107,7 @@ class IUserLocalCommunicationService final
106 : public ServiceFramework<IUserLocalCommunicationService> { 107 : public ServiceFramework<IUserLocalCommunicationService> {
107public: 108public:
108 explicit IUserLocalCommunicationService(Core::System& system_) 109 explicit IUserLocalCommunicationService(Core::System& system_)
109 : ServiceFramework{system_, "IUserLocalCommunicationService", ServiceThreadType::CreateNew}, 110 : ServiceFramework{system_, "IUserLocalCommunicationService"},
110 service_context{system, "IUserLocalCommunicationService"}, 111 service_context{system, "IUserLocalCommunicationService"},
111 room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} { 112 room_network{system_.GetRoomNetwork()}, lan_discovery{room_network} {
112 // clang-format off 113 // clang-format off
@@ -730,12 +731,15 @@ public:
730 } 731 }
731}; 732};
732 733
733void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 734void LoopProcess(Core::System& system) {
734 std::make_shared<LDNM>(system)->InstallAsService(sm); 735 auto server_manager = std::make_unique<ServerManager>(system);
735 std::make_shared<LDNS>(system)->InstallAsService(sm); 736
736 std::make_shared<LDNU>(system)->InstallAsService(sm); 737 server_manager->RegisterNamedService("ldn:m", std::make_shared<LDNM>(system));
737 std::make_shared<LP2PAPP>(system)->InstallAsService(sm); 738 server_manager->RegisterNamedService("ldn:s", std::make_shared<LDNS>(system));
738 std::make_shared<LP2PSYS>(system)->InstallAsService(sm); 739 server_manager->RegisterNamedService("ldn:u", std::make_shared<LDNU>(system));
740 server_manager->RegisterNamedService("lp2p:app", std::make_shared<LP2PAPP>(system));
741 server_manager->RegisterNamedService("lp2p:sys", std::make_shared<LP2PSYS>(system));
742 ServerManager::RunServer(std::move(server_manager));
739} 743}
740 744
741} // namespace Service::LDN 745} // 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 {
13class System; 13class System;
14} 14}
15 15
16namespace Service::SM {
17class ServiceManager;
18}
19
20namespace Service::LDN { 16namespace Service::LDN {
21 17
22/// Registers all LDN services with the specified service manager. 18void LoopProcess(Core::System& system);
23void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
24 19
25} // namespace Service::LDN 20} // 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 @@
14#include "core/hle/kernel/svc_results.h" 14#include "core/hle/kernel/svc_results.h"
15#include "core/hle/kernel/svc_types.h" 15#include "core/hle/kernel/svc_types.h"
16#include "core/hle/service/ldr/ldr.h" 16#include "core/hle/service/ldr/ldr.h"
17#include "core/hle/service/server_manager.h"
17#include "core/hle/service/service.h" 18#include "core/hle/service/service.h"
18#include "core/loader/nro.h" 19#include "core/loader/nro.h"
19#include "core/memory.h" 20#include "core/memory.h"
@@ -159,8 +160,7 @@ public:
159 160
160class RelocatableObject final : public ServiceFramework<RelocatableObject> { 161class RelocatableObject final : public ServiceFramework<RelocatableObject> {
161public: 162public:
162 explicit RelocatableObject(Core::System& system_) 163 explicit RelocatableObject(Core::System& system_) : ServiceFramework{system_, "ldr:ro"} {
163 : ServiceFramework{system_, "ldr:ro", ServiceThreadType::CreateNew} {
164 // clang-format off 164 // clang-format off
165 static const FunctionInfo functions[] = { 165 static const FunctionInfo functions[] = {
166 {0, &RelocatableObject::LoadModule, "LoadModule"}, 166 {0, &RelocatableObject::LoadModule, "LoadModule"},
@@ -682,11 +682,15 @@ private:
682 } 682 }
683}; 683};
684 684
685void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 685void LoopProcess(Core::System& system) {
686 std::make_shared<DebugMonitor>(system)->InstallAsService(sm); 686 auto server_manager = std::make_unique<ServerManager>(system);
687 std::make_shared<ProcessManager>(system)->InstallAsService(sm); 687
688 std::make_shared<Shell>(system)->InstallAsService(sm); 688 server_manager->RegisterNamedService("ldr:dmnt", std::make_shared<DebugMonitor>(system));
689 std::make_shared<RelocatableObject>(system)->InstallAsService(sm); 689 server_manager->RegisterNamedService("ldr:pm", std::make_shared<ProcessManager>(system));
690 server_manager->RegisterNamedService("ldr:shel", std::make_shared<Shell>(system));
691 server_manager->RegisterNamedService("ldr:ro", std::make_shared<RelocatableObject>(system));
692
693 ServerManager::RunServer(std::move(server_manager));
690} 694}
691 695
692} // namespace Service::LDR 696} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::LDR { 10namespace Service::LDR {
15 11
16/// Registers all LDR services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& sm, Core::System& system);
18 13
19} // namespace Service::LDR 14} // 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 @@
10#include "core/core.h" 10#include "core/core.h"
11#include "core/hle/ipc_helpers.h" 11#include "core/hle/ipc_helpers.h"
12#include "core/hle/service/lm/lm.h" 12#include "core/hle/service/lm/lm.h"
13#include "core/hle/service/server_manager.h"
13#include "core/hle/service/service.h" 14#include "core/hle/service/service.h"
14 15
15namespace Service::LM { 16namespace Service::LM {
@@ -351,8 +352,11 @@ private:
351 } 352 }
352}; 353};
353 354
354void InstallInterfaces(Core::System& system) { 355void LoopProcess(Core::System& system) {
355 std::make_shared<LM>(system)->InstallAsService(system.ServiceManager()); 356 auto server_manager = std::make_unique<ServerManager>(system);
357
358 server_manager->RegisterNamedService("lm", std::make_shared<LM>(system));
359 ServerManager::RunServer(std::move(server_manager));
356} 360}
357 361
358} // namespace Service::LM 362} // 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;
9 9
10namespace Service::LM { 10namespace Service::LM {
11 11
12/// Registers all LM services with the specified service manager. 12void LoopProcess(Core::System& system);
13void InstallInterfaces(Core::System& system);
14 13
15} // namespace Service::LM 14} // 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 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/mig/mig.h" 6#include "core/hle/service/mig/mig.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::Migration { 10namespace Service::Migration {
11 11
@@ -32,8 +32,11 @@ public:
32 } 32 }
33}; 33};
34 34
35void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 35void LoopProcess(Core::System& system) {
36 std::make_shared<MIG_USR>(system)->InstallAsService(sm); 36 auto server_manager = std::make_unique<ServerManager>(system);
37
38 server_manager->RegisterNamedService("mig:user", std::make_shared<MIG_USR>(system));
39 ServerManager::RunServer(std::move(server_manager));
37} 40}
38 41
39} // namespace Service::Migration 42} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::Migration { 10namespace Service::Migration {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::Migration 14} // 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 @@
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/mii/mii.h" 8#include "core/hle/service/mii/mii.h"
9#include "core/hle/service/mii/mii_manager.h" 9#include "core/hle/service/mii/mii_manager.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
11#include "core/hle/service/sm/sm.h"
12 12
13namespace Service::Mii { 13namespace Service::Mii {
14 14
@@ -310,11 +310,13 @@ public:
310 } 310 }
311}; 311};
312 312
313void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 313void LoopProcess(Core::System& system) {
314 std::make_shared<MiiDBModule>(system, "mii:e")->InstallAsService(sm); 314 auto server_manager = std::make_unique<ServerManager>(system);
315 std::make_shared<MiiDBModule>(system, "mii:u")->InstallAsService(sm);
316 315
317 std::make_shared<MiiImg>(system)->InstallAsService(sm); 316 server_manager->RegisterNamedService("mii:e", std::make_shared<MiiDBModule>(system, "mii:e"));
317 server_manager->RegisterNamedService("mii:u", std::make_shared<MiiDBModule>(system, "mii:u"));
318 server_manager->RegisterNamedService("miiimg", std::make_shared<MiiImg>(system));
319 ServerManager::RunServer(std::move(server_manager));
318} 320}
319 321
320} // namespace Service::Mii 322} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::Mii { 10namespace Service::Mii {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::Mii 14} // 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 @@
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h" 5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/mm/mm_u.h" 6#include "core/hle/service/mm/mm_u.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/sm/sm.h" 8#include "core/hle/service/sm/sm.h"
8 9
9namespace Service::MM { 10namespace Service::MM {
@@ -103,8 +104,11 @@ private:
103 u32 id{1}; 104 u32 id{1};
104}; 105};
105 106
106void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 107void LoopProcess(Core::System& system) {
107 std::make_shared<MM_U>(system)->InstallAsService(service_manager); 108 auto server_manager = std::make_unique<ServerManager>(system);
109
110 server_manager->RegisterNamedService("mm:u", std::make_shared<MM_U>(system));
111 ServerManager::RunServer(std::move(server_manager));
108} 112}
109 113
110} // namespace Service::MM 114} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::MM { 10namespace Service::MM {
15 11
16/// Registers all MM services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::MM 14} // 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 @@
4#include "common/logging/log.h" 4#include "common/logging/log.h"
5#include "core/hle/ipc_helpers.h" 5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/mnpp/mnpp_app.h" 6#include "core/hle/service/mnpp/mnpp_app.h"
7#include "core/hle/service/sm/sm.h" 7#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h"
8 9
9namespace Service::MNPP { 10namespace Service::MNPP {
10 11
@@ -37,8 +38,11 @@ private:
37 } 38 }
38}; 39};
39 40
40void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 41void LoopProcess(Core::System& system) {
41 std::make_shared<MNPP_APP>(system)->InstallAsService(service_manager); 42 auto server_manager = std::make_unique<ServerManager>(system);
43
44 server_manager->RegisterNamedService("mnpp:app", std::make_shared<MNPP_APP>(system));
45 ServerManager::RunServer(std::move(server_manager));
42} 46}
43 47
44} // namespace Service::MNPP 48} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::MNPP { 10namespace Service::MNPP {
15 11
16/// Registers all MNPP services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::MNPP 14} // 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 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/core.h"
5#include "core/hle/kernel/k_event.h"
6#include "core/hle/kernel/k_synchronization_object.h"
7#include "core/hle/service/mutex.h"
8
9namespace Service {
10
11Mutex::Mutex(Core::System& system) : m_system(system) {
12 m_event = Kernel::KEvent::Create(system.Kernel());
13 m_event->Initialize(nullptr);
14
15 ASSERT(R_SUCCEEDED(m_event->Signal()));
16}
17
18Mutex::~Mutex() {
19 m_event->GetReadableEvent().Close();
20 m_event->Close();
21}
22
23void Mutex::lock() {
24 // Infinitely retry until we successfully clear the event.
25 while (R_FAILED(m_event->GetReadableEvent().Reset())) {
26 s32 index;
27 Kernel::KSynchronizationObject* obj = &m_event->GetReadableEvent();
28
29 // The event was already cleared!
30 // Wait for it to become signaled again.
31 ASSERT(R_SUCCEEDED(
32 Kernel::KSynchronizationObject::Wait(m_system.Kernel(), &index, &obj, 1, -1)));
33 }
34
35 // We successfully cleared the event, and now have exclusive ownership.
36}
37
38void Mutex::unlock() {
39 // Unlock.
40 ASSERT(R_SUCCEEDED(m_event->Signal()));
41}
42
43} // 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 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "common/common_types.h"
7
8namespace Core {
9class System;
10}
11
12namespace Kernel {
13class KEvent;
14}
15
16namespace Service {
17
18class Mutex {
19public:
20 explicit Mutex(Core::System& system);
21 ~Mutex();
22
23 void lock();
24 void unlock();
25
26private:
27 Core::System& m_system;
28 Kernel::KEvent* m_event{};
29};
30
31} // namespace Service
diff --git a/src/core/hle/service/ncm/ncm.cpp b/src/core/hle/service/ncm/ncm.cpp
index 4c66cfeba..5ab24dc34 100644
--- a/src/core/hle/service/ncm/ncm.cpp
+++ b/src/core/hle/service/ncm/ncm.cpp
@@ -6,8 +6,8 @@
6#include "core/file_sys/romfs_factory.h" 6#include "core/file_sys/romfs_factory.h"
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/ncm/ncm.h" 8#include "core/hle/service/ncm/ncm.h"
9#include "core/hle/service/server_manager.h"
9#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
10#include "core/hle/service/sm/sm.h"
11 11
12namespace Service::NCM { 12namespace Service::NCM {
13 13
@@ -132,9 +132,12 @@ public:
132 } 132 }
133}; 133};
134 134
135void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 135void LoopProcess(Core::System& system) {
136 std::make_shared<LR>(system)->InstallAsService(sm); 136 auto server_manager = std::make_unique<ServerManager>(system);
137 std::make_shared<NCM>(system)->InstallAsService(sm); 137
138 server_manager->RegisterNamedService("lr", std::make_shared<LR>(system));
139 server_manager->RegisterNamedService("ncm", std::make_shared<NCM>(system));
140 ServerManager::RunServer(std::move(server_manager));
138} 141}
139 142
140} // namespace Service::NCM 143} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NCM { 10namespace Service::NCM {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::NCM 14} // 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 @@
9#include "core/hle/service/nfc/mifare_user.h" 9#include "core/hle/service/nfc/mifare_user.h"
10#include "core/hle/service/nfc/nfc.h" 10#include "core/hle/service/nfc/nfc.h"
11#include "core/hle/service/nfc/nfc_user.h" 11#include "core/hle/service/nfc/nfc_user.h"
12#include "core/hle/service/server_manager.h"
12#include "core/hle/service/service.h" 13#include "core/hle/service/service.h"
13#include "core/hle/service/sm/sm.h"
14 14
15namespace Service::NFC { 15namespace Service::NFC {
16 16
@@ -154,11 +154,14 @@ private:
154 } 154 }
155}; 155};
156 156
157void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 157void LoopProcess(Core::System& system) {
158 std::make_shared<NFC_AM>(system)->InstallAsService(sm); 158 auto server_manager = std::make_unique<ServerManager>(system);
159 std::make_shared<NFC_MF_U>(system)->InstallAsService(sm); 159
160 std::make_shared<NFC_U>(system)->InstallAsService(sm); 160 server_manager->RegisterNamedService("nfc:am", std::make_shared<NFC_AM>(system));
161 std::make_shared<NFC_SYS>(system)->InstallAsService(sm); 161 server_manager->RegisterNamedService("nfc:mf:u", std::make_shared<NFC_MF_U>(system));
162 server_manager->RegisterNamedService("nfc:user", std::make_shared<NFC_U>(system));
163 server_manager->RegisterNamedService("nfc:sys", std::make_shared<NFC_SYS>(system));
164 ServerManager::RunServer(std::move(server_manager));
162} 165}
163 166
164} // namespace Service::NFC 167} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NFC { 10namespace Service::NFC {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::NFC 14} // 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 @@
5#include "core/hle/ipc_helpers.h" 5#include "core/hle/ipc_helpers.h"
6#include "core/hle/service/nfp/nfp.h" 6#include "core/hle/service/nfp/nfp.h"
7#include "core/hle/service/nfp/nfp_user.h" 7#include "core/hle/service/nfp/nfp_user.h"
8#include "core/hle/service/server_manager.h"
8 9
9namespace Service::NFP { 10namespace Service::NFP {
10 11
@@ -36,8 +37,11 @@ private:
36 std::shared_ptr<IUser> user_interface; 37 std::shared_ptr<IUser> user_interface;
37}; 38};
38 39
39void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 40void LoopProcess(Core::System& system) {
40 std::make_shared<IUserManager>(system)->InstallAsService(service_manager); 41 auto server_manager = std::make_unique<ServerManager>(system);
42
43 server_manager->RegisterNamedService("nfp:user", std::make_shared<IUserManager>(system));
44 ServerManager::RunServer(std::move(server_manager));
41} 45}
42 46
43} // namespace Service::NFP 47} // 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 @@
7 7
8namespace Service::NFP { 8namespace Service::NFP {
9 9
10void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); 10void LoopProcess(Core::System& system);
11 11
12} // namespace Service::NFP 12} // 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 @@
5#include "core/core.h" 5#include "core/core.h"
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/ngct/ngct.h" 7#include "core/hle/service/ngct/ngct.h"
8#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9 10
10namespace Service::NGCT { 11namespace Service::NGCT {
@@ -51,8 +52,11 @@ private:
51 } 52 }
52}; 53};
53 54
54void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 55void LoopProcess(Core::System& system) {
55 std::make_shared<IService>(system)->InstallAsService(system.ServiceManager()); 56 auto server_manager = std::make_unique<ServerManager>(system);
57
58 server_manager->RegisterNamedService("ngct:u", std::make_shared<IService>(system));
59 ServerManager::RunServer(std::move(server_manager));
56} 60}
57 61
58} // namespace Service::NGCT 62} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NGCT { 10namespace Service::NGCT {
15 11
16/// Registers all NGCT services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::NGCT 14} // 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 @@
6#include "core/hle/kernel/k_event.h" 6#include "core/hle/kernel/k_event.h"
7#include "core/hle/service/kernel_helpers.h" 7#include "core/hle/service/kernel_helpers.h"
8#include "core/hle/service/nifm/nifm.h" 8#include "core/hle/service/nifm/nifm.h"
9#include "core/hle/service/server_manager.h"
9 10
10namespace { 11namespace {
11 12
@@ -626,10 +627,16 @@ private:
626 } 627 }
627}; 628};
628 629
629void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 630void LoopProcess(Core::System& system) {
630 std::make_shared<NetworkInterface>("nifm:a", system)->InstallAsService(service_manager); 631 auto server_manager = std::make_unique<ServerManager>(system);
631 std::make_shared<NetworkInterface>("nifm:s", system)->InstallAsService(service_manager); 632
632 std::make_shared<NetworkInterface>("nifm:u", system)->InstallAsService(service_manager); 633 server_manager->RegisterNamedService("nifm:a",
634 std::make_shared<NetworkInterface>("nifm:a", system));
635 server_manager->RegisterNamedService("nifm:s",
636 std::make_shared<NetworkInterface>("nifm:s", system));
637 server_manager->RegisterNamedService("nifm:u",
638 std::make_shared<NetworkInterface>("nifm:u", system));
639 ServerManager::RunServer(std::move(server_manager));
633} 640}
634 641
635} // namespace Service::NIFM 642} // 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 {
12class System; 12class System;
13} 13}
14 14
15namespace Service::SM {
16class ServiceManager;
17}
18
19namespace Service::NIFM { 15namespace Service::NIFM {
20 16
21/// Registers all NIFM services with the specified service manager. 17void LoopProcess(Core::System& system);
22void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
23 18
24class IGeneralService final : public ServiceFramework<IGeneralService> { 19class IGeneralService final : public ServiceFramework<IGeneralService> {
25public: 20public:
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 @@
8#include "core/hle/kernel/k_event.h" 8#include "core/hle/kernel/k_event.h"
9#include "core/hle/service/kernel_helpers.h" 9#include "core/hle/service/kernel_helpers.h"
10#include "core/hle/service/nim/nim.h" 10#include "core/hle/service/nim/nim.h"
11#include "core/hle/service/server_manager.h"
11#include "core/hle/service/service.h" 12#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h"
13 13
14namespace Service::NIM { 14namespace Service::NIM {
15 15
@@ -418,11 +418,14 @@ private:
418 } 418 }
419}; 419};
420 420
421void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 421void LoopProcess(Core::System& system) {
422 std::make_shared<NIM>(system)->InstallAsService(sm); 422 auto server_manager = std::make_unique<ServerManager>(system);
423 std::make_shared<NIM_ECA>(system)->InstallAsService(sm); 423
424 std::make_shared<NIM_SHP>(system)->InstallAsService(sm); 424 server_manager->RegisterNamedService("nim", std::make_shared<NIM>(system));
425 std::make_shared<NTC>(system)->InstallAsService(sm); 425 server_manager->RegisterNamedService("nim:eca", std::make_shared<NIM_ECA>(system));
426 server_manager->RegisterNamedService("nim:shp", std::make_shared<NIM_SHP>(system));
427 server_manager->RegisterNamedService("ntc", std::make_shared<NTC>(system));
428 ServerManager::RunServer(std::move(server_manager));
426} 429}
427 430
428} // namespace Service::NIM 431} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NIM { 10namespace Service::NIM {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::NIM 14} // 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 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/npns/npns.h" 6#include "core/hle/service/npns/npns.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::NPNS { 10namespace Service::NPNS {
11 11
@@ -94,9 +94,12 @@ public:
94 } 94 }
95}; 95};
96 96
97void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 97void LoopProcess(Core::System& system) {
98 std::make_shared<NPNS_S>(system)->InstallAsService(sm); 98 auto server_manager = std::make_unique<ServerManager>(system);
99 std::make_shared<NPNS_U>(system)->InstallAsService(sm); 99
100 server_manager->RegisterNamedService("npns:s", std::make_shared<NPNS_S>(system));
101 server_manager->RegisterNamedService("npns:u", std::make_shared<NPNS_U>(system));
102 ServerManager::RunServer(std::move(server_manager));
100} 103}
101 104
102} // namespace Service::NPNS 105} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::NPNS { 10namespace Service::NPNS {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::NPNS 14} // namespace Service::NPNS
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index e53bdde52..062e96ef9 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -14,6 +14,7 @@
14#include "core/hle/service/ns/language.h" 14#include "core/hle/service/ns/language.h"
15#include "core/hle/service/ns/ns.h" 15#include "core/hle/service/ns/ns.h"
16#include "core/hle/service/ns/pdm_qry.h" 16#include "core/hle/service/ns/pdm_qry.h"
17#include "core/hle/service/server_manager.h"
17#include "core/hle/service/set/set.h" 18#include "core/hle/service/set/set.h"
18 19
19namespace Service::NS { 20namespace Service::NS {
@@ -785,23 +786,26 @@ private:
785 } 786 }
786}; 787};
787 788
788void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 789void LoopProcess(Core::System& system) {
789 790 auto server_manager = std::make_unique<ServerManager>(system);
790 std::make_shared<NS>("ns:am2", system)->InstallAsService(service_manager); 791
791 std::make_shared<NS>("ns:ec", system)->InstallAsService(service_manager); 792 server_manager->RegisterNamedService("ns:am2", std::make_shared<NS>("ns:am2", system));
792 std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager); 793 server_manager->RegisterNamedService("ns:ec", std::make_shared<NS>("ns:ec", system));
793 std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager); 794 server_manager->RegisterNamedService("ns:rid", std::make_shared<NS>("ns:rid", system));
794 std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager); 795 server_manager->RegisterNamedService("ns:rt", std::make_shared<NS>("ns:rt", system));
795 std::make_shared<NS>("ns:ro", system)->InstallAsService(service_manager); 796 server_manager->RegisterNamedService("ns:web", std::make_shared<NS>("ns:web", system));
796 797 server_manager->RegisterNamedService("ns:ro", std::make_shared<NS>("ns:ro", system));
797 std::make_shared<NS_DEV>(system)->InstallAsService(service_manager); 798
798 std::make_shared<NS_SU>(system)->InstallAsService(service_manager); 799 server_manager->RegisterNamedService("ns:dev", std::make_shared<NS_DEV>(system));
799 std::make_shared<NS_VM>(system)->InstallAsService(service_manager); 800 server_manager->RegisterNamedService("ns:su", std::make_shared<NS_SU>(system));
800 801 server_manager->RegisterNamedService("ns:vm", std::make_shared<NS_VM>(system));
801 std::make_shared<PDM_QRY>(system)->InstallAsService(service_manager); 802 server_manager->RegisterNamedService("pdm:qry", std::make_shared<PDM_QRY>(system));
802 803
803 std::make_shared<IPlatformServiceManager>(system, "pl:s")->InstallAsService(service_manager); 804 server_manager->RegisterNamedService("pl:s",
804 std::make_shared<IPlatformServiceManager>(system, "pl:u")->InstallAsService(service_manager); 805 std::make_shared<IPlatformServiceManager>(system, "pl:s"));
806 server_manager->RegisterNamedService("pl:u",
807 std::make_shared<IPlatformServiceManager>(system, "pl:u"));
808 ServerManager::RunServer(std::move(server_manager));
805} 809}
806 810
807} // namespace Service::NS 811} // 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:
117 } 117 }
118}; 118};
119 119
120/// Registers all NS services with the specified service manager. 120void LoopProcess(Core::System& system);
121void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
122 121
123} // namespace NS 122} // namespace NS
124} // namespace Service 123} // 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 @@
24#include "core/hle/service/nvdrv/nvdrv_interface.h" 24#include "core/hle/service/nvdrv/nvdrv_interface.h"
25#include "core/hle/service/nvdrv/nvmemp.h" 25#include "core/hle/service/nvdrv/nvmemp.h"
26#include "core/hle/service/nvflinger/nvflinger.h" 26#include "core/hle/service/nvflinger/nvflinger.h"
27#include "core/hle/service/server_manager.h"
27#include "video_core/gpu.h" 28#include "video_core/gpu.h"
28 29
29namespace Service::Nvidia { 30namespace Service::Nvidia {
@@ -41,15 +42,19 @@ void EventInterface::FreeEvent(Kernel::KEvent* event) {
41 module.service_context.CloseEvent(event); 42 module.service_context.CloseEvent(event);
42} 43}
43 44
44void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger, 45void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system) {
45 Core::System& system) { 46 auto server_manager = std::make_unique<ServerManager>(system);
46 auto module_ = std::make_shared<Module>(system); 47 auto module = std::make_shared<Module>(system);
47 std::make_shared<NVDRV>(system, module_, "nvdrv")->InstallAsService(service_manager); 48 server_manager->RegisterNamedService("nvdrv", std::make_shared<NVDRV>(system, module, "nvdrv"));
48 std::make_shared<NVDRV>(system, module_, "nvdrv:a")->InstallAsService(service_manager); 49 server_manager->RegisterNamedService("nvdrv:a",
49 std::make_shared<NVDRV>(system, module_, "nvdrv:s")->InstallAsService(service_manager); 50 std::make_shared<NVDRV>(system, module, "nvdrv:a"));
50 std::make_shared<NVDRV>(system, module_, "nvdrv:t")->InstallAsService(service_manager); 51 server_manager->RegisterNamedService("nvdrv:s",
51 std::make_shared<NVMEMP>(system)->InstallAsService(service_manager); 52 std::make_shared<NVDRV>(system, module, "nvdrv:s"));
52 nvflinger.SetNVDrvInstance(module_); 53 server_manager->RegisterNamedService("nvdrv:t",
54 std::make_shared<NVDRV>(system, module, "nvdrv:t"));
55 server_manager->RegisterNamedService("nvmemp", std::make_shared<NVMEMP>(system));
56 nvflinger.SetNVDrvInstance(module);
57 ServerManager::RunServer(std::move(server_manager));
53} 58}
54 59
55Module::Module(Core::System& system) 60Module::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:
114 std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders; 114 std::unordered_map<std::string, std::function<FilesContainerType::iterator(DeviceFD)>> builders;
115}; 115};
116 116
117/// Registers all NVDRV services with the specified service manager. 117void LoopProcess(NVFlinger::NVFlinger& nvflinger, Core::System& system);
118void InstallInterfaces(SM::ServiceManager& service_manager, NVFlinger::NVFlinger& nvflinger,
119 Core::System& system);
120 118
121} // namespace Service::Nvidia 119} // 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) {
222} 222}
223 223
224NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name) 224NVDRV::NVDRV(Core::System& system_, std::shared_ptr<Module> nvdrv_, const char* name)
225 : ServiceFramework{system_, name, ServiceThreadType::CreateNew}, nvdrv{std::move(nvdrv_)} { 225 : ServiceFramework{system_, name}, nvdrv{std::move(nvdrv_)} {
226 static const FunctionInfo functions[] = { 226 static const FunctionInfo functions[] = {
227 {0, &NVDRV::Open, "Open"}, 227 {0, &NVDRV::Open, "Open"},
228 {1, &NVDRV::Ioctl1, "Ioctl"}, 228 {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 @@
3 3
4#include "core/hle/ipc_helpers.h" 4#include "core/hle/ipc_helpers.h"
5#include "core/hle/service/olsc/olsc.h" 5#include "core/hle/service/olsc/olsc.h"
6#include "core/hle/service/server_manager.h"
6#include "core/hle/service/service.h" 7#include "core/hle/service/service.h"
7#include "core/hle/service/sm/sm.h"
8 8
9namespace Service::OLSC { 9namespace Service::OLSC {
10 10
@@ -72,8 +72,11 @@ private:
72 bool initialized{}; 72 bool initialized{};
73}; 73};
74 74
75void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 75void LoopProcess(Core::System& system) {
76 std::make_shared<OLSC>(system)->InstallAsService(service_manager); 76 auto server_manager = std::make_unique<ServerManager>(system);
77
78 server_manager->RegisterNamedService("olsc:u", std::make_shared<OLSC>(system));
79 ServerManager::RunServer(std::move(server_manager));
77} 80}
78 81
79} // namespace Service::OLSC 82} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::OLSC { 10namespace Service::OLSC {
15 11
16/// Registers all SSL services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::OLSC 14} // 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 @@
4#include <memory> 4#include <memory>
5 5
6#include "core/hle/service/pcie/pcie.h" 6#include "core/hle/service/pcie/pcie.h"
7#include "core/hle/service/server_manager.h"
7#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
8#include "core/hle/service/sm/sm.h"
9 9
10namespace Service::PCIe { 10namespace Service::PCIe {
11 11
@@ -59,8 +59,11 @@ public:
59 } 59 }
60}; 60};
61 61
62void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 62void LoopProcess(Core::System& system) {
63 std::make_shared<PCIe>(system)->InstallAsService(sm); 63 auto server_manager = std::make_unique<ServerManager>(system);
64
65 server_manager->RegisterNamedService("pcie", std::make_shared<PCIe>(system));
66 ServerManager::RunServer(std::move(server_manager));
64} 67}
65 68
66} // namespace Service::PCIe 69} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PCIe { 10namespace Service::PCIe {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::PCIe 14} // 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 @@
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
9#include "core/hle/service/pctl/pctl.h" 9#include "core/hle/service/pctl/pctl.h"
10#include "core/hle/service/pctl/pctl_module.h" 10#include "core/hle/service/pctl/pctl_module.h"
11#include "core/hle/service/server_manager.h"
11 12
12namespace Service::PCTL { 13namespace Service::PCTL {
13 14
@@ -393,19 +394,22 @@ Module::Interface::Interface(Core::System& system_, std::shared_ptr<Module> modu
393 394
394Module::Interface::~Interface() = default; 395Module::Interface::~Interface() = default;
395 396
396void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 397void LoopProcess(Core::System& system) {
398 auto server_manager = std::make_unique<ServerManager>(system);
399
397 auto module = std::make_shared<Module>(); 400 auto module = std::make_shared<Module>();
398 std::make_shared<PCTL>(system, module, "pctl", 401 server_manager->RegisterNamedService(
399 Capability::Application | Capability::SnsPost | Capability::Status | 402 "pctl", std::make_shared<PCTL>(system, module, "pctl",
400 Capability::StereoVision) 403 Capability::Application | Capability::SnsPost |
401 ->InstallAsService(service_manager); 404 Capability::Status | Capability::StereoVision));
402 // TODO(ogniK): Implement remaining capabilities 405 // TODO(ogniK): Implement remaining capabilities
403 std::make_shared<PCTL>(system, module, "pctl:a", Capability::None) 406 server_manager->RegisterNamedService(
404 ->InstallAsService(service_manager); 407 "pctl:a", std::make_shared<PCTL>(system, module, "pctl:a", Capability::None));
405 std::make_shared<PCTL>(system, module, "pctl:r", Capability::None) 408 server_manager->RegisterNamedService(
406 ->InstallAsService(service_manager); 409 "pctl:r", std::make_shared<PCTL>(system, module, "pctl:r", Capability::None));
407 std::make_shared<PCTL>(system, module, "pctl:s", Capability::None) 410 server_manager->RegisterNamedService(
408 ->InstallAsService(service_manager); 411 "pctl:s", std::make_shared<PCTL>(system, module, "pctl:s", Capability::None));
412 ServerManager::RunServer(std::move(server_manager));
409} 413}
410 414
411} // namespace Service::PCTL 415} // 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:
42 }; 42 };
43}; 43};
44 44
45/// Registers all PCTL services with the specified service manager. 45void LoopProcess(Core::System& system);
46void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
47 46
48} // namespace Service::PCTL 47} // 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 @@
5 5
6#include "core/hle/ipc_helpers.h" 6#include "core/hle/ipc_helpers.h"
7#include "core/hle/service/pcv/pcv.h" 7#include "core/hle/service/pcv/pcv.h"
8#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10 10
11namespace Service::PCV { 11namespace Service::PCV {
12 12
@@ -141,11 +141,14 @@ public:
141 } 141 }
142}; 142};
143 143
144void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 144void LoopProcess(Core::System& system) {
145 std::make_shared<PCV>(system)->InstallAsService(sm); 145 auto server_manager = std::make_unique<ServerManager>(system);
146 std::make_shared<CLKRST>(system, "clkrst")->InstallAsService(sm); 146
147 std::make_shared<CLKRST>(system, "clkrst:i")->InstallAsService(sm); 147 server_manager->RegisterNamedService("pcv", std::make_shared<PCV>(system));
148 std::make_shared<CLKRST_A>(system)->InstallAsService(sm); 148 server_manager->RegisterNamedService("clkrst", std::make_shared<CLKRST>(system, "clkrst"));
149 server_manager->RegisterNamedService("clkrst:i", std::make_shared<CLKRST>(system, "clkrst:i"));
150 server_manager->RegisterNamedService("clkrst:a", std::make_shared<CLKRST_A>(system));
151 ServerManager::RunServer(std::move(server_manager));
149} 152}
150 153
151} // namespace Service::PCV 154} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PCV { 10namespace Service::PCV {
15 11
16enum class DeviceCode : u32 { 12enum class DeviceCode : u32 {
@@ -104,6 +100,6 @@ enum class DeviceCode : u32 {
104 OscClk = 0x40000080 100 OscClk = 0x40000080
105}; 101};
106 102
107void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 103void LoopProcess(Core::System& system);
108 104
109} // namespace Service::PCV 105} // 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 @@
6#include "core/hle/kernel/k_process.h" 6#include "core/hle/kernel/k_process.h"
7#include "core/hle/kernel/kernel.h" 7#include "core/hle/kernel/kernel.h"
8#include "core/hle/service/pm/pm.h" 8#include "core/hle/service/pm/pm.h"
9#include "core/hle/service/server_manager.h"
9#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
10 11
11namespace Service::PM { 12namespace Service::PM {
@@ -262,12 +263,15 @@ private:
262 const Kernel::KernelCore& kernel; 263 const Kernel::KernelCore& kernel;
263}; 264};
264 265
265void InstallInterfaces(Core::System& system) { 266void LoopProcess(Core::System& system) {
266 std::make_shared<BootMode>(system)->InstallAsService(system.ServiceManager()); 267 auto server_manager = std::make_unique<ServerManager>(system);
267 std::make_shared<DebugMonitor>(system)->InstallAsService(system.ServiceManager()); 268
268 std::make_shared<Info>(system, system.Kernel().GetProcessList()) 269 server_manager->RegisterNamedService("pm:bm", std::make_shared<BootMode>(system));
269 ->InstallAsService(system.ServiceManager()); 270 server_manager->RegisterNamedService("pm:dmnt", std::make_shared<DebugMonitor>(system));
270 std::make_shared<Shell>(system)->InstallAsService(system.ServiceManager()); 271 server_manager->RegisterNamedService(
272 "pm:info", std::make_shared<Info>(system, system.Kernel().GetProcessList()));
273 server_manager->RegisterNamedService("pm:shell", std::make_shared<Shell>(system));
274 ServerManager::RunServer(std::move(server_manager));
271} 275}
272 276
273} // namespace Service::PM 277} // 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 {
14 Maintenance, 14 Maintenance,
15}; 15};
16 16
17/// Registers all PM services with the specified service manager. 17void LoopProcess(Core::System& system);
18void InstallInterfaces(Core::System& system);
19 18
20} // namespace Service::PM 19} // 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 @@
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/acc/profile_manager.h" 8#include "core/hle/service/acc/profile_manager.h"
9#include "core/hle/service/prepo/prepo.h" 9#include "core/hle/service/prepo/prepo.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/service.h" 11#include "core/hle/service/service.h"
11#include "core/reporter.h" 12#include "core/reporter.h"
12 13
@@ -183,12 +184,20 @@ private:
183 } 184 }
184}; 185};
185 186
186void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 187void LoopProcess(Core::System& system) {
187 std::make_shared<PlayReport>("prepo:a", system)->InstallAsService(service_manager); 188 auto server_manager = std::make_unique<ServerManager>(system);
188 std::make_shared<PlayReport>("prepo:a2", system)->InstallAsService(service_manager); 189
189 std::make_shared<PlayReport>("prepo:m", system)->InstallAsService(service_manager); 190 server_manager->RegisterNamedService("prepo:a",
190 std::make_shared<PlayReport>("prepo:s", system)->InstallAsService(service_manager); 191 std::make_shared<PlayReport>("prepo:a", system));
191 std::make_shared<PlayReport>("prepo:u", system)->InstallAsService(service_manager); 192 server_manager->RegisterNamedService("prepo:a2",
193 std::make_shared<PlayReport>("prepo:a2", system));
194 server_manager->RegisterNamedService("prepo:m",
195 std::make_shared<PlayReport>("prepo:m", system));
196 server_manager->RegisterNamedService("prepo:s",
197 std::make_shared<PlayReport>("prepo:s", system));
198 server_manager->RegisterNamedService("prepo:u",
199 std::make_shared<PlayReport>("prepo:u", system));
200 ServerManager::RunServer(std::move(server_manager));
192} 201}
193 202
194} // namespace Service::PlayReport 203} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PlayReport { 10namespace Service::PlayReport {
15 11
16void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::PlayReport 14} // 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 @@
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/psc/psc.h" 8#include "core/hle/service/psc/psc.h"
9#include "core/hle/service/server_manager.h"
9#include "core/hle/service/service.h" 10#include "core/hle/service/service.h"
10#include "core/hle/service/sm/sm.h"
11 11
12namespace Service::PSC { 12namespace Service::PSC {
13 13
@@ -71,9 +71,12 @@ private:
71 } 71 }
72}; 72};
73 73
74void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 74void LoopProcess(Core::System& system) {
75 std::make_shared<PSC_C>(system)->InstallAsService(sm); 75 auto server_manager = std::make_unique<ServerManager>(system);
76 std::make_shared<PSC_M>(system)->InstallAsService(sm); 76
77 server_manager->RegisterNamedService("psc:c", std::make_shared<PSC_C>(system));
78 server_manager->RegisterNamedService("psc:m", std::make_shared<PSC_M>(system));
79 ServerManager::RunServer(std::move(server_manager));
77} 80}
78 81
79} // namespace Service::PSC 82} // 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;
13 13
14namespace Service::PSC { 14namespace Service::PSC {
15 15
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 16void LoopProcess(Core::System& system);
17 17
18} // namespace Service::PSC 18} // 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 @@
7#include "core/hle/service/ptm/psm.h" 7#include "core/hle/service/ptm/psm.h"
8#include "core/hle/service/ptm/ptm.h" 8#include "core/hle/service/ptm/ptm.h"
9#include "core/hle/service/ptm/ts.h" 9#include "core/hle/service/ptm/ts.h"
10#include "core/hle/service/server_manager.h"
10 11
11namespace Service::PTM { 12namespace Service::PTM {
12 13
13void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 14void LoopProcess(Core::System& system) {
14 std::make_shared<PSM>(system)->InstallAsService(sm); 15 auto server_manager = std::make_unique<ServerManager>(system);
15 std::make_shared<TS>(system)->InstallAsService(sm); 16
17 server_manager->RegisterNamedService("psm", std::make_shared<PSM>(system));
18 server_manager->RegisterNamedService("ts", std::make_shared<TS>(system));
19 ServerManager::RunServer(std::move(server_manager));
16} 20}
17 21
18} // namespace Service::PTM 22} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::PTM { 10namespace Service::PTM {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::PTM 14} // namespace Service::PTM
diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp
new file mode 100644
index 000000000..1b3db3caf
--- /dev/null
+++ b/src/core/hle/service/server_manager.cpp
@@ -0,0 +1,448 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "common/scope_exit.h"
5
6#include "core/core.h"
7#include "core/hle/ipc_helpers.h"
8#include "core/hle/kernel/hle_ipc.h"
9#include "core/hle/kernel/k_client_port.h"
10#include "core/hle/kernel/k_client_session.h"
11#include "core/hle/kernel/k_event.h"
12#include "core/hle/kernel/k_object_name.h"
13#include "core/hle/kernel/k_port.h"
14#include "core/hle/kernel/k_server_port.h"
15#include "core/hle/kernel/k_server_session.h"
16#include "core/hle/kernel/k_synchronization_object.h"
17#include "core/hle/kernel/svc_results.h"
18#include "core/hle/service/server_manager.h"
19#include "core/hle/service/sm/sm.h"
20
21namespace Service {
22
23constexpr size_t MaximumWaitObjects = 0x40;
24
25enum HandleType {
26 Port,
27 Session,
28 DeferEvent,
29 Event,
30};
31
32ServerManager::ServerManager(Core::System& system) : m_system{system}, m_serve_mutex{system} {
33 // Initialize event.
34 m_event = Kernel::KEvent::Create(system.Kernel());
35 m_event->Initialize(nullptr);
36}
37
38ServerManager::~ServerManager() {
39 // Signal stop.
40 m_stop_source.request_stop();
41 m_event->Signal();
42
43 // Wait for processing to stop.
44 m_stopped.wait(false);
45 m_threads.clear();
46
47 // Clean up ports.
48 for (const auto& [port, handler] : m_ports) {
49 port->Close();
50 }
51
52 // Clean up sessions.
53 for (const auto& [session, manager] : m_sessions) {
54 session->Close();
55 }
56
57 for (const auto& request : m_deferrals) {
58 request.session->Close();
59 }
60
61 // Close event.
62 m_event->GetReadableEvent().Close();
63 m_event->Close();
64
65 if (m_deferral_event) {
66 m_deferral_event->GetReadableEvent().Close();
67 // Write event is owned by ServiceManager
68 }
69}
70
71void ServerManager::RunServer(std::unique_ptr<ServerManager>&& server_manager) {
72 server_manager->m_system.RunServer(std::move(server_manager));
73}
74
75Result ServerManager::RegisterSession(Kernel::KServerSession* session,
76 std::shared_ptr<Kernel::SessionRequestManager> manager) {
77 ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
78
79 // We are taking ownership of the server session, so don't open it.
80 // Begin tracking the server session.
81 {
82 std::scoped_lock ll{m_list_mutex};
83 m_sessions.emplace(session, std::move(manager));
84 }
85
86 // Signal the wakeup event.
87 m_event->Signal();
88
89 R_SUCCEED();
90}
91
92Result ServerManager::RegisterNamedService(const std::string& service_name,
93 std::shared_ptr<Kernel::SessionRequestHandler>&& handler,
94 u32 max_sessions) {
95 ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
96
97 // Add the new server to sm:.
98 ASSERT(R_SUCCEEDED(
99 m_system.ServiceManager().RegisterService(service_name, max_sessions, handler)));
100
101 // Get the registered port.
102 auto port = m_system.ServiceManager().GetServicePort(service_name);
103 ASSERT(port.Succeeded());
104
105 // Open a new reference to the server port.
106 (*port)->GetServerPort().Open();
107
108 // Begin tracking the server port.
109 {
110 std::scoped_lock ll{m_list_mutex};
111 m_ports.emplace(std::addressof((*port)->GetServerPort()), std::move(handler));
112 }
113
114 // Signal the wakeup event.
115 m_event->Signal();
116
117 R_SUCCEED();
118}
119
120Result ServerManager::ManageNamedPort(const std::string& service_name,
121 std::shared_ptr<Kernel::SessionRequestHandler>&& handler,
122 u32 max_sessions) {
123 ASSERT(m_sessions.size() + m_ports.size() < MaximumWaitObjects);
124
125 // Create a new port.
126 auto* port = Kernel::KPort::Create(m_system.Kernel());
127 port->Initialize(max_sessions, false, service_name);
128
129 // Register the port.
130 Kernel::KPort::Register(m_system.Kernel(), port);
131
132 // Ensure that our reference to the port is closed if we fail to register it.
133 SCOPE_EXIT({
134 port->GetClientPort().Close();
135 port->GetServerPort().Close();
136 });
137
138 // Register the object name with the kernel.
139 R_TRY(Kernel::KObjectName::NewFromName(m_system.Kernel(), std::addressof(port->GetClientPort()),
140 service_name.c_str()));
141
142 // Open a new reference to the server port.
143 port->GetServerPort().Open();
144
145 // Begin tracking the server port.
146 {
147 std::scoped_lock ll{m_list_mutex};
148 m_ports.emplace(std::addressof(port->GetServerPort()), std::move(handler));
149 }
150
151 // We succeeded.
152 R_SUCCEED();
153}
154
155Result ServerManager::ManageDeferral(Kernel::KEvent** out_event) {
156 // Create a new event.
157 m_deferral_event = Kernel::KEvent::Create(m_system.Kernel());
158 ASSERT(m_deferral_event != nullptr);
159
160 // Initialize the event.
161 m_deferral_event->Initialize(nullptr);
162
163 // Set the output.
164 *out_event = m_deferral_event;
165
166 // We succeeded.
167 R_SUCCEED();
168}
169
170void ServerManager::StartAdditionalHostThreads(const char* name, size_t num_threads) {
171 for (size_t i = 0; i < num_threads; i++) {
172 auto thread_name = fmt::format("{}:{}", name, i + 1);
173 m_threads.emplace_back(m_system.Kernel().RunOnHostCoreThread(
174 std::move(thread_name), [&] { this->LoopProcessImpl(); }));
175 }
176}
177
178Result ServerManager::LoopProcess() {
179 SCOPE_EXIT({
180 m_stopped.store(true);
181 m_stopped.notify_all();
182 });
183
184 R_RETURN(this->LoopProcessImpl());
185}
186
187Result ServerManager::LoopProcessImpl() {
188 while (!m_stop_source.stop_requested()) {
189 R_TRY(this->WaitAndProcessImpl());
190 }
191
192 R_SUCCEED();
193}
194
195Result ServerManager::WaitAndProcessImpl() {
196 Kernel::KScopedAutoObject<Kernel::KSynchronizationObject> wait_obj;
197 HandleType wait_type{};
198
199 // Ensure we are the only thread waiting for this server.
200 std::unique_lock sl{m_serve_mutex};
201
202 // If we're done, return before we start waiting.
203 R_SUCCEED_IF(m_stop_source.stop_requested());
204
205 // Wait for a tracked object to become signaled.
206 {
207 s32 num_objs{};
208 std::array<HandleType, MaximumWaitObjects> wait_types{};
209 std::array<Kernel::KSynchronizationObject*, MaximumWaitObjects> wait_objs{};
210
211 const auto AddWaiter{
212 [&](Kernel::KSynchronizationObject* synchronization_object, HandleType type) {
213 // Open a new reference to the object.
214 synchronization_object->Open();
215
216 // Insert into the list.
217 wait_types[num_objs] = type;
218 wait_objs[num_objs++] = synchronization_object;
219 }};
220
221 {
222 std::scoped_lock ll{m_list_mutex};
223
224 // Add all of our ports.
225 for (const auto& [port, handler] : m_ports) {
226 AddWaiter(port, HandleType::Port);
227 }
228
229 // Add all of our sessions.
230 for (const auto& [session, manager] : m_sessions) {
231 AddWaiter(session, HandleType::Session);
232 }
233 }
234
235 // Add the deferral wakeup event.
236 if (m_deferral_event != nullptr) {
237 AddWaiter(std::addressof(m_deferral_event->GetReadableEvent()), HandleType::DeferEvent);
238 }
239
240 // Add the wakeup event.
241 AddWaiter(std::addressof(m_event->GetReadableEvent()), HandleType::Event);
242
243 // Clean up extra references on exit.
244 SCOPE_EXIT({
245 for (s32 i = 0; i < num_objs; i++) {
246 wait_objs[i]->Close();
247 }
248 });
249
250 // Wait for a signal.
251 s32 out_index{-1};
252 R_TRY(Kernel::KSynchronizationObject::Wait(m_system.Kernel(), &out_index, wait_objs.data(),
253 num_objs, -1));
254 ASSERT(out_index >= 0 && out_index < num_objs);
255
256 // Set the output index.
257 wait_obj = wait_objs[out_index];
258 wait_type = wait_types[out_index];
259 }
260
261 // Process what we just received, temporarily removing the object so it is
262 // not processed concurrently by another thread.
263 {
264 switch (wait_type) {
265 case HandleType::Port: {
266 // Port signaled.
267 auto* port = wait_obj->DynamicCast<Kernel::KServerPort*>();
268 std::shared_ptr<Kernel::SessionRequestHandler> handler;
269
270 // Remove from tracking.
271 {
272 std::scoped_lock ll{m_list_mutex};
273 ASSERT(m_ports.contains(port));
274 m_ports.at(port).swap(handler);
275 m_ports.erase(port);
276 }
277
278 // Allow other threads to serve.
279 sl.unlock();
280
281 // Finish.
282 R_RETURN(this->OnPortEvent(port, std::move(handler)));
283 }
284 case HandleType::Session: {
285 // Session signaled.
286 auto* session = wait_obj->DynamicCast<Kernel::KServerSession*>();
287 std::shared_ptr<Kernel::SessionRequestManager> manager;
288
289 // Remove from tracking.
290 {
291 std::scoped_lock ll{m_list_mutex};
292 ASSERT(m_sessions.contains(session));
293 m_sessions.at(session).swap(manager);
294 m_sessions.erase(session);
295 }
296
297 // Allow other threads to serve.
298 sl.unlock();
299
300 // Finish.
301 R_RETURN(this->OnSessionEvent(session, std::move(manager)));
302 }
303 case HandleType::DeferEvent: {
304 // Clear event.
305 ASSERT(R_SUCCEEDED(m_deferral_event->Clear()));
306
307 // Drain the list of deferrals while we process.
308 std::list<RequestState> deferrals;
309 {
310 std::scoped_lock ll{m_list_mutex};
311 m_deferrals.swap(deferrals);
312 }
313
314 // Allow other threads to serve.
315 sl.unlock();
316
317 // Finish.
318 R_RETURN(this->OnDeferralEvent(std::move(deferrals)));
319 }
320 case HandleType::Event: {
321 // Clear event and finish.
322 R_RETURN(m_event->Clear());
323 }
324 default: {
325 UNREACHABLE();
326 }
327 }
328 }
329}
330
331Result ServerManager::OnPortEvent(Kernel::KServerPort* port,
332 std::shared_ptr<Kernel::SessionRequestHandler>&& handler) {
333 // Accept a new server session.
334 Kernel::KServerSession* session = port->AcceptSession();
335 ASSERT(session != nullptr);
336
337 // Create the session manager and install the handler.
338 auto manager = std::make_shared<Kernel::SessionRequestManager>(m_system.Kernel(), *this);
339 manager->SetSessionHandler(std::shared_ptr(handler));
340
341 // Track the server session.
342 {
343 std::scoped_lock ll{m_list_mutex};
344 m_ports.emplace(port, std::move(handler));
345 m_sessions.emplace(session, std::move(manager));
346 }
347
348 // Signal the wakeup event.
349 m_event->Signal();
350
351 // We succeeded.
352 R_SUCCEED();
353}
354
355Result ServerManager::OnSessionEvent(Kernel::KServerSession* session,
356 std::shared_ptr<Kernel::SessionRequestManager>&& manager) {
357 Result rc{ResultSuccess};
358
359 // Try to receive a message.
360 std::shared_ptr<Kernel::HLERequestContext> context;
361 rc = session->ReceiveRequest(&context, manager);
362
363 // If the session has been closed, we're done.
364 if (rc == Kernel::ResultSessionClosed) {
365 // Close the session.
366 session->Close();
367
368 // Finish.
369 R_SUCCEED();
370 }
371 ASSERT(R_SUCCEEDED(rc));
372
373 RequestState request{
374 .session = session,
375 .context = std::move(context),
376 .manager = std::move(manager),
377 };
378
379 // Complete the sync request with deferral handling.
380 R_RETURN(this->CompleteSyncRequest(std::move(request)));
381}
382
383Result ServerManager::CompleteSyncRequest(RequestState&& request) {
384 Result rc{ResultSuccess};
385 Result service_rc{ResultSuccess};
386
387 // Mark the request as not deferred.
388 request.context->SetIsDeferred(false);
389
390 // Complete the request. We have exclusive access to this session.
391 service_rc = request.manager->CompleteSyncRequest(request.session, *request.context);
392
393 // If we've been deferred, we're done.
394 if (request.context->GetIsDeferred()) {
395 // Insert into deferral list.
396 std::scoped_lock ll{m_list_mutex};
397 m_deferrals.emplace_back(std::move(request));
398
399 // Finish.
400 R_SUCCEED();
401 }
402
403 // Send the reply.
404 rc = request.session->SendReplyHLE();
405
406 // If the session has been closed, we're done.
407 if (rc == Kernel::ResultSessionClosed || service_rc == IPC::ERR_REMOTE_PROCESS_DEAD) {
408 // Close the session.
409 request.session->Close();
410
411 // Finish.
412 R_SUCCEED();
413 }
414
415 ASSERT(R_SUCCEEDED(rc));
416 ASSERT(R_SUCCEEDED(service_rc));
417
418 // Reinsert the session.
419 {
420 std::scoped_lock ll{m_list_mutex};
421 m_sessions.emplace(request.session, std::move(request.manager));
422 }
423
424 // Signal the wakeup event.
425 m_event->Signal();
426
427 // We succeeded.
428 R_SUCCEED();
429}
430
431Result ServerManager::OnDeferralEvent(std::list<RequestState>&& deferrals) {
432 ON_RESULT_FAILURE {
433 std::scoped_lock ll{m_list_mutex};
434 m_deferrals.splice(m_deferrals.end(), deferrals);
435 };
436
437 while (!deferrals.empty()) {
438 RequestState request = deferrals.front();
439 deferrals.pop_front();
440
441 // Try again to complete the request.
442 R_TRY(this->CompleteSyncRequest(std::move(request)));
443 }
444
445 R_SUCCEED();
446}
447
448} // namespace Service
diff --git a/src/core/hle/service/server_manager.h b/src/core/hle/service/server_manager.h
new file mode 100644
index 000000000..57b954ae8
--- /dev/null
+++ b/src/core/hle/service/server_manager.h
@@ -0,0 +1,91 @@
1// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <atomic>
7#include <functional>
8#include <list>
9#include <map>
10#include <mutex>
11#include <string_view>
12#include <vector>
13
14#include "common/polyfill_thread.h"
15#include "core/hle/result.h"
16#include "core/hle/service/mutex.h"
17
18namespace Core {
19class System;
20}
21
22namespace Kernel {
23class HLERequestContext;
24class KEvent;
25class KServerPort;
26class KServerSession;
27class KSynchronizationObject;
28class SessionRequestHandler;
29class SessionRequestManager;
30} // namespace Kernel
31
32namespace Service {
33
34class ServerManager {
35public:
36 explicit ServerManager(Core::System& system);
37 ~ServerManager();
38
39 Result RegisterSession(Kernel::KServerSession* session,
40 std::shared_ptr<Kernel::SessionRequestManager> manager);
41 Result RegisterNamedService(const std::string& service_name,
42 std::shared_ptr<Kernel::SessionRequestHandler>&& handler,
43 u32 max_sessions = 64);
44 Result ManageNamedPort(const std::string& service_name,
45 std::shared_ptr<Kernel::SessionRequestHandler>&& handler,
46 u32 max_sessions = 64);
47 Result ManageDeferral(Kernel::KEvent** out_event);
48
49 Result LoopProcess();
50 void StartAdditionalHostThreads(const char* name, size_t num_threads);
51
52 static void RunServer(std::unique_ptr<ServerManager>&& server);
53
54private:
55 struct RequestState;
56
57 Result LoopProcessImpl();
58 Result WaitAndProcessImpl();
59 Result OnPortEvent(Kernel::KServerPort* port,
60 std::shared_ptr<Kernel::SessionRequestHandler>&& handler);
61 Result OnSessionEvent(Kernel::KServerSession* session,
62 std::shared_ptr<Kernel::SessionRequestManager>&& manager);
63 Result OnDeferralEvent(std::list<RequestState>&& deferrals);
64 Result CompleteSyncRequest(RequestState&& state);
65
66private:
67 Core::System& m_system;
68 Mutex m_serve_mutex;
69 std::mutex m_list_mutex;
70
71 // Guest state tracking
72 std::map<Kernel::KServerPort*, std::shared_ptr<Kernel::SessionRequestHandler>> m_ports{};
73 std::map<Kernel::KServerSession*, std::shared_ptr<Kernel::SessionRequestManager>> m_sessions{};
74 Kernel::KEvent* m_event{};
75 Kernel::KEvent* m_deferral_event{};
76
77 // Deferral tracking
78 struct RequestState {
79 Kernel::KServerSession* session;
80 std::shared_ptr<Kernel::HLERequestContext> context;
81 std::shared_ptr<Kernel::SessionRequestManager> manager;
82 };
83 std::list<RequestState> m_deferrals{};
84
85 // Host state tracking
86 std::atomic<bool> m_stopped{};
87 std::vector<std::jthread> m_threads{};
88 std::stop_source m_stop_source{};
89};
90
91} // 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 {
90} 90}
91 91
92ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_, 92ServiceFrameworkBase::ServiceFrameworkBase(Core::System& system_, const char* service_name_,
93 ServiceThreadType thread_type, u32 max_sessions_, 93 u32 max_sessions_, InvokerFn* handler_invoker_)
94 InvokerFn* handler_invoker_) 94 : SessionRequestHandler(system_.Kernel(), service_name_), system{system_},
95 : SessionRequestHandler(system_.Kernel(), service_name_, thread_type), system{system_},
96 service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {} 95 service_name{service_name_}, max_sessions{max_sessions_}, handler_invoker{handler_invoker_} {}
97 96
98ServiceFrameworkBase::~ServiceFrameworkBase() { 97ServiceFrameworkBase::~ServiceFrameworkBase() {
99 // Wait for other threads to release access before destroying 98 // Wait for other threads to release access before destroying
100 const auto guard = LockService(); 99 const auto guard = LockService();
101
102 if (named_port != nullptr) {
103 named_port->GetClientPort().Close();
104 named_port->GetServerPort().Close();
105 named_port = nullptr;
106 }
107}
108
109void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) {
110 const auto guard = LockService();
111
112 ASSERT(!service_registered);
113
114 service_manager.RegisterService(service_name, max_sessions, shared_from_this());
115 service_registered = true;
116}
117
118Kernel::KClientPort& ServiceFrameworkBase::CreatePort() {
119 const auto guard = LockService();
120
121 if (named_port == nullptr) {
122 ASSERT(!service_registered);
123
124 named_port = Kernel::KPort::Create(kernel);
125 named_port->Initialize(max_sessions, false, service_name);
126
127 service_registered = true;
128 }
129
130 return named_port->GetClientPort();
131} 100}
132 101
133void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { 102void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) {
@@ -244,67 +213,69 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
244 : hos_binder_driver_server{std::make_unique<NVFlinger::HosBinderDriverServer>(system)}, 213 : hos_binder_driver_server{std::make_unique<NVFlinger::HosBinderDriverServer>(system)},
245 nv_flinger{std::make_unique<NVFlinger::NVFlinger>(system, *hos_binder_driver_server)} { 214 nv_flinger{std::make_unique<NVFlinger::NVFlinger>(system, *hos_binder_driver_server)} {
246 215
216 auto& kernel = system.Kernel();
217
247 // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it 218 // NVFlinger needs to be accessed by several services like Vi and AppletOE so we instantiate it
248 // here and pass it into the respective InstallInterfaces functions. 219 // here and pass it into the respective InstallInterfaces functions.
249
250 system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); 220 system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false);
251 221
252 system.Kernel().RegisterNamedService("sm:", SM::ServiceManager::InterfaceFactory); 222 // clang-format off
253 system.Kernel().RegisterInterfaceForNamedService("sm:", SM::ServiceManager::SessionHandler); 223 kernel.RunOnHostCoreProcess("audio", [&] { Audio::LoopProcess(system); }).detach();
254 224 kernel.RunOnHostCoreProcess("FS", [&] { FileSystem::LoopProcess(system); }).detach();
255 Account::InstallInterfaces(system); 225 kernel.RunOnHostCoreProcess("jit", [&] { JIT::LoopProcess(system); }).detach();
256 AM::InstallInterfaces(*sm, *nv_flinger, system); 226 kernel.RunOnHostCoreProcess("ldn", [&] { LDN::LoopProcess(system); }).detach();
257 AOC::InstallInterfaces(*sm, system); 227 kernel.RunOnHostCoreProcess("Loader", [&] { LDR::LoopProcess(system); }).detach();
258 APM::InstallInterfaces(system); 228 kernel.RunOnHostCoreProcess("nvservices", [&] { Nvidia::LoopProcess(*nv_flinger, system); }).detach();
259 Audio::InstallInterfaces(*sm, system); 229 kernel.RunOnHostCoreProcess("bsdsocket", [&] { Sockets::LoopProcess(system); }).detach();
260 BCAT::InstallInterfaces(system); 230 kernel.RunOnHostCoreProcess("vi", [&] { VI::LoopProcess(system, *nv_flinger, *hos_binder_driver_server); }).detach();
261 BPC::InstallInterfaces(*sm, system); 231
262 BtDrv::InstallInterfaces(*sm, system); 232 kernel.RunOnGuestCoreProcess("sm", [&] { SM::LoopProcess(system); });
263 BTM::InstallInterfaces(*sm, system); 233 kernel.RunOnGuestCoreProcess("account", [&] { Account::LoopProcess(system); });
264 Capture::InstallInterfaces(*sm, system); 234 kernel.RunOnGuestCoreProcess("am", [&] { AM::LoopProcess(*nv_flinger, system); });
265 ERPT::InstallInterfaces(*sm, system); 235 kernel.RunOnGuestCoreProcess("aoc", [&] { AOC::LoopProcess(system); });
266 ES::InstallInterfaces(*sm, system); 236 kernel.RunOnGuestCoreProcess("apm", [&] { APM::LoopProcess(system); });
267 EUPLD::InstallInterfaces(*sm, system); 237 kernel.RunOnGuestCoreProcess("bcat", [&] { BCAT::LoopProcess(system); });
268 Fatal::InstallInterfaces(*sm, system); 238 kernel.RunOnGuestCoreProcess("bpc", [&] { BPC::LoopProcess(system); });
269 FGM::InstallInterfaces(*sm, system); 239 kernel.RunOnGuestCoreProcess("btdrv", [&] { BtDrv::LoopProcess(system); });
270 FileSystem::InstallInterfaces(system); 240 kernel.RunOnGuestCoreProcess("btm", [&] { BTM::LoopProcess(system); });
271 Friend::InstallInterfaces(*sm, system); 241 kernel.RunOnGuestCoreProcess("capsrv", [&] { Capture::LoopProcess(system); });
272 Glue::InstallInterfaces(system); 242 kernel.RunOnGuestCoreProcess("erpt", [&] { ERPT::LoopProcess(system); });
273 GRC::InstallInterfaces(*sm, system); 243 kernel.RunOnGuestCoreProcess("es", [&] { ES::LoopProcess(system); });
274 HID::InstallInterfaces(*sm, system); 244 kernel.RunOnGuestCoreProcess("eupld", [&] { EUPLD::LoopProcess(system); });
275 JIT::InstallInterfaces(*sm, system); 245 kernel.RunOnGuestCoreProcess("fatal", [&] { Fatal::LoopProcess(system); });
276 LBL::InstallInterfaces(*sm, system); 246 kernel.RunOnGuestCoreProcess("fgm", [&] { FGM::LoopProcess(system); });
277 LDN::InstallInterfaces(*sm, system); 247 kernel.RunOnGuestCoreProcess("friends", [&] { Friend::LoopProcess(system); });
278 LDR::InstallInterfaces(*sm, system); 248 kernel.RunOnGuestCoreProcess("glue", [&] { Glue::LoopProcess(system); });
279 LM::InstallInterfaces(system); 249 kernel.RunOnGuestCoreProcess("grc", [&] { GRC::LoopProcess(system); });
280 Migration::InstallInterfaces(*sm, system); 250 kernel.RunOnGuestCoreProcess("hid", [&] { HID::LoopProcess(system); });
281 Mii::InstallInterfaces(*sm, system); 251 kernel.RunOnGuestCoreProcess("lbl", [&] { LBL::LoopProcess(system); });
282 MM::InstallInterfaces(*sm, system); 252 kernel.RunOnGuestCoreProcess("LogManager.Prod", [&] { LM::LoopProcess(system); });
283 MNPP::InstallInterfaces(*sm, system); 253 kernel.RunOnGuestCoreProcess("mig", [&] { Migration::LoopProcess(system); });
284 NCM::InstallInterfaces(*sm, system); 254 kernel.RunOnGuestCoreProcess("mii", [&] { Mii::LoopProcess(system); });
285 NFC::InstallInterfaces(*sm, system); 255 kernel.RunOnGuestCoreProcess("mm", [&] { MM::LoopProcess(system); });
286 NFP::InstallInterfaces(*sm, system); 256 kernel.RunOnGuestCoreProcess("mnpp", [&] { MNPP::LoopProcess(system); });
287 NGCT::InstallInterfaces(*sm, system); 257 kernel.RunOnGuestCoreProcess("NCM", [&] { NCM::LoopProcess(system); });
288 NIFM::InstallInterfaces(*sm, system); 258 kernel.RunOnGuestCoreProcess("nfc", [&] { NFC::LoopProcess(system); });
289 NIM::InstallInterfaces(*sm, system); 259 kernel.RunOnGuestCoreProcess("nfp", [&] { NFP::LoopProcess(system); });
290 NPNS::InstallInterfaces(*sm, system); 260 kernel.RunOnGuestCoreProcess("ngct", [&] { NGCT::LoopProcess(system); });
291 NS::InstallInterfaces(*sm, system); 261 kernel.RunOnGuestCoreProcess("nifm", [&] { NIFM::LoopProcess(system); });
292 Nvidia::InstallInterfaces(*sm, *nv_flinger, system); 262 kernel.RunOnGuestCoreProcess("nim", [&] { NIM::LoopProcess(system); });
293 OLSC::InstallInterfaces(*sm, system); 263 kernel.RunOnGuestCoreProcess("npns", [&] { NPNS::LoopProcess(system); });
294 PCIe::InstallInterfaces(*sm, system); 264 kernel.RunOnGuestCoreProcess("ns", [&] { NS::LoopProcess(system); });
295 PCTL::InstallInterfaces(*sm, system); 265 kernel.RunOnGuestCoreProcess("olsc", [&] { OLSC::LoopProcess(system); });
296 PCV::InstallInterfaces(*sm, system); 266 kernel.RunOnGuestCoreProcess("pcie", [&] { PCIe::LoopProcess(system); });
297 PlayReport::InstallInterfaces(*sm, system); 267 kernel.RunOnGuestCoreProcess("pctl", [&] { PCTL::LoopProcess(system); });
298 PM::InstallInterfaces(system); 268 kernel.RunOnGuestCoreProcess("pcv", [&] { PCV::LoopProcess(system); });
299 PSC::InstallInterfaces(*sm, system); 269 kernel.RunOnGuestCoreProcess("prepo", [&] { PlayReport::LoopProcess(system); });
300 PTM::InstallInterfaces(*sm, system); 270 kernel.RunOnGuestCoreProcess("ProcessManager", [&] { PM::LoopProcess(system); });
301 Set::InstallInterfaces(*sm, system); 271 kernel.RunOnGuestCoreProcess("psc", [&] { PSC::LoopProcess(system); });
302 Sockets::InstallInterfaces(*sm, system); 272 kernel.RunOnGuestCoreProcess("ptm", [&] { PTM::LoopProcess(system); });
303 SPL::InstallInterfaces(*sm, system); 273 kernel.RunOnGuestCoreProcess("settings", [&] { Set::LoopProcess(system); });
304 SSL::InstallInterfaces(*sm, system); 274 kernel.RunOnGuestCoreProcess("spl", [&] { SPL::LoopProcess(system); });
305 Time::InstallInterfaces(system); 275 kernel.RunOnGuestCoreProcess("ssl", [&] { SSL::LoopProcess(system); });
306 USB::InstallInterfaces(*sm, system); 276 kernel.RunOnGuestCoreProcess("time", [&] { Time::LoopProcess(system); });
307 VI::InstallInterfaces(*sm, system, *nv_flinger, *hos_binder_driver_server); 277 kernel.RunOnGuestCoreProcess("usb", [&] { USB::LoopProcess(system); });
278 // clang-format on
308} 279}
309 280
310Services::~Services() = default; 281Services::~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;
19 19
20namespace Kernel { 20namespace Kernel {
21class HLERequestContext; 21class HLERequestContext;
22class KClientPort;
23class KPort;
24class KServerSession; 22class KServerSession;
25class ServiceThread; 23class ServiceThread;
26} // namespace Kernel 24} // namespace Kernel
@@ -67,18 +65,12 @@ public:
67 return max_sessions; 65 return max_sessions;
68 } 66 }
69 67
70 /// Creates a port pair and registers this service with the given ServiceManager.
71 void InstallAsService(SM::ServiceManager& service_manager);
72
73 /// Invokes a service request routine using the HIPC protocol. 68 /// Invokes a service request routine using the HIPC protocol.
74 void InvokeRequest(Kernel::HLERequestContext& ctx); 69 void InvokeRequest(Kernel::HLERequestContext& ctx);
75 70
76 /// Invokes a service request routine using the HIPC protocol. 71 /// Invokes a service request routine using the HIPC protocol.
77 void InvokeRequestTipc(Kernel::HLERequestContext& ctx); 72 void InvokeRequestTipc(Kernel::HLERequestContext& ctx);
78 73
79 /// Creates a port pair and registers it on the kernel's global port registry.
80 Kernel::KClientPort& CreatePort();
81
82 /// Handles a synchronization request for the service. 74 /// Handles a synchronization request for the service.
83 Result HandleSyncRequest(Kernel::KServerSession& session, 75 Result HandleSyncRequest(Kernel::KServerSession& session,
84 Kernel::HLERequestContext& context) override; 76 Kernel::HLERequestContext& context) override;
@@ -99,9 +91,6 @@ protected:
99 /// Identifier string used to connect to the service. 91 /// Identifier string used to connect to the service.
100 std::string service_name; 92 std::string service_name;
101 93
102 /// Port used by ManageNamedPort.
103 Kernel::KPort* named_port{};
104
105private: 94private:
106 template <typename T> 95 template <typename T>
107 friend class ServiceFramework; 96 friend class ServiceFramework;
@@ -116,8 +105,7 @@ private:
116 Kernel::HLERequestContext& ctx); 105 Kernel::HLERequestContext& ctx);
117 106
118 explicit ServiceFrameworkBase(Core::System& system_, const char* service_name_, 107 explicit ServiceFrameworkBase(Core::System& system_, const char* service_name_,
119 ServiceThreadType thread_type, u32 max_sessions_, 108 u32 max_sessions_, InvokerFn* handler_invoker_);
120 InvokerFn* handler_invoker_);
121 ~ServiceFrameworkBase() override; 109 ~ServiceFrameworkBase() override;
122 110
123 void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n); 111 void RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n);
@@ -181,15 +169,12 @@ protected:
181 * 169 *
182 * @param system_ The system context to construct this service under. 170 * @param system_ The system context to construct this service under.
183 * @param service_name_ Name of the service. 171 * @param service_name_ Name of the service.
184 * @param thread_type Specifies the thread type for this service. If this is set to CreateNew,
185 * it creates a new thread for it, otherwise this uses the default thread.
186 * @param max_sessions_ Maximum number of sessions that can be connected to this service at the 172 * @param max_sessions_ Maximum number of sessions that can be connected to this service at the
187 * same time. 173 * same time.
188 */ 174 */
189 explicit ServiceFramework(Core::System& system_, const char* service_name_, 175 explicit ServiceFramework(Core::System& system_, const char* service_name_,
190 ServiceThreadType thread_type = ServiceThreadType::Default,
191 u32 max_sessions_ = ServerSessionCountMax) 176 u32 max_sessions_ = ServerSessionCountMax)
192 : ServiceFrameworkBase(system_, service_name_, thread_type, max_sessions_, Invoker) {} 177 : ServiceFrameworkBase(system_, service_name_, max_sessions_, Invoker) {}
193 178
194 /// Registers handlers in the service. 179 /// Registers handlers in the service.
195 template <std::size_t N> 180 template <std::size_t N>
diff --git a/src/core/hle/service/set/settings.cpp b/src/core/hle/service/set/settings.cpp
index 4ebc2a0ec..c48844f77 100644
--- a/src/core/hle/service/set/settings.cpp
+++ b/src/core/hle/service/set/settings.cpp
@@ -1,20 +1,23 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/server_manager.h"
4#include "core/hle/service/set/set.h" 5#include "core/hle/service/set/set.h"
5#include "core/hle/service/set/set_cal.h" 6#include "core/hle/service/set/set_cal.h"
6#include "core/hle/service/set/set_fd.h" 7#include "core/hle/service/set/set_fd.h"
7#include "core/hle/service/set/set_sys.h" 8#include "core/hle/service/set/set_sys.h"
8#include "core/hle/service/set/settings.h" 9#include "core/hle/service/set/settings.h"
9#include "core/hle/service/sm/sm.h"
10 10
11namespace Service::Set { 11namespace Service::Set {
12 12
13void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 13void LoopProcess(Core::System& system) {
14 std::make_shared<SET>(system)->InstallAsService(service_manager); 14 auto server_manager = std::make_unique<ServerManager>(system);
15 std::make_shared<SET_CAL>(system)->InstallAsService(service_manager); 15
16 std::make_shared<SET_FD>(system)->InstallAsService(service_manager); 16 server_manager->RegisterNamedService("set", std::make_shared<SET>(system));
17 std::make_shared<SET_SYS>(system)->InstallAsService(service_manager); 17 server_manager->RegisterNamedService("set:cal", std::make_shared<SET_CAL>(system));
18 server_manager->RegisterNamedService("set:fd", std::make_shared<SET_FD>(system));
19 server_manager->RegisterNamedService("set:sys", std::make_shared<SET_SYS>(system));
20 ServerManager::RunServer(std::move(server_manager));
18} 21}
19 22
20} // namespace Service::Set 23} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::Set { 10namespace Service::Set {
15 11
16/// Registers all Settings services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::Set 14} // namespace Service::Set
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 84720094f..53c877836 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -12,6 +12,7 @@
12#include "core/hle/kernel/k_scoped_resource_reservation.h" 12#include "core/hle/kernel/k_scoped_resource_reservation.h"
13#include "core/hle/kernel/k_server_port.h" 13#include "core/hle/kernel/k_server_port.h"
14#include "core/hle/result.h" 14#include "core/hle/result.h"
15#include "core/hle/service/server_manager.h"
15#include "core/hle/service/sm/sm.h" 16#include "core/hle/service/sm/sm.h"
16#include "core/hle/service/sm/sm_controller.h" 17#include "core/hle/service/sm/sm_controller.h"
17 18
@@ -22,13 +23,19 @@ constexpr Result ERR_ALREADY_REGISTERED(ErrorModule::SM, 4);
22constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6); 23constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6);
23constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); 24constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7);
24 25
25ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} 26ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {
27 controller_interface = std::make_unique<Controller>(kernel.System());
28}
26 29
27ServiceManager::~ServiceManager() { 30ServiceManager::~ServiceManager() {
28 for (auto& [name, port] : service_ports) { 31 for (auto& [name, port] : service_ports) {
29 port->GetClientPort().Close(); 32 port->GetClientPort().Close();
30 port->GetServerPort().Close(); 33 port->GetServerPort().Close();
31 } 34 }
35
36 if (deferral_event) {
37 deferral_event->Close();
38 }
32} 39}
33 40
34void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { 41void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) {
@@ -43,21 +50,12 @@ static Result ValidateServiceName(const std::string& name) {
43 return ResultSuccess; 50 return ResultSuccess;
44} 51}
45 52
46Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core::System& system) {
47 self.sm_interface = std::make_shared<SM>(self, system);
48 self.controller_interface = std::make_unique<Controller>(system);
49 return self.sm_interface->CreatePort();
50}
51
52void ServiceManager::SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port) {
53 self.sm_interface->AcceptSession(server_port);
54}
55
56Result ServiceManager::RegisterService(std::string name, u32 max_sessions, 53Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
57 Kernel::SessionRequestHandlerPtr handler) { 54 Kernel::SessionRequestHandlerPtr handler) {
58 55
59 CASCADE_CODE(ValidateServiceName(name)); 56 CASCADE_CODE(ValidateServiceName(name));
60 57
58 std::scoped_lock lk{lock};
61 if (registered_services.find(name) != registered_services.end()) { 59 if (registered_services.find(name) != registered_services.end()) {
62 LOG_ERROR(Service_SM, "Service is already registered! service={}", name); 60 LOG_ERROR(Service_SM, "Service is already registered! service={}", name);
63 return ERR_ALREADY_REGISTERED; 61 return ERR_ALREADY_REGISTERED;
@@ -68,6 +66,9 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
68 66
69 service_ports.emplace(name, port); 67 service_ports.emplace(name, port);
70 registered_services.emplace(name, handler); 68 registered_services.emplace(name, handler);
69 if (deferral_event) {
70 deferral_event->Signal();
71 }
71 72
72 return ResultSuccess; 73 return ResultSuccess;
73} 74}
@@ -75,6 +76,7 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
75Result ServiceManager::UnregisterService(const std::string& name) { 76Result ServiceManager::UnregisterService(const std::string& name) {
76 CASCADE_CODE(ValidateServiceName(name)); 77 CASCADE_CODE(ValidateServiceName(name));
77 78
79 std::scoped_lock lk{lock};
78 const auto iter = registered_services.find(name); 80 const auto iter = registered_services.find(name);
79 if (iter == registered_services.end()) { 81 if (iter == registered_services.end()) {
80 LOG_ERROR(Service_SM, "Server is not registered! service={}", name); 82 LOG_ERROR(Service_SM, "Server is not registered! service={}", name);
@@ -89,9 +91,11 @@ Result ServiceManager::UnregisterService(const std::string& name) {
89 91
90ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { 92ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) {
91 CASCADE_CODE(ValidateServiceName(name)); 93 CASCADE_CODE(ValidateServiceName(name));
94
95 std::scoped_lock lk{lock};
92 auto it = service_ports.find(name); 96 auto it = service_ports.find(name);
93 if (it == service_ports.end()) { 97 if (it == service_ports.end()) {
94 LOG_ERROR(Service_SM, "Server is not registered! service={}", name); 98 LOG_WARNING(Service_SM, "Server is not registered! service={}", name);
95 return ERR_SERVICE_NOT_REGISTERED; 99 return ERR_SERVICE_NOT_REGISTERED;
96 } 100 }
97 101
@@ -108,7 +112,7 @@ ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name
108void SM::Initialize(Kernel::HLERequestContext& ctx) { 112void SM::Initialize(Kernel::HLERequestContext& ctx) {
109 LOG_DEBUG(Service_SM, "called"); 113 LOG_DEBUG(Service_SM, "called");
110 114
111 is_initialized = true; 115 ctx.GetManager()->SetIsInitializedForSm();
112 116
113 IPC::ResponseBuilder rb{ctx, 2}; 117 IPC::ResponseBuilder rb{ctx, 2};
114 rb.Push(ResultSuccess); 118 rb.Push(ResultSuccess);
@@ -116,6 +120,11 @@ void SM::Initialize(Kernel::HLERequestContext& ctx) {
116 120
117void SM::GetService(Kernel::HLERequestContext& ctx) { 121void SM::GetService(Kernel::HLERequestContext& ctx) {
118 auto result = GetServiceImpl(ctx); 122 auto result = GetServiceImpl(ctx);
123 if (ctx.GetIsDeferred()) {
124 // Don't overwrite the command buffer.
125 return;
126 }
127
119 if (result.Succeeded()) { 128 if (result.Succeeded()) {
120 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 129 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
121 rb.Push(result.Code()); 130 rb.Push(result.Code());
@@ -128,6 +137,11 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
128 137
129void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) { 138void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) {
130 auto result = GetServiceImpl(ctx); 139 auto result = GetServiceImpl(ctx);
140 if (ctx.GetIsDeferred()) {
141 // Don't overwrite the command buffer.
142 return;
143 }
144
131 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 145 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
132 rb.Push(result.Code()); 146 rb.Push(result.Code());
133 rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr); 147 rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr);
@@ -145,7 +159,7 @@ static std::string PopServiceName(IPC::RequestParser& rp) {
145} 159}
146 160
147ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& ctx) { 161ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& ctx) {
148 if (!is_initialized) { 162 if (!ctx.GetManager()->GetIsInitializedForSm()) {
149 return ERR_NOT_INITIALIZED; 163 return ERR_NOT_INITIALIZED;
150 } 164 }
151 165
@@ -154,10 +168,15 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
154 168
155 // Find the named port. 169 // Find the named port.
156 auto port_result = service_manager.GetServicePort(name); 170 auto port_result = service_manager.GetServicePort(name);
157 auto service = service_manager.GetService<Kernel::SessionRequestHandler>(name); 171 if (port_result.Code() == ERR_INVALID_NAME) {
158 if (port_result.Failed() || !service) { 172 LOG_ERROR(Service_SM, "Invalid service name '{}'", name);
159 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); 173 return ERR_INVALID_NAME;
160 return port_result.Code(); 174 }
175
176 if (port_result.Failed()) {
177 LOG_INFO(Service_SM, "Waiting for service {} to become available", name);
178 ctx.SetIsDeferred();
179 return ERR_SERVICE_NOT_REGISTERED;
161 } 180 }
162 auto& port = port_result.Unwrap(); 181 auto& port = port_result.Unwrap();
163 182
@@ -167,7 +186,6 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
167 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); 186 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);
168 return result; 187 return result;
169 } 188 }
170 service->AcceptSession(&port->GetServerPort());
171 189
172 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); 190 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId());
173 191
@@ -212,7 +230,7 @@ void SM::UnregisterService(Kernel::HLERequestContext& ctx) {
212} 230}
213 231
214SM::SM(ServiceManager& service_manager_, Core::System& system_) 232SM::SM(ServiceManager& service_manager_, Core::System& system_)
215 : ServiceFramework{system_, "sm:", ServiceThreadType::Default, 4}, 233 : ServiceFramework{system_, "sm:", 4},
216 service_manager{service_manager_}, kernel{system_.Kernel()} { 234 service_manager{service_manager_}, kernel{system_.Kernel()} {
217 RegisterHandlers({ 235 RegisterHandlers({
218 {0, &SM::Initialize, "Initialize"}, 236 {0, &SM::Initialize, "Initialize"},
@@ -232,4 +250,16 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)
232 250
233SM::~SM() = default; 251SM::~SM() = default;
234 252
253void LoopProcess(Core::System& system) {
254 auto& service_manager = system.ServiceManager();
255 auto server_manager = std::make_unique<ServerManager>(system);
256
257 Kernel::KEvent* deferral_event{};
258 server_manager->ManageDeferral(&deferral_event);
259 service_manager.SetDeferralEvent(deferral_event);
260
261 server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system));
262 ServerManager::RunServer(std::move(server_manager));
263}
264
235} // namespace Service::SM 265} // namespace Service::SM
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 02a5dde9e..b7eeafdd6 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -4,6 +4,7 @@
4#pragma once 4#pragma once
5 5
6#include <memory> 6#include <memory>
7#include <mutex>
7#include <string> 8#include <string>
8#include <unordered_map> 9#include <unordered_map>
9 10
@@ -50,9 +51,6 @@ private:
50 51
51class ServiceManager { 52class ServiceManager {
52public: 53public:
53 static Kernel::KClientPort& InterfaceFactory(ServiceManager& self, Core::System& system);
54 static void SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port);
55
56 explicit ServiceManager(Kernel::KernelCore& kernel_); 54 explicit ServiceManager(Kernel::KernelCore& kernel_);
57 ~ServiceManager(); 55 ~ServiceManager();
58 56
@@ -73,16 +71,25 @@ public:
73 71
74 void InvokeControlRequest(Kernel::HLERequestContext& context); 72 void InvokeControlRequest(Kernel::HLERequestContext& context);
75 73
74 void SetDeferralEvent(Kernel::KEvent* deferral_event_) {
75 deferral_event = deferral_event_;
76 }
77
76private: 78private:
77 std::shared_ptr<SM> sm_interface; 79 std::shared_ptr<SM> sm_interface;
78 std::unique_ptr<Controller> controller_interface; 80 std::unique_ptr<Controller> controller_interface;
79 81
80 /// Map of registered services, retrieved using GetServicePort. 82 /// Map of registered services, retrieved using GetServicePort.
83 std::mutex lock;
81 std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services; 84 std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services;
82 std::unordered_map<std::string, Kernel::KPort*> service_ports; 85 std::unordered_map<std::string, Kernel::KPort*> service_ports;
83 86
84 /// Kernel context 87 /// Kernel context
85 Kernel::KernelCore& kernel; 88 Kernel::KernelCore& kernel;
89 Kernel::KEvent* deferral_event{};
86}; 90};
87 91
92/// Runs SM services.
93void LoopProcess(Core::System& system);
94
88} // namespace Service::SM 95} // 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 @@
10#include "core/hle/kernel/k_scoped_resource_reservation.h" 10#include "core/hle/kernel/k_scoped_resource_reservation.h"
11#include "core/hle/kernel/k_server_session.h" 11#include "core/hle/kernel/k_server_session.h"
12#include "core/hle/kernel/k_session.h" 12#include "core/hle/kernel/k_session.h"
13#include "core/hle/service/server_manager.h"
13#include "core/hle/service/sm/sm_controller.h" 14#include "core/hle/service/sm/sm_controller.h"
14 15
15namespace Service::SM { 16namespace Service::SM {
@@ -48,9 +49,9 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
48 // Commit the session reservation. 49 // Commit the session reservation.
49 session_reservation.Commit(); 50 session_reservation.Commit();
50 51
51 // Register with manager. 52 // Register with server manager.
52 session_manager->SessionHandler().RegisterSession(&session->GetServerSession(), 53 session_manager->GetServerManager().RegisterSession(&session->GetServerSession(),
53 session_manager); 54 session_manager);
54 55
55 // We succeeded. 56 // We succeeded.
56 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 57 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp
index 330a66409..2789fa1ed 100644
--- a/src/core/hle/service/sockets/bsd.cpp
+++ b/src/core/hle/service/sockets/bsd.cpp
@@ -881,8 +881,7 @@ void BSD::OnProxyPacketReceived(const Network::ProxyPacket& packet) {
881} 881}
882 882
883BSD::BSD(Core::System& system_, const char* name) 883BSD::BSD(Core::System& system_, const char* name)
884 : ServiceFramework{system_, name, ServiceThreadType::CreateNew}, room_network{ 884 : ServiceFramework{system_, name}, room_network{system_.GetRoomNetwork()} {
885 system_.GetRoomNetwork()} {
886 // clang-format off 885 // clang-format off
887 static const FunctionInfo functions[] = { 886 static const FunctionInfo functions[] = {
888 {0, &BSD::RegisterClient, "RegisterClient"}, 887 {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 @@
1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/service/server_manager.h"
4#include "core/hle/service/sockets/bsd.h" 5#include "core/hle/service/sockets/bsd.h"
5#include "core/hle/service/sockets/nsd.h" 6#include "core/hle/service/sockets/nsd.h"
6#include "core/hle/service/sockets/sfdnsres.h" 7#include "core/hle/service/sockets/sfdnsres.h"
@@ -8,15 +9,17 @@
8 9
9namespace Service::Sockets { 10namespace Service::Sockets {
10 11
11void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 12void LoopProcess(Core::System& system) {
12 std::make_shared<BSD>(system, "bsd:s")->InstallAsService(service_manager); 13 auto server_manager = std::make_unique<ServerManager>(system);
13 std::make_shared<BSD>(system, "bsd:u")->InstallAsService(service_manager);
14 std::make_shared<BSDCFG>(system)->InstallAsService(service_manager);
15 14
16 std::make_shared<NSD>(system, "nsd:a")->InstallAsService(service_manager); 15 server_manager->RegisterNamedService("bsd:s", std::make_shared<BSD>(system, "bsd:s"));
17 std::make_shared<NSD>(system, "nsd:u")->InstallAsService(service_manager); 16 server_manager->RegisterNamedService("bsd:u", std::make_shared<BSD>(system, "bsd:u"));
18 17 server_manager->RegisterNamedService("bsdcfg", std::make_shared<BSDCFG>(system));
19 std::make_shared<SFDNSRES>(system)->InstallAsService(service_manager); 18 server_manager->RegisterNamedService("nsd:a", std::make_shared<NSD>(system, "nsd:a"));
19 server_manager->RegisterNamedService("nsd:u", std::make_shared<NSD>(system, "nsd:u"));
20 server_manager->RegisterNamedService("sfdnsres", std::make_shared<SFDNSRES>(system));
21 server_manager->StartAdditionalHostThreads("bsdsocket", 2);
22 ServerManager::RunServer(std::move(server_manager));
20} 23}
21 24
22} // namespace Service::Sockets 25} // namespace Service::Sockets
diff --git a/src/core/hle/service/sockets/sockets.h b/src/core/hle/service/sockets/sockets.h
index 9840c11f9..acd2dae7b 100644
--- a/src/core/hle/service/sockets/sockets.h
+++ b/src/core/hle/service/sockets/sockets.h
@@ -10,10 +10,6 @@ namespace Core {
10class System; 10class System;
11} 11}
12 12
13namespace Service::SM {
14class ServiceManager;
15}
16
17namespace Service::Sockets { 13namespace Service::Sockets {
18 14
19enum class Errno : u32 { 15enum class Errno : u32 {
@@ -99,7 +95,6 @@ struct Linger {
99 u32 linger; 95 u32 linger;
100}; 96};
101 97
102/// Registers all Sockets services with the specified service manager. 98void LoopProcess(Core::System& system);
103void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
104 99
105} // namespace Service::Sockets 100} // 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 @@
9#include "common/settings.h" 9#include "common/settings.h"
10#include "core/hle/api_version.h" 10#include "core/hle/api_version.h"
11#include "core/hle/ipc_helpers.h" 11#include "core/hle/ipc_helpers.h"
12#include "core/hle/service/server_manager.h"
12#include "core/hle/service/spl/csrng.h" 13#include "core/hle/service/spl/csrng.h"
13#include "core/hle/service/spl/spl.h" 14#include "core/hle/service/spl/spl.h"
14#include "core/hle/service/spl/spl_module.h" 15#include "core/hle/service/spl/spl_module.h"
@@ -158,15 +159,18 @@ ResultVal<u64> Module::Interface::GetConfigImpl(ConfigItem config_item) const {
158 } 159 }
159} 160}
160 161
161void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 162void LoopProcess(Core::System& system) {
163 auto server_manager = std::make_unique<ServerManager>(system);
162 auto module = std::make_shared<Module>(); 164 auto module = std::make_shared<Module>();
163 std::make_shared<CSRNG>(system, module)->InstallAsService(service_manager); 165
164 std::make_shared<SPL>(system, module)->InstallAsService(service_manager); 166 server_manager->RegisterNamedService("csrng", std::make_shared<CSRNG>(system, module));
165 std::make_shared<SPL_MIG>(system, module)->InstallAsService(service_manager); 167 server_manager->RegisterNamedService("spl", std::make_shared<SPL>(system, module));
166 std::make_shared<SPL_FS>(system, module)->InstallAsService(service_manager); 168 server_manager->RegisterNamedService("spl:mig", std::make_shared<SPL_MIG>(system, module));
167 std::make_shared<SPL_SSL>(system, module)->InstallAsService(service_manager); 169 server_manager->RegisterNamedService("spl:fs", std::make_shared<SPL_FS>(system, module));
168 std::make_shared<SPL_ES>(system, module)->InstallAsService(service_manager); 170 server_manager->RegisterNamedService("spl:ssl", std::make_shared<SPL_SSL>(system, module));
169 std::make_shared<SPL_MANU>(system, module)->InstallAsService(service_manager); 171 server_manager->RegisterNamedService("spl:es", std::make_shared<SPL_ES>(system, module));
172 server_manager->RegisterNamedService("spl:manu", std::make_shared<SPL_MANU>(system, module));
173 ServerManager::RunServer(std::move(server_manager));
170} 174}
171 175
172} // namespace Service::SPL 176} // 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:
41 }; 41 };
42}; 42};
43 43
44/// Registers all SPL services with the specified service manager. 44void LoopProcess(Core::System& system);
45void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
46 45
47} // namespace Service::SPL 46} // namespace Service::SPL
diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp
index 015208593..c1fd1a59b 100644
--- a/src/core/hle/service/ssl/ssl.cpp
+++ b/src/core/hle/service/ssl/ssl.cpp
@@ -2,8 +2,8 @@
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/ipc_helpers.h" 4#include "core/hle/ipc_helpers.h"
5#include "core/hle/service/server_manager.h"
5#include "core/hle/service/service.h" 6#include "core/hle/service/service.h"
6#include "core/hle/service/sm/sm.h"
7#include "core/hle/service/ssl/ssl.h" 7#include "core/hle/service/ssl/ssl.h"
8 8
9namespace Service::SSL { 9namespace Service::SSL {
@@ -183,8 +183,11 @@ private:
183 } 183 }
184}; 184};
185 185
186void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) { 186void LoopProcess(Core::System& system) {
187 std::make_shared<SSL>(system)->InstallAsService(service_manager); 187 auto server_manager = std::make_unique<ServerManager>(system);
188
189 server_manager->RegisterNamedService("ssl", std::make_shared<SSL>(system));
190 ServerManager::RunServer(std::move(server_manager));
188} 191}
189 192
190} // namespace Service::SSL 193} // 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 {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::SSL { 10namespace Service::SSL {
15 11
16/// Registers all SSL services with the specified service manager. 12void LoopProcess(Core::System& system);
17void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
18 13
19} // namespace Service::SSL 14} // 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 @@
7#include "core/hardware_properties.h" 7#include "core/hardware_properties.h"
8#include "core/hle/ipc_helpers.h" 8#include "core/hle/ipc_helpers.h"
9#include "core/hle/kernel/kernel.h" 9#include "core/hle/kernel/kernel.h"
10#include "core/hle/service/server_manager.h"
10#include "core/hle/service/time/time.h" 11#include "core/hle/service/time/time.h"
11#include "core/hle/service/time/time_interface.h" 12#include "core/hle/service/time/time_interface.h"
12#include "core/hle/service/time/time_manager.h" 13#include "core/hle/service/time/time_manager.h"
@@ -397,11 +398,17 @@ Module::Interface::Interface(std::shared_ptr<Module> module_, Core::System& syst
397 398
398Module::Interface::~Interface() = default; 399Module::Interface::~Interface() = default;
399 400
400void InstallInterfaces(Core::System& system) { 401void LoopProcess(Core::System& system) {
402 auto server_manager = std::make_unique<ServerManager>(system);
401 auto module{std::make_shared<Module>()}; 403 auto module{std::make_shared<Module>()};
402 std::make_shared<Time>(module, system, "time:a")->InstallAsService(system.ServiceManager()); 404
403 std::make_shared<Time>(module, system, "time:s")->InstallAsService(system.ServiceManager()); 405 server_manager->RegisterNamedService("time:a",
404 std::make_shared<Time>(module, system, "time:u")->InstallAsService(system.ServiceManager()); 406 std::make_shared<Time>(module, system, "time:a"));
407 server_manager->RegisterNamedService("time:s",
408 std::make_shared<Time>(module, system, "time:s"));
409 server_manager->RegisterNamedService("time:u",
410 std::make_shared<Time>(module, system, "time:u"));
411 ServerManager::RunServer(std::move(server_manager));
405} 412}
406 413
407} // namespace Service::Time 414} // namespace Service::Time
diff --git a/src/core/hle/service/time/time.h b/src/core/hle/service/time/time.h
index 76a46cfc7..c9936c645 100644
--- a/src/core/hle/service/time/time.h
+++ b/src/core/hle/service/time/time.h
@@ -46,7 +46,6 @@ public:
46 }; 46 };
47}; 47};
48 48
49/// Registers all Time services with the specified service manager. 49void LoopProcess(Core::System& system);
50void InstallInterfaces(Core::System& system);
51 50
52} // namespace Service::Time 51} // namespace Service::Time
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
index ac46a406c..ddb73f394 100644
--- a/src/core/hle/service/usb/usb.cpp
+++ b/src/core/hle/service/usb/usb.cpp
@@ -5,8 +5,8 @@
5 5
6#include "common/logging/log.h" 6#include "common/logging/log.h"
7#include "core/hle/ipc_helpers.h" 7#include "core/hle/ipc_helpers.h"
8#include "core/hle/service/server_manager.h"
8#include "core/hle/service/service.h" 9#include "core/hle/service/service.h"
9#include "core/hle/service/sm/sm.h"
10#include "core/hle/service/usb/usb.h" 10#include "core/hle/service/usb/usb.h"
11 11
12namespace Service::USB { 12namespace Service::USB {
@@ -218,12 +218,15 @@ public:
218 } 218 }
219}; 219};
220 220
221void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { 221void LoopProcess(Core::System& system) {
222 std::make_shared<USB_DS>(system)->InstallAsService(sm); 222 auto server_manager = std::make_unique<ServerManager>(system);
223 std::make_shared<USB_HS>(system)->InstallAsService(sm); 223
224 std::make_shared<USB_PD>(system)->InstallAsService(sm); 224 server_manager->RegisterNamedService("usb:ds", std::make_shared<USB_DS>(system));
225 std::make_shared<USB_PD_C>(system)->InstallAsService(sm); 225 server_manager->RegisterNamedService("usb:hs", std::make_shared<USB_HS>(system));
226 std::make_shared<USB_PM>(system)->InstallAsService(sm); 226 server_manager->RegisterNamedService("usb:pd", std::make_shared<USB_PD>(system));
227 server_manager->RegisterNamedService("usb:pd:c", std::make_shared<USB_PD_C>(system));
228 server_manager->RegisterNamedService("usb:pm", std::make_shared<USB_PM>(system));
229 ServerManager::RunServer(std::move(server_manager));
227} 230}
228 231
229} // namespace Service::USB 232} // namespace Service::USB
diff --git a/src/core/hle/service/usb/usb.h b/src/core/hle/service/usb/usb.h
index b41b9684c..98376ebc0 100644
--- a/src/core/hle/service/usb/usb.h
+++ b/src/core/hle/service/usb/usb.h
@@ -7,12 +7,8 @@ namespace Core {
7class System; 7class System;
8} 8}
9 9
10namespace Service::SM {
11class ServiceManager;
12}
13
14namespace Service::USB { 10namespace Service::USB {
15 11
16void InstallInterfaces(SM::ServiceManager& sm, Core::System& system); 12void LoopProcess(Core::System& system);
17 13
18} // namespace Service::USB 14} // namespace Service::USB
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 0915785d2..d9cfebd70 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -26,6 +26,7 @@
26#include "core/hle/service/nvflinger/hos_binder_driver_server.h" 26#include "core/hle/service/nvflinger/hos_binder_driver_server.h"
27#include "core/hle/service/nvflinger/nvflinger.h" 27#include "core/hle/service/nvflinger/nvflinger.h"
28#include "core/hle/service/nvflinger/parcel.h" 28#include "core/hle/service/nvflinger/parcel.h"
29#include "core/hle/service/server_manager.h"
29#include "core/hle/service/service.h" 30#include "core/hle/service/service.h"
30#include "core/hle/service/vi/vi.h" 31#include "core/hle/service/vi/vi.h"
31#include "core/hle/service/vi/vi_m.h" 32#include "core/hle/service/vi/vi_m.h"
@@ -73,8 +74,7 @@ static_assert(sizeof(NativeWindow) == 0x28, "NativeWindow has wrong size");
73class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> { 74class IHOSBinderDriver final : public ServiceFramework<IHOSBinderDriver> {
74public: 75public:
75 explicit IHOSBinderDriver(Core::System& system_, NVFlinger::HosBinderDriverServer& server_) 76 explicit IHOSBinderDriver(Core::System& system_, NVFlinger::HosBinderDriverServer& server_)
76 : ServiceFramework{system_, "IHOSBinderDriver", ServiceThreadType::CreateNew}, 77 : ServiceFramework{system_, "IHOSBinderDriver"}, server(server_) {
77 server(server_) {
78 static const FunctionInfo functions[] = { 78 static const FunctionInfo functions[] = {
79 {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"}, 79 {0, &IHOSBinderDriver::TransactParcel, "TransactParcel"},
80 {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"}, 80 {1, &IHOSBinderDriver::AdjustRefcount, "AdjustRefcount"},
@@ -809,15 +809,17 @@ void detail::GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System&
809 rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger, hos_binder_driver_server); 809 rb.PushIpcInterface<IApplicationDisplayService>(system, nv_flinger, hos_binder_driver_server);
810} 810}
811 811
812void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system, 812void LoopProcess(Core::System& system, NVFlinger::NVFlinger& nv_flinger,
813 NVFlinger::NVFlinger& nv_flinger, 813 NVFlinger::HosBinderDriverServer& hos_binder_driver_server) {
814 NVFlinger::HosBinderDriverServer& hos_binder_driver_server) { 814 auto server_manager = std::make_unique<ServerManager>(system);
815 std::make_shared<VI_M>(system, nv_flinger, hos_binder_driver_server) 815
816 ->InstallAsService(service_manager); 816 server_manager->RegisterNamedService(
817 std::make_shared<VI_S>(system, nv_flinger, hos_binder_driver_server) 817 "vi:m", std::make_shared<VI_M>(system, nv_flinger, hos_binder_driver_server));
818 ->InstallAsService(service_manager); 818 server_manager->RegisterNamedService(
819 std::make_shared<VI_U>(system, nv_flinger, hos_binder_driver_server) 819 "vi:s", std::make_shared<VI_S>(system, nv_flinger, hos_binder_driver_server));
820 ->InstallAsService(service_manager); 820 server_manager->RegisterNamedService(
821 "vi:u", std::make_shared<VI_U>(system, nv_flinger, hos_binder_driver_server));
822 ServerManager::RunServer(std::move(server_manager));
821} 823}
822 824
823} // namespace Service::VI 825} // namespace Service::VI
diff --git a/src/core/hle/service/vi/vi.h b/src/core/hle/service/vi/vi.h
index fc2d717e7..4ed7aaf2b 100644
--- a/src/core/hle/service/vi/vi.h
+++ b/src/core/hle/service/vi/vi.h
@@ -18,10 +18,6 @@ class HosBinderDriverServer;
18class NVFlinger; 18class NVFlinger;
19} // namespace Service::NVFlinger 19} // namespace Service::NVFlinger
20 20
21namespace Service::SM {
22class ServiceManager;
23}
24
25namespace Service::VI { 21namespace Service::VI {
26 22
27enum class DisplayResolution : u32 { 23enum class DisplayResolution : u32 {
@@ -52,9 +48,7 @@ void GetDisplayServiceImpl(Kernel::HLERequestContext& ctx, Core::System& system,
52 Permission permission); 48 Permission permission);
53} // namespace detail 49} // namespace detail
54 50
55/// Registers all VI services with the specified service manager. 51void LoopProcess(Core::System& system, NVFlinger::NVFlinger& nv_flinger,
56void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system, 52 NVFlinger::HosBinderDriverServer& hos_binder_driver_server);
57 NVFlinger::NVFlinger& nv_flinger,
58 NVFlinger::HosBinderDriverServer& hos_binder_driver_server);
59 53
60} // namespace Service::VI 54} // namespace Service::VI
diff --git a/src/core/memory/cheat_engine.cpp b/src/core/memory/cheat_engine.cpp
index 44ee39648..c2d96bbec 100644
--- a/src/core/memory/cheat_engine.cpp
+++ b/src/core/memory/cheat_engine.cpp
@@ -47,8 +47,13 @@ void StandardVmCallbacks::MemoryWrite(VAddr address, const void* data, u64 size)
47} 47}
48 48
49u64 StandardVmCallbacks::HidKeysDown() { 49u64 StandardVmCallbacks::HidKeysDown() {
50 const auto applet_resource = 50 const auto hid = system.ServiceManager().GetService<Service::HID::Hid>("hid");
51 system.ServiceManager().GetService<Service::HID::Hid>("hid")->GetAppletResource(); 51 if (hid == nullptr) {
52 LOG_WARNING(CheatEngine, "Attempted to read input state, but hid is not initialized!");
53 return 0;
54 }
55
56 const auto applet_resource = hid->GetAppletResource();
52 if (applet_resource == nullptr) { 57 if (applet_resource == nullptr) {
53 LOG_WARNING(CheatEngine, 58 LOG_WARNING(CheatEngine,
54 "Attempted to read input state, but applet resource is not initialized!"); 59 "Attempted to read input state, but applet resource is not initialized!");