diff options
| author | 2023-12-17 20:46:41 -0500 | |
|---|---|---|
| committer | 2023-12-22 21:52:49 -0500 | |
| commit | 31bf57a310f3b3417e96ec9e1cee6c1c817882d9 (patch) | |
| tree | c5101e70584301cfc452641544cd31d4d4c6d105 /src/core/hle/service/sm | |
| parent | k_server_session: remove scratch buffer usage in favor of direct copy (diff) | |
| download | yuzu-31bf57a310f3b3417e96ec9e1cee6c1c817882d9.tar.gz yuzu-31bf57a310f3b3417e96ec9e1cee6c1c817882d9.tar.xz yuzu-31bf57a310f3b3417e96ec9e1cee6c1c817882d9.zip | |
general: properly support multiple memory instances
Diffstat (limited to 'src/core/hle/service/sm')
| -rw-r--r-- | src/core/hle/service/sm/sm.cpp | 36 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 8 |
2 files changed, 23 insertions, 21 deletions
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 296ee6e89..1095dcf6c 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp | |||
| @@ -29,8 +29,7 @@ ServiceManager::ServiceManager(Kernel::KernelCore& kernel_) : kernel{kernel_} { | |||
| 29 | 29 | ||
| 30 | ServiceManager::~ServiceManager() { | 30 | ServiceManager::~ServiceManager() { |
| 31 | for (auto& [name, port] : service_ports) { | 31 | for (auto& [name, port] : service_ports) { |
| 32 | port->GetClientPort().Close(); | 32 | port->Close(); |
| 33 | port->GetServerPort().Close(); | ||
| 34 | } | 33 | } |
| 35 | 34 | ||
| 36 | if (deferral_event) { | 35 | if (deferral_event) { |
| @@ -50,8 +49,8 @@ static Result ValidateServiceName(const std::string& name) { | |||
| 50 | return ResultSuccess; | 49 | return ResultSuccess; |
| 51 | } | 50 | } |
| 52 | 51 | ||
| 53 | Result ServiceManager::RegisterService(std::string name, u32 max_sessions, | 52 | Result ServiceManager::RegisterService(Kernel::KServerPort** out_server_port, std::string name, |
| 54 | SessionRequestHandlerFactory handler) { | 53 | u32 max_sessions, SessionRequestHandlerFactory handler) { |
| 55 | R_TRY(ValidateServiceName(name)); | 54 | R_TRY(ValidateServiceName(name)); |
| 56 | 55 | ||
| 57 | std::scoped_lock lk{lock}; | 56 | std::scoped_lock lk{lock}; |
| @@ -66,13 +65,17 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions, | |||
| 66 | // Register the port. | 65 | // Register the port. |
| 67 | Kernel::KPort::Register(kernel, port); | 66 | Kernel::KPort::Register(kernel, port); |
| 68 | 67 | ||
| 69 | service_ports.emplace(name, port); | 68 | service_ports.emplace(name, std::addressof(port->GetClientPort())); |
| 70 | registered_services.emplace(name, handler); | 69 | registered_services.emplace(name, handler); |
| 71 | if (deferral_event) { | 70 | if (deferral_event) { |
| 72 | deferral_event->Signal(); | 71 | deferral_event->Signal(); |
| 73 | } | 72 | } |
| 74 | 73 | ||
| 75 | return ResultSuccess; | 74 | // Set our output. |
| 75 | *out_server_port = std::addressof(port->GetServerPort()); | ||
| 76 | |||
| 77 | // We succeeded. | ||
| 78 | R_SUCCEED(); | ||
| 76 | } | 79 | } |
| 77 | 80 | ||
| 78 | Result ServiceManager::UnregisterService(const std::string& name) { | 81 | Result ServiceManager::UnregisterService(const std::string& name) { |
| @@ -91,7 +94,8 @@ Result ServiceManager::UnregisterService(const std::string& name) { | |||
| 91 | return ResultSuccess; | 94 | return ResultSuccess; |
| 92 | } | 95 | } |
| 93 | 96 | ||
| 94 | Result ServiceManager::GetServicePort(Kernel::KPort** out_port, const std::string& name) { | 97 | Result ServiceManager::GetServicePort(Kernel::KClientPort** out_client_port, |
| 98 | const std::string& name) { | ||
| 95 | R_TRY(ValidateServiceName(name)); | 99 | R_TRY(ValidateServiceName(name)); |
| 96 | 100 | ||
| 97 | std::scoped_lock lk{lock}; | 101 | std::scoped_lock lk{lock}; |
| @@ -101,7 +105,7 @@ Result ServiceManager::GetServicePort(Kernel::KPort** out_port, const std::strin | |||
| 101 | return Service::SM::ResultNotRegistered; | 105 | return Service::SM::ResultNotRegistered; |
| 102 | } | 106 | } |
| 103 | 107 | ||
| 104 | *out_port = it->second; | 108 | *out_client_port = it->second; |
| 105 | return ResultSuccess; | 109 | return ResultSuccess; |
| 106 | } | 110 | } |
| 107 | 111 | ||
| @@ -172,8 +176,8 @@ Result SM::GetServiceImpl(Kernel::KClientSession** out_client_session, HLEReques | |||
| 172 | std::string name(PopServiceName(rp)); | 176 | std::string name(PopServiceName(rp)); |
| 173 | 177 | ||
| 174 | // Find the named port. | 178 | // Find the named port. |
| 175 | Kernel::KPort* port{}; | 179 | Kernel::KClientPort* client_port{}; |
| 176 | auto port_result = service_manager.GetServicePort(&port, name); | 180 | auto port_result = service_manager.GetServicePort(&client_port, name); |
| 177 | if (port_result == Service::SM::ResultInvalidServiceName) { | 181 | if (port_result == Service::SM::ResultInvalidServiceName) { |
| 178 | LOG_ERROR(Service_SM, "Invalid service name '{}'", name); | 182 | LOG_ERROR(Service_SM, "Invalid service name '{}'", name); |
| 179 | return Service::SM::ResultInvalidServiceName; | 183 | return Service::SM::ResultInvalidServiceName; |
| @@ -187,7 +191,7 @@ Result SM::GetServiceImpl(Kernel::KClientSession** out_client_session, HLEReques | |||
| 187 | 191 | ||
| 188 | // Create a new session. | 192 | // Create a new session. |
| 189 | Kernel::KClientSession* session{}; | 193 | Kernel::KClientSession* session{}; |
| 190 | if (const auto result = port->GetClientPort().CreateSession(&session); result.IsError()) { | 194 | if (const auto result = client_port->CreateSession(&session); result.IsError()) { |
| 191 | LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); | 195 | LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); |
| 192 | return result; | 196 | return result; |
| 193 | } | 197 | } |
| @@ -221,7 +225,9 @@ void SM::RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_s | |||
| 221 | LOG_DEBUG(Service_SM, "called with name={}, max_session_count={}, is_light={}", name, | 225 | LOG_DEBUG(Service_SM, "called with name={}, max_session_count={}, is_light={}", name, |
| 222 | max_session_count, is_light); | 226 | max_session_count, is_light); |
| 223 | 227 | ||
| 224 | if (const auto result = service_manager.RegisterService(name, max_session_count, nullptr); | 228 | Kernel::KServerPort* server_port{}; |
| 229 | if (const auto result = service_manager.RegisterService(std::addressof(server_port), name, | ||
| 230 | max_session_count, nullptr); | ||
| 225 | result.IsError()) { | 231 | result.IsError()) { |
| 226 | LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", result.raw); | 232 | LOG_ERROR(Service_SM, "failed to register service with error_code={:08X}", result.raw); |
| 227 | IPC::ResponseBuilder rb{ctx, 2}; | 233 | IPC::ResponseBuilder rb{ctx, 2}; |
| @@ -229,13 +235,9 @@ void SM::RegisterServiceImpl(HLERequestContext& ctx, std::string name, u32 max_s | |||
| 229 | return; | 235 | return; |
| 230 | } | 236 | } |
| 231 | 237 | ||
| 232 | auto* port = Kernel::KPort::Create(kernel); | ||
| 233 | port->Initialize(ServerSessionCountMax, is_light, 0); | ||
| 234 | SCOPE_EXIT({ port->GetClientPort().Close(); }); | ||
| 235 | |||
| 236 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; | 238 | IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; |
| 237 | rb.Push(ResultSuccess); | 239 | rb.Push(ResultSuccess); |
| 238 | rb.PushMoveObjects(port->GetServerPort()); | 240 | rb.PushMoveObjects(server_port); |
| 239 | } | 241 | } |
| 240 | 242 | ||
| 241 | void SM::UnregisterService(HLERequestContext& ctx) { | 243 | void SM::UnregisterService(HLERequestContext& ctx) { |
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index ff74f588a..4ae32a9c1 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h | |||
| @@ -56,10 +56,10 @@ public: | |||
| 56 | explicit ServiceManager(Kernel::KernelCore& kernel_); | 56 | explicit ServiceManager(Kernel::KernelCore& kernel_); |
| 57 | ~ServiceManager(); | 57 | ~ServiceManager(); |
| 58 | 58 | ||
| 59 | Result RegisterService(std::string name, u32 max_sessions, | 59 | Result RegisterService(Kernel::KServerPort** out_server_port, std::string name, |
| 60 | SessionRequestHandlerFactory handler_factory); | 60 | u32 max_sessions, SessionRequestHandlerFactory handler_factory); |
| 61 | Result UnregisterService(const std::string& name); | 61 | Result UnregisterService(const std::string& name); |
| 62 | Result GetServicePort(Kernel::KPort** out_port, const std::string& name); | 62 | Result GetServicePort(Kernel::KClientPort** out_client_port, const std::string& name); |
| 63 | 63 | ||
| 64 | template <Common::DerivedFrom<SessionRequestHandler> T> | 64 | template <Common::DerivedFrom<SessionRequestHandler> T> |
| 65 | std::shared_ptr<T> GetService(const std::string& service_name) const { | 65 | std::shared_ptr<T> GetService(const std::string& service_name) const { |
| @@ -84,7 +84,7 @@ private: | |||
| 84 | /// Map of registered services, retrieved using GetServicePort. | 84 | /// Map of registered services, retrieved using GetServicePort. |
| 85 | std::mutex lock; | 85 | std::mutex lock; |
| 86 | std::unordered_map<std::string, SessionRequestHandlerFactory> registered_services; | 86 | std::unordered_map<std::string, SessionRequestHandlerFactory> registered_services; |
| 87 | std::unordered_map<std::string, Kernel::KPort*> service_ports; | 87 | std::unordered_map<std::string, Kernel::KClientPort*> service_ports; |
| 88 | 88 | ||
| 89 | /// Kernel context | 89 | /// Kernel context |
| 90 | Kernel::KernelCore& kernel; | 90 | Kernel::KernelCore& kernel; |