diff options
| author | 2023-02-19 08:44:54 -0500 | |
|---|---|---|
| committer | 2023-02-21 12:19:25 -0500 | |
| commit | 6e0a33089b97747ea0e3dc9d57e19223d420c98a (patch) | |
| tree | 64e746021d186e84053c14f186f6434c69fcf910 /src/core/hle/service/sm | |
| parent | service: refactor server architecture (diff) | |
| download | yuzu-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.cpp | 29 | ||||
| -rw-r--r-- | src/core/hle/service/sm/sm.h | 5 |
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 | ||
| 37 | void ServiceManager::InvokeControlRequest(Kernel::HLERequestContext& context) { | 41 | void 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 | ||
| 114 | void SM::GetService(Kernel::HLERequestContext& ctx) { | 121 | void 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 | ||
| 126 | void SM::GetServiceTipc(Kernel::HLERequestContext& ctx) { | 138 | void 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_) | |||
| 228 | SM::~SM() = default; | 246 | SM::~SM() = default; |
| 229 | 247 | ||
| 230 | void LoopProcess(Core::System& system) { | 248 | void 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 | |||
| 74 | private: | 78 | private: |
| 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. |