kernel: more complete fix for KPort reference counting
This commit is contained in:
parent
d8ff939edc
commit
4e9adae5da
|
@ -149,9 +149,10 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
|
||||||
return port_result.Code();
|
return port_result.Code();
|
||||||
}
|
}
|
||||||
auto& port = port_result.Unwrap();
|
auto& port = port_result.Unwrap();
|
||||||
SCOPE_EXIT({ port->GetClientPort().Close(); });
|
SCOPE_EXIT({
|
||||||
|
port->GetClientPort().Close();
|
||||||
kernel.RegisterServerObject(&port->GetServerPort());
|
port->GetServerPort().Close();
|
||||||
|
});
|
||||||
|
|
||||||
// Create a new session.
|
// Create a new session.
|
||||||
Kernel::KClientSession* session{};
|
Kernel::KClientSession* session{};
|
||||||
|
|
|
@ -28,23 +28,36 @@ void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
|
||||||
void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
|
void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service, "called");
|
LOG_DEBUG(Service, "called");
|
||||||
|
|
||||||
|
auto& process = *ctx.GetThread().GetOwnerProcess();
|
||||||
auto& parent_session = *ctx.Session()->GetParent();
|
auto& parent_session = *ctx.Session()->GetParent();
|
||||||
auto& parent_port = parent_session.GetParent()->GetParent()->GetClientPort();
|
|
||||||
auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager();
|
auto& session_manager = parent_session.GetServerSession().GetSessionRequestManager();
|
||||||
|
auto& session_handler = session_manager->SessionHandler();
|
||||||
|
|
||||||
// Create a session.
|
// FIXME: this is duplicated from the SVC, it should just call it instead
|
||||||
Kernel::KClientSession* session{};
|
// once this is a proper process
|
||||||
const Result result = parent_port.CreateSession(std::addressof(session), session_manager);
|
|
||||||
if (result.IsError()) {
|
// Reserve a new session from the process resource limit.
|
||||||
LOG_CRITICAL(Service, "CreateSession failed with error 0x{:08X}", result.raw);
|
Kernel::KScopedResourceReservation session_reservation(&process,
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
Kernel::LimitableResource::Sessions);
|
||||||
rb.Push(result);
|
ASSERT(session_reservation.Succeeded());
|
||||||
}
|
|
||||||
|
// Create the session.
|
||||||
|
Kernel::KSession* session = Kernel::KSession::Create(system.Kernel());
|
||||||
|
ASSERT(session != nullptr);
|
||||||
|
|
||||||
|
// Initialize the session.
|
||||||
|
session->Initialize(nullptr, parent_session.GetName(), session_manager);
|
||||||
|
|
||||||
|
// Commit the session reservation.
|
||||||
|
session_reservation.Commit();
|
||||||
|
|
||||||
|
// Register the session.
|
||||||
|
session_handler.ClientConnected(&session->GetServerSession());
|
||||||
|
|
||||||
// We succeeded.
|
// We succeeded.
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.PushMoveObjects(session);
|
rb.PushMoveObjects(session->GetClientSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
|
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
Reference in New Issue