mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2025-07-22 23:15:45 +00:00
hle: kernel: Implement CloneCurrentObject and improve session management.
This commit is contained in:
parent
c40e7593f5
commit
7361eac10f
13 changed files with 184 additions and 99 deletions
|
@ -4,8 +4,13 @@
|
|||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/k_client_port.h"
|
||||
#include "core/hle/kernel/k_client_session.h"
|
||||
#include "core/hle/kernel/k_port.h"
|
||||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||
#include "core/hle/kernel/k_server_port.h"
|
||||
#include "core/hle/kernel/k_server_session.h"
|
||||
#include "core/hle/kernel/k_session.h"
|
||||
#include "core/hle/service/sm/controller.h"
|
||||
|
@ -13,7 +18,7 @@
|
|||
namespace Service::SM {
|
||||
|
||||
void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) {
|
||||
ASSERT_MSG(ctx.Session()->IsSession(), "Session is already a domain");
|
||||
ASSERT_MSG(!ctx.Session()->IsDomain(), "Session is already a domain");
|
||||
LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId());
|
||||
ctx.Session()->ConvertToDomain();
|
||||
|
||||
|
@ -29,16 +34,36 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
|
|||
|
||||
LOG_DEBUG(Service, "called");
|
||||
|
||||
auto session = ctx.Session()->GetParent();
|
||||
auto& kernel = system.Kernel();
|
||||
auto* session = ctx.Session()->GetParent();
|
||||
auto* port = session->GetParent()->GetParent();
|
||||
|
||||
// Open a reference to the session to simulate a new one being created.
|
||||
session->Open();
|
||||
session->GetClientSession().Open();
|
||||
session->GetServerSession().Open();
|
||||
// Reserve a new session from the process resource limit.
|
||||
Kernel::KScopedResourceReservation session_reservation(
|
||||
kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions);
|
||||
if (!session_reservation.Succeeded()) {
|
||||
IPC::ResponseBuilder rb{ctx, 2};
|
||||
rb.Push(Kernel::ResultLimitReached);
|
||||
}
|
||||
|
||||
// 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(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(session->GetClientSession());
|
||||
rb.PushMoveObjects(clone->GetClientSession());
|
||||
}
|
||||
|
||||
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue