diff options
| author | 2021-05-15 22:30:21 -0700 | |
|---|---|---|
| committer | 2021-05-15 22:30:21 -0700 | |
| commit | 5a2b15bf75318987d773a2bc69bd6224a28b7939 (patch) | |
| tree | f213f5b011410022e8e98f7c3905d16d575ed413 /src/core/hle/service/service.cpp | |
| parent | Merge pull request #6289 from ameerj/oob-blit (diff) | |
| parent | common: tree: Avoid a nullptr dereference. (diff) | |
| download | yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.tar.gz yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.tar.xz yuzu-5a2b15bf75318987d773a2bc69bd6224a28b7939.zip | |
Merge pull request #6299 from bunnei/ipc-improvements
Various improvements to IPC and session management
Diffstat (limited to 'src/core/hle/service/service.cpp')
| -rw-r--r-- | src/core/hle/service/service.cpp | 55 |
1 files changed, 44 insertions, 11 deletions
diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 00e683c2f..2c9b2ce6d 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp | |||
| @@ -111,7 +111,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) | |||
| 111 | port_installed = true; | 111 | port_installed = true; |
| 112 | } | 112 | } |
| 113 | 113 | ||
| 114 | void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) { | 114 | Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel) { |
| 115 | const auto guard = LockService(); | 115 | const auto guard = LockService(); |
| 116 | 116 | ||
| 117 | ASSERT(!port_installed); | 117 | ASSERT(!port_installed); |
| @@ -119,9 +119,10 @@ void ServiceFrameworkBase::InstallAsNamedPort(Kernel::KernelCore& kernel) { | |||
| 119 | auto* port = Kernel::KPort::Create(kernel); | 119 | auto* port = Kernel::KPort::Create(kernel); |
| 120 | port->Initialize(max_sessions, false, service_name); | 120 | port->Initialize(max_sessions, false, service_name); |
| 121 | port->GetServerPort().SetHleHandler(shared_from_this()); | 121 | port->GetServerPort().SetHleHandler(shared_from_this()); |
| 122 | kernel.AddNamedPort(service_name, &port->GetClientPort()); | ||
| 123 | 122 | ||
| 124 | port_installed = true; | 123 | port_installed = true; |
| 124 | |||
| 125 | return port->GetClientPort(); | ||
| 125 | } | 126 | } |
| 126 | 127 | ||
| 127 | void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { | 128 | void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* functions, std::size_t n) { |
| @@ -132,6 +133,16 @@ void ServiceFrameworkBase::RegisterHandlersBase(const FunctionInfoBase* function | |||
| 132 | } | 133 | } |
| 133 | } | 134 | } |
| 134 | 135 | ||
| 136 | void ServiceFrameworkBase::RegisterHandlersBaseTipc(const FunctionInfoBase* functions, | ||
| 137 | std::size_t n) { | ||
| 138 | handlers_tipc.reserve(handlers_tipc.size() + n); | ||
| 139 | for (std::size_t i = 0; i < n; ++i) { | ||
| 140 | // Usually this array is sorted by id already, so hint to insert at the end | ||
| 141 | handlers_tipc.emplace_hint(handlers_tipc.cend(), functions[i].expected_header, | ||
| 142 | functions[i]); | ||
| 143 | } | ||
| 144 | } | ||
| 145 | |||
| 135 | void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, | 146 | void ServiceFrameworkBase::ReportUnimplementedFunction(Kernel::HLERequestContext& ctx, |
| 136 | const FunctionInfoBase* info) { | 147 | const FunctionInfoBase* info) { |
| 137 | auto cmd_buf = ctx.CommandBuffer(); | 148 | auto cmd_buf = ctx.CommandBuffer(); |
| @@ -166,33 +177,55 @@ void ServiceFrameworkBase::InvokeRequest(Kernel::HLERequestContext& ctx) { | |||
| 166 | handler_invoker(this, info->handler_callback, ctx); | 177 | handler_invoker(this, info->handler_callback, ctx); |
| 167 | } | 178 | } |
| 168 | 179 | ||
| 169 | ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::HLERequestContext& context) { | 180 | void ServiceFrameworkBase::InvokeRequestTipc(Kernel::HLERequestContext& ctx) { |
| 181 | boost::container::flat_map<u32, FunctionInfoBase>::iterator itr; | ||
| 182 | |||
| 183 | itr = handlers_tipc.find(ctx.GetCommand()); | ||
| 184 | |||
| 185 | const FunctionInfoBase* info = itr == handlers_tipc.end() ? nullptr : &itr->second; | ||
| 186 | if (info == nullptr || info->handler_callback == nullptr) { | ||
| 187 | return ReportUnimplementedFunction(ctx, info); | ||
| 188 | } | ||
| 189 | |||
| 190 | LOG_TRACE(Service, "{}", MakeFunctionString(info->name, GetServiceName(), ctx.CommandBuffer())); | ||
| 191 | handler_invoker(this, info->handler_callback, ctx); | ||
| 192 | } | ||
| 193 | |||
| 194 | ResultCode ServiceFrameworkBase::HandleSyncRequest(Kernel::KServerSession& session, | ||
| 195 | Kernel::HLERequestContext& ctx) { | ||
| 170 | const auto guard = LockService(); | 196 | const auto guard = LockService(); |
| 171 | 197 | ||
| 172 | switch (context.GetCommandType()) { | 198 | switch (ctx.GetCommandType()) { |
| 173 | case IPC::CommandType::Close: { | 199 | case IPC::CommandType::Close: |
| 174 | IPC::ResponseBuilder rb{context, 2}; | 200 | case IPC::CommandType::TIPC_Close: { |
| 201 | session.Close(); | ||
| 202 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 175 | rb.Push(RESULT_SUCCESS); | 203 | rb.Push(RESULT_SUCCESS); |
| 176 | return IPC::ERR_REMOTE_PROCESS_DEAD; | 204 | return IPC::ERR_REMOTE_PROCESS_DEAD; |
| 177 | } | 205 | } |
| 178 | case IPC::CommandType::ControlWithContext: | 206 | case IPC::CommandType::ControlWithContext: |
| 179 | case IPC::CommandType::Control: { | 207 | case IPC::CommandType::Control: { |
| 180 | system.ServiceManager().InvokeControlRequest(context); | 208 | system.ServiceManager().InvokeControlRequest(ctx); |
| 181 | break; | 209 | break; |
| 182 | } | 210 | } |
| 183 | case IPC::CommandType::RequestWithContext: | 211 | case IPC::CommandType::RequestWithContext: |
| 184 | case IPC::CommandType::Request: { | 212 | case IPC::CommandType::Request: { |
| 185 | InvokeRequest(context); | 213 | InvokeRequest(ctx); |
| 186 | break; | 214 | break; |
| 187 | } | 215 | } |
| 188 | default: | 216 | default: |
| 189 | UNIMPLEMENTED_MSG("command_type={}", context.GetCommandType()); | 217 | if (ctx.IsTipc()) { |
| 218 | InvokeRequestTipc(ctx); | ||
| 219 | break; | ||
| 220 | } | ||
| 221 | |||
| 222 | UNIMPLEMENTED_MSG("command_type={}", ctx.GetCommandType()); | ||
| 190 | } | 223 | } |
| 191 | 224 | ||
| 192 | // If emulation was shutdown, we are closing service threads, do not write the response back to | 225 | // If emulation was shutdown, we are closing service threads, do not write the response back to |
| 193 | // memory that may be shutting down as well. | 226 | // memory that may be shutting down as well. |
| 194 | if (system.IsPoweredOn()) { | 227 | if (system.IsPoweredOn()) { |
| 195 | context.WriteToOutgoingCommandBuffer(context.GetThread()); | 228 | ctx.WriteToOutgoingCommandBuffer(ctx.GetThread()); |
| 196 | } | 229 | } |
| 197 | 230 | ||
| 198 | return RESULT_SUCCESS; | 231 | return RESULT_SUCCESS; |
| @@ -207,7 +240,7 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system | |||
| 207 | 240 | ||
| 208 | system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); | 241 | system.GetFileSystemController().CreateFactories(*system.GetFilesystem(), false); |
| 209 | 242 | ||
| 210 | SM::ServiceManager::InstallInterfaces(sm, system); | 243 | system.Kernel().RegisterNamedService("sm:", SM::ServiceManager::InterfaceFactory); |
| 211 | 244 | ||
| 212 | Account::InstallInterfaces(system); | 245 | Account::InstallInterfaces(system); |
| 213 | AM::InstallInterfaces(*sm, *nv_flinger, system); | 246 | AM::InstallInterfaces(*sm, *nv_flinger, system); |