summaryrefslogtreecommitdiff
path: root/src/core/hle/service/sm
diff options
context:
space:
mode:
authorGravatar Liam2023-12-17 20:46:41 -0500
committerGravatar Liam2023-12-22 21:52:49 -0500
commit31bf57a310f3b3417e96ec9e1cee6c1c817882d9 (patch)
treec5101e70584301cfc452641544cd31d4d4c6d105 /src/core/hle/service/sm
parentk_server_session: remove scratch buffer usage in favor of direct copy (diff)
downloadyuzu-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.cpp36
-rw-r--r--src/core/hle/service/sm/sm.h8
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
30ServiceManager::~ServiceManager() { 30ServiceManager::~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
53Result ServiceManager::RegisterService(std::string name, u32 max_sessions, 52Result 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
78Result ServiceManager::UnregisterService(const std::string& name) { 81Result 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
94Result ServiceManager::GetServicePort(Kernel::KPort** out_port, const std::string& name) { 97Result 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
241void SM::UnregisterService(HLERequestContext& ctx) { 243void 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;