diff options
| author | 2023-02-18 16:26:48 -0500 | |
|---|---|---|
| committer | 2023-02-21 12:19:25 -0500 | |
| commit | a9369726147c7499e0016e183d5d56a7b44efe4b (patch) | |
| tree | c1d1b4a9fdafd92863c0922b05d72c14de83ffa7 /src/core/hle/service/sm | |
| parent | core: defer cpu shutdown (diff) | |
| download | yuzu-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.cpp | 32 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 8 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm_controller.cpp | 7 |
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); | |||
| 22 | constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6); | 23 | constexpr Result ERR_INVALID_NAME(ErrorModule::SM, 6); |
| 23 | constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); | 24 | constexpr Result ERR_SERVICE_NOT_REGISTERED(ErrorModule::SM, 7); |
| 24 | 25 | ||
| 25 | ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} {} | 26 | ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} { |
| 27 | controller_interface = std::make_unique<Controller>(kernel.System()); | ||
| 28 | } | ||
| 26 | 29 | ||
| 27 | ServiceManager::~ServiceManager() { | 30 | ServiceManager::~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 | ||
| 46 | Kernel::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 | |||
| 52 | void ServiceManager::SessionHandler(ServiceManager& self, Kernel::KServerPort* server_port) { | ||
| 53 | self.sm_interface->AcceptSession(server_port); | ||
| 54 | } | ||
| 55 | |||
| 56 | Result ServiceManager::RegisterService(std::string name, u32 max_sessions, | 49 | Result 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, | |||
| 75 | Result ServiceManager::UnregisterService(const std::string& name) { | 69 | Result 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 | ||
| 90 | ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name) { | 85 | ResultVal<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 | ||
| 214 | SM::SM(ServiceManager& service_manager_, Core::System& system_) | 209 | SM::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 | ||
| 233 | SM::~SM() = default; | 228 | SM::~SM() = default; |
| 234 | 229 | ||
| 230 | void 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 | ||
| 51 | class ServiceManager { | 52 | class ServiceManager { |
| 52 | public: | 53 | public: |
| 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. | ||
| 88 | void 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 | ||
| 15 | namespace Service::SM { | 16 | namespace 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}; |