summaryrefslogtreecommitdiff
path: root/src/core/hle/service/sm
diff options
context:
space:
mode:
authorGravatar Liam2023-02-19 08:44:54 -0500
committerGravatar Liam2023-02-21 12:19:25 -0500
commit6e0a33089b97747ea0e3dc9d57e19223d420c98a (patch)
tree64e746021d186e84053c14f186f6434c69fcf910 /src/core/hle/service/sm
parentservice: refactor server architecture (diff)
downloadyuzu-6e0a33089b97747ea0e3dc9d57e19223d420c98a.tar.gz
yuzu-6e0a33089b97747ea0e3dc9d57e19223d420c98a.tar.xz
yuzu-6e0a33089b97747ea0e3dc9d57e19223d420c98a.zip
sm:: support service registration deferral
Diffstat (limited to 'src/core/hle/service/sm')
-rw-r--r--src/core/hle/service/sm/sm.cpp29
-rw-r--r--src/core/hle/service/sm/sm.h5
2 files changed, 31 insertions, 3 deletions
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 0de32b05d..6eba48f03 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -32,6 +32,10 @@ ServiceManager::~ServiceManager() {
32 port->GetClientPort().Close(); 32 port->GetClientPort().Close();
33 port->GetServerPort().Close(); 33 port->GetServerPort().Close();
34 } 34 }
35
36 if (deferral_event) {
37 deferral_event->Close();
38 }
35} 39}
36 40
37void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { 41void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) {
@@ -62,6 +66,9 @@ Result ServiceManager::RegisterService(std::string name, u32 max_sessions,
62 66
63 service_ports.emplace(name, port); 67 service_ports.emplace(name, port);
64 registered_services.emplace(name, handler); 68 registered_services.emplace(name, handler);
69 if (deferral_event) {
70 deferral_event->Signal();
71 }
65 72
66 return ResultSuccess; 73 return ResultSuccess;
67} 74}
@@ -88,7 +95,7 @@ ResultVal<Kernel::KPort*> ServiceManager::GetServicePort(const std::string& name
88 std::scoped_lock lk{lock}; 95 std::scoped_lock lk{lock};
89 auto it = service_ports.find(name); 96 auto it = service_ports.find(name);
90 if (it == service_ports.end()) { 97 if (it == service_ports.end()) {
91 LOG_ERROR(Service_SM, "Server is not registered! service={}", name); 98 LOG_WARNING(Service_SM, "Server is not registered! service={}", name);
92 return ERR_SERVICE_NOT_REGISTERED; 99 return ERR_SERVICE_NOT_REGISTERED;
93 } 100 }
94 101
@@ -113,6 +120,11 @@ void SM::Initialize(Kernel::HLERequestContext& ctx) {
113 120
114void SM::GetService(Kernel::HLERequestContext& ctx) { 121void SM::GetService(Kernel::HLERequestContext& ctx) {
115 auto result = GetServiceImpl(ctx); 122 auto result = GetServiceImpl(ctx);
123 if (ctx.GetIsDeferred()) {
124 // Don't overwrite the command buffer.
125 return;
126 }
127
116 if (result.Succeeded()) { 128 if (result.Succeeded()) {
117 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 129 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
118 rb.Push(result.Code()); 130 rb.Push(result.Code());
@@ -125,6 +137,11 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
125 137
126void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) { 138void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) {
127 auto result = GetServiceImpl(ctx); 139 auto result = GetServiceImpl(ctx);
140 if (ctx.GetIsDeferred()) {
141 // Don't overwrite the command buffer.
142 return;
143 }
144
128 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; 145 IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
129 rb.Push(result.Code()); 146 rb.Push(result.Code());
130 rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr); 147 rb.PushMoveObjects(result.Succeeded() ? result.Unwrap() : nullptr);
@@ -152,8 +169,9 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
152 // Find the named port. 169 // Find the named port.
153 auto port_result = service_manager.GetServicePort(name); 170 auto port_result = service_manager.GetServicePort(name);
154 if (port_result.Failed()) { 171 if (port_result.Failed()) {
155 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); 172 LOG_INFO(Service_SM, "Waiting for service {} to become available", name);
156 return port_result.Code(); 173 ctx.SetIsDeferred();
174 return ERR_SERVICE_NOT_REGISTERED;
157 } 175 }
158 auto& port = port_result.Unwrap(); 176 auto& port = port_result.Unwrap();
159 177
@@ -228,8 +246,13 @@ SM::SM(ServiceManager& service_manager_, Core::System& system_)
228SM::~SM() = default; 246SM::~SM() = default;
229 247
230void LoopProcess(Core::System& system) { 248void LoopProcess(Core::System& system) {
249 auto& service_manager = system.ServiceManager();
231 auto server_manager = std::make_unique<ServerManager>(system); 250 auto server_manager = std::make_unique<ServerManager>(system);
232 251
252 Kernel::KEvent* deferral_event{};
253 server_manager->ManageDeferral(&deferral_event);
254 service_manager.SetDeferralEvent(deferral_event);
255
233 server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system)); 256 server_manager->ManageNamedPort("sm:", std::make_shared<SM>(system.ServiceManager(), system));
234 ServerManager::RunServer(std::move(server_manager)); 257 ServerManager::RunServer(std::move(server_manager));
235} 258}
diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h
index 22ca720f8..b7eeafdd6 100644
--- a/src/core/hle/service/sm/sm.h
+++ b/src/core/hle/service/sm/sm.h
@@ -71,6 +71,10 @@ public:
71 71
72 void InvokeControlRequest(Kernel::HLERequestContext& context); 72 void InvokeControlRequest(Kernel::HLERequestContext& context);
73 73
74 void SetDeferralEvent(Kernel::KEvent* deferral_event_) {
75 deferral_event = deferral_event_;
76 }
77
74private: 78private:
75 std::shared_ptr<SM> sm_interface; 79 std::shared_ptr<SM> sm_interface;
76 std::unique_ptr<Controller> controller_interface; 80 std::unique_ptr<Controller> controller_interface;
@@ -82,6 +86,7 @@ private:
82 86
83 /// Kernel context 87 /// Kernel context
84 Kernel::KernelCore& kernel; 88 Kernel::KernelCore& kernel;
89 Kernel::KEvent* deferral_event{};
85}; 90};
86 91
87/// Runs SM services. 92/// Runs SM services.