diff options
Diffstat (limited to '')
-rw-r--r-- | src/core/hle/service/sm/controller.cpp | 37 | ||||
-rw-r--r-- | src/core/hle/service/sm/sm.cpp | 32 |
2 files changed, 22 insertions, 47 deletions
diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index 5fa5e0512..8b9418e0f 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -28,42 +28,25 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { } void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { - // TODO(bunnei): This is just creating a new handle to the same Session. I assume this is wrong - // and that we probably want to actually make an entirely new Session, but we still need to - // verify this on hardware. - LOG_DEBUG(Service, "called"); - auto& kernel = system.Kernel(); - auto* session = ctx.Session()->GetParent(); - auto* port = session->GetParent()->GetParent(); + auto& parent_session = *ctx.Session()->GetParent(); + auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort(); + auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager(); - // Reserve a new session from the process resource limit. - Kernel::KScopedResourceReservation session_reservation( - kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions); - if (!session_reservation.Succeeded()) { + // Create a session. + Kernel::KClientSession* session{}; + const ResultCode result = parent_port.CreateSession(std::addressof(session), session_manager); + if (result.IsError()) { + LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(Kernel::ResultLimitReached); + rb.Push(result); } - // Create a new session. - auto* clone = Kernel::KSession::Create(kernel); - clone->Initialize(&port->GetClientPort(), session->GetName()); - - // Commit the session reservation. - session_reservation.Commit(); - - // Enqueue the session with the named port. - port->EnqueueSession(&clone->GetServerSession()); - - // Set the session request manager. - clone->GetServerSession().SetSessionRequestManager( - session->GetServerSession().GetSessionRequestManager()); - // We succeeded. IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(ResultSuccess); - rb.PushMoveObjects(clone->GetClientSession()); + rb.PushMoveObjects(session); } void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index d8b20a3f2..c7828c3bd 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -46,7 +46,7 @@ Kernel::KClientPort& ServiceManager::InterfaceFactory(ServiceManager& self, Core self.sm_interface = sm; self.controller_interface = std::make_unique<Controller>(system); - return sm->CreatePort(system.Kernel()); + return sm->CreatePort(); } ResultVal<Kernel::KServerPort*> ServiceManager::RegisterService(std::string name, @@ -151,31 +151,23 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& std::string name(PopServiceName(rp)); // Find the named port. - auto result = service_manager.GetServicePort(name); - if (result.Failed()) { - LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.Code().raw); - return result.Code(); + auto port_result = service_manager.GetServicePort(name); + if (port_result.Failed()) { + LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, port_result.Code().raw); + return port_result.Code(); } - auto* port = result.Unwrap(); - - // Reserve a new session from the process resource limit. - Kernel::KScopedResourceReservation session_reservation( - kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions); - R_UNLESS(session_reservation.Succeeded(), Kernel::ResultLimitReached); + auto& port = port_result.Unwrap()->GetClientPort(); // Create a new session. - auto* session = Kernel::KSession::Create(kernel); - session->Initialize(&port->GetClientPort(), std::move(name)); - - // Commit the session reservation. - session_reservation.Commit(); - - // Enqueue the session with the named port. - port->EnqueueSession(&session->GetServerSession()); + Kernel::KClientSession* session{}; + if (const auto result = port.CreateSession(std::addressof(session)); result.IsError()) { + LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); + return result; + } LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); - return MakeResult(&session->GetClientSession()); + return MakeResult(session); } void SM::RegisterService(Kernel::HLERequestContext& ctx) { |