summaryrefslogtreecommitdiff
path: root/src/core/hle/service/sm
diff options
context:
space:
mode:
authorGravatar Liam2023-02-18 16:26:48 -0500
committerGravatar Liam2023-02-21 12:19:25 -0500
commita9369726147c7499e0016e183d5d56a7b44efe4b (patch)
treec1d1b4a9fdafd92863c0922b05d72c14de83ffa7 /src/core/hle/service/sm
parentcore: defer cpu shutdown (diff)
downloadyuzu-a9369726147c7499e0016e183d5d56a7b44efe4b.tar.gz
yuzu-a9369726147c7499e0016e183d5d56a7b44efe4b.tar.xz
yuzu-a9369726147c7499e0016e183d5d56a7b44efe4b.zip
service: refactor server architecture
Converts services to have their own processes
Diffstat (limited to 'src/core/hle/service/sm')
-rw-r--r--src/core/hle/service/sm/sm.cpp32
-rw-r--r--src/core/hle/service/sm/sm.h8
-rw-r--r--src/core/hle/service/sm/sm_controller.cpp7
3 files changed, 26 insertions, 21 deletions
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 84720094f..0de32b05d 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -12,6 +12,7 @@
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,7 +23,9 @@ 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) {
@@ -43,21 +46,12 @@ static Result ValidateServiceName(const std::string& name) {
43 return ResultSuccess; 46 return ResultSuccess;
44} 47}
45 48
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, 49Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
57 Kernel::SessionRequestHandlerPtr handler) { 50 Kernel::SessionRequestHandlerPtr handler) {
58 51
59 CASCADE_CODE(ValidateServiceName(name)); 52 CASCADE_CODE(ValidateServiceName(name));
60 53
54 std::scoped_lock lk{lock};
61 if (registered_services.find(name) != registered_services.end()) { 55 if (registered_services.find(name) != registered_services.end()) {
62 LOG_ERROR(Service_SM, "Service is already registered! service={}", name); 56 LOG_ERROR(Service_SM, "Service is already registered! service={}", name);
63 return ERR_ALREADY_REGISTERED; 57 return ERR_ALREADY_REGISTERED;
@@ -75,6 +69,7 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
75Result ServiceManager::UnregisterService(const std::string& name) { 69Result ServiceManager::UnregisterService(const std::string& name) {
76 CASCADE_CODE(ValidateServiceName(name)); 70 CASCADE_CODE(ValidateServiceName(name));
77 71
72 std::scoped_lock lk{lock};
78 const auto iter = registered_services.find(name); 73 const auto iter = registered_services.find(name);
79 if (iter == registered_services.end()) { 74 if (iter == registered_services.end()) {
80 LOG_ERROR(Service_SM, "Server is not registered! service={}", name); 75 LOG_ERROR(Service_SM, "Server is not registered! service={}", name);
@@ -89,6 +84,8 @@ Result ServiceManager::UnregisterService(const std::string& name) {
89 84
90ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { 85ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) {
91 CASCADE_CODE(ValidateServiceName(name)); 86 CASCADE_CODE(ValidateServiceName(name));
87
88 std::scoped_lock lk{lock};
92 auto it = service_ports.find(name); 89 auto it = service_ports.find(name);
93 if (it == service_ports.end()) { 90 if (it == service_ports.end()) {
94 LOG_ERROR(Service_SM, "Server is not registered! service={}", name); 91 LOG_ERROR(Service_SM, "Server is not registered! service={}", name);
@@ -154,8 +151,7 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
154 151
155 // Find the named port. 152 // Find the named port.
156 auto port_result = service_manager.GetServicePort(name); 153 auto port_result = service_manager.GetServicePort(name);
157 auto service = service_manager.GetService<Kernel::SessionRequestHandler>(name); 154 if (port_result.Failed()) {
158 if (port_result.Failed() || !service) {
159 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); 155 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw);
160 return port_result.Code(); 156 return port_result.Code();
161 } 157 }
@@ -167,7 +163,6 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
167 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); 163 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);
168 return result; 164 return result;
169 } 165 }
170 service->AcceptSession(&port->GetServerPort());
171 166
172 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); 167 LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId());
173 168
@@ -212,7 +207,7 @@ void SM::UnregisterService(Kernel::HLERequestContext& ctx) {
212} 207}
213 208
214SM::SM(ServiceManager& service_manager_, Core::System& system_) 209SM::SM(ServiceManager& service_manager_, Core::System& system_)
215 : ServiceFramework{system_, "sm:", ServiceThreadType::Default, 4}, 210 : ServiceFramework{system_, "sm:", 4},
216 service_manager{service_manager_}, kernel{system_.Kernel()} { 211 service_manager{service_manager_}, kernel{system_.Kernel()} {
217 RegisterHandlers({ 212 RegisterHandlers({
218 {0, &SM::Initialize, "Initialize"}, 213 {0, &SM::Initialize, "Initialize"},
@@ -232,4 +227,11 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)
232 227
233SM::~SM() = default; 228SM::~SM() = default;
234 229
230void LoopProcess(Core::System& system) {
231 auto server_manager = std::make_unique<ServerManager>(system);
232
233 server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system));
234 ServerManager::RunServer(std::move(server_manager));
235}
236
235} // namespace Service::SM 237} // namespace Service::SM
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 02a5dde9e..22ca720f8 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -4,6 +4,7 @@
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
@@ -78,6 +76,7 @@ private:
78 std::unique_ptr<Controller> controller_interface; 76 std::unique_ptr<Controller> controller_interface;
79 77
80 /// Map of registered services, retrieved using GetServicePort. 78 /// Map of registered services, retrieved using GetServicePort.
79 std::mutex lock;
81 std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services; 80 std::unordered_map<std::string, Kernel::SessionRequestHandlerPtr> registered_services;
82 std::unordered_map<std::string, Kernel::KPort*> service_ports; 81 std::unordered_map<std::string, Kernel::KPort*> service_ports;
83 82
@@ -85,4 +84,7 @@ private:
85 Kernel::KernelCore& kernel; 84 Kernel::KernelCore& kernel;
86}; 85};
87 86
87/// Runs SM services.
88void LoopProcess(Core::System& system);
89
88} // namespace Service::SM 90} // 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};