hle: kernel: Migrate KSession, KClientSession, and KServerSession to KAutoObject.
This commit is contained in:
parent
2cb6106523
commit
7444963bbb
|
@ -146,8 +146,6 @@ add_library(core STATIC
|
||||||
hle/kernel/board/nintendo/nx/secure_monitor.h
|
hle/kernel/board/nintendo/nx/secure_monitor.h
|
||||||
hle/kernel/client_port.cpp
|
hle/kernel/client_port.cpp
|
||||||
hle/kernel/client_port.h
|
hle/kernel/client_port.h
|
||||||
hle/kernel/client_session.cpp
|
|
||||||
hle/kernel/client_session.h
|
|
||||||
hle/kernel/code_set.cpp
|
hle/kernel/code_set.cpp
|
||||||
hle/kernel/code_set.h
|
hle/kernel/code_set.h
|
||||||
hle/kernel/svc_results.h
|
hle/kernel/svc_results.h
|
||||||
|
@ -170,6 +168,8 @@ add_library(core STATIC
|
||||||
hle/kernel/k_affinity_mask.h
|
hle/kernel/k_affinity_mask.h
|
||||||
hle/kernel/k_class_token.cpp
|
hle/kernel/k_class_token.cpp
|
||||||
hle/kernel/k_class_token.h
|
hle/kernel/k_class_token.h
|
||||||
|
hle/kernel/k_client_session.cpp
|
||||||
|
hle/kernel/k_client_session.h
|
||||||
hle/kernel/k_condition_variable.cpp
|
hle/kernel/k_condition_variable.cpp
|
||||||
hle/kernel/k_condition_variable.h
|
hle/kernel/k_condition_variable.h
|
||||||
hle/kernel/k_event.cpp
|
hle/kernel/k_event.cpp
|
||||||
|
@ -205,6 +205,10 @@ add_library(core STATIC
|
||||||
hle/kernel/k_scoped_lock.h
|
hle/kernel/k_scoped_lock.h
|
||||||
hle/kernel/k_scoped_resource_reservation.h
|
hle/kernel/k_scoped_resource_reservation.h
|
||||||
hle/kernel/k_scoped_scheduler_lock_and_sleep.h
|
hle/kernel/k_scoped_scheduler_lock_and_sleep.h
|
||||||
|
hle/kernel/k_server_session.cpp
|
||||||
|
hle/kernel/k_server_session.h
|
||||||
|
hle/kernel/k_session.cpp
|
||||||
|
hle/kernel/k_session.h
|
||||||
hle/kernel/k_shared_memory.cpp
|
hle/kernel/k_shared_memory.cpp
|
||||||
hle/kernel/k_shared_memory.h
|
hle/kernel/k_shared_memory.h
|
||||||
hle/kernel/k_slab_heap.h
|
hle/kernel/k_slab_heap.h
|
||||||
|
@ -233,12 +237,8 @@ add_library(core STATIC
|
||||||
hle/kernel/process_capability.h
|
hle/kernel/process_capability.h
|
||||||
hle/kernel/server_port.cpp
|
hle/kernel/server_port.cpp
|
||||||
hle/kernel/server_port.h
|
hle/kernel/server_port.h
|
||||||
hle/kernel/server_session.cpp
|
|
||||||
hle/kernel/server_session.h
|
|
||||||
hle/kernel/service_thread.cpp
|
hle/kernel/service_thread.cpp
|
||||||
hle/kernel/service_thread.h
|
hle/kernel/service_thread.h
|
||||||
hle/kernel/session.cpp
|
|
||||||
hle/kernel/session.h
|
|
||||||
hle/kernel/slab_helpers.h
|
hle/kernel/slab_helpers.h
|
||||||
hle/kernel/svc.cpp
|
hle/kernel/svc.cpp
|
||||||
hle/kernel/svc.h
|
hle/kernel/svc.h
|
||||||
|
|
|
@ -14,11 +14,9 @@
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "core/hle/ipc.h"
|
#include "core/hle/ipc.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/kernel/hle_ipc.h"
|
#include "core/hle/kernel/hle_ipc.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
|
||||||
#include "core/hle/kernel/session.h"
|
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
namespace IPC {
|
namespace IPC {
|
||||||
|
@ -137,9 +135,11 @@ public:
|
||||||
if (context->Session()->IsDomain()) {
|
if (context->Session()->IsDomain()) {
|
||||||
context->AddDomainObject(std::move(iface));
|
context->AddDomainObject(std::move(iface));
|
||||||
} else {
|
} else {
|
||||||
auto [client, server] = Kernel::Session::Create(kernel, iface->GetServiceName());
|
auto* session = Kernel::KSession::Create(kernel);
|
||||||
context->AddMoveObject(client.get());
|
session->Initialize(iface->GetServiceName());
|
||||||
iface->ClientConnected(std::move(client), std::move(server));
|
|
||||||
|
context->AddMoveObject(&session->GetClientSession());
|
||||||
|
iface->ClientConnected(session);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,10 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/kernel/hle_ipc.h"
|
#include "core/hle/kernel/hle_ipc.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
#include "core/hle/kernel/server_port.h"
|
#include "core/hle/kernel/server_port.h"
|
||||||
#include "core/hle/kernel/session.h"
|
|
||||||
#include "core/hle/kernel/svc_results.h"
|
#include "core/hle/kernel/svc_results.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
@ -19,21 +18,22 @@ std::shared_ptr<ServerPort> ClientPort::GetServerPort() const {
|
||||||
return server_port;
|
return server_port;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
|
ResultVal<KClientSession*> ClientPort::Connect() {
|
||||||
if (active_sessions >= max_sessions) {
|
if (active_sessions >= max_sessions) {
|
||||||
return ResultOutOfSessions;
|
return ResultOutOfSessions;
|
||||||
}
|
}
|
||||||
active_sessions++;
|
active_sessions++;
|
||||||
|
|
||||||
auto [client, server] = Kernel::Session::Create(kernel, name);
|
auto* session = Kernel::KSession::Create(kernel);
|
||||||
|
session->Initialize(name + ":ClientPort");
|
||||||
|
|
||||||
if (server_port->HasHLEHandler()) {
|
if (server_port->HasHLEHandler()) {
|
||||||
server_port->GetHLEHandler()->ClientConnected(client, std::move(server));
|
server_port->GetHLEHandler()->ClientConnected(session);
|
||||||
} else {
|
} else {
|
||||||
server_port->AppendPendingSession(std::move(server));
|
server_port->AppendPendingSession(std::addressof(session->GetServerSession()));
|
||||||
}
|
}
|
||||||
|
|
||||||
return MakeResult(std::move(client));
|
return MakeResult(std::addressof(session->GetClientSession()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClientPort::ConnectionClosed() {
|
void ClientPort::ConnectionClosed() {
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class ClientSession;
|
class KClientSession;
|
||||||
class KernelCore;
|
class KernelCore;
|
||||||
class ServerPort;
|
class ServerPort;
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ public:
|
||||||
* waiting on it to awake.
|
* waiting on it to awake.
|
||||||
* @returns ClientSession The client endpoint of the created Session pair, or error code.
|
* @returns ClientSession The client endpoint of the created Session pair, or error code.
|
||||||
*/
|
*/
|
||||||
ResultVal<std::shared_ptr<ClientSession>> Connect();
|
ResultVal<KClientSession*> Connect();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signifies that a previously active connection has been closed,
|
* Signifies that a previously active connection has been closed,
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
// Copyright 2019 yuzu emulator team
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/kernel/hle_ipc.h"
|
|
||||||
#include "core/hle/kernel/k_thread.h"
|
|
||||||
#include "core/hle/kernel/server_session.h"
|
|
||||||
#include "core/hle/kernel/session.h"
|
|
||||||
#include "core/hle/kernel/svc_results.h"
|
|
||||||
#include "core/hle/result.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
ClientSession::ClientSession(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
|
||||||
|
|
||||||
ClientSession::~ClientSession() {
|
|
||||||
// This destructor will be called automatically when the last ClientSession handle is closed by
|
|
||||||
// the emulated application.
|
|
||||||
if (parent->Server()) {
|
|
||||||
parent->Server()->ClientDisconnected();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ClientSession::IsSignaled() const {
|
|
||||||
UNIMPLEMENTED();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultVal<std::shared_ptr<ClientSession>> ClientSession::Create(KernelCore& kernel,
|
|
||||||
std::shared_ptr<Session> parent,
|
|
||||||
std::string name) {
|
|
||||||
std::shared_ptr<ClientSession> client_session{std::make_shared<ClientSession>(kernel)};
|
|
||||||
|
|
||||||
client_session->name = std::move(name);
|
|
||||||
client_session->parent = std::move(parent);
|
|
||||||
|
|
||||||
return MakeResult(std::move(client_session));
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultCode ClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory,
|
|
||||||
Core::Timing::CoreTiming& core_timing) {
|
|
||||||
// Keep ServerSession alive until we're done working with it.
|
|
||||||
if (!parent->Server()) {
|
|
||||||
return ResultSessionClosed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Signal the server session that new data is available
|
|
||||||
return parent->Server()->HandleSyncRequest(std::move(thread), memory, core_timing);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Kernel
|
|
|
@ -56,7 +56,10 @@ ResultVal<Handle> HandleTable::Create(Object* obj) {
|
||||||
case HandleType::Event:
|
case HandleType::Event:
|
||||||
case HandleType::Process:
|
case HandleType::Process:
|
||||||
case HandleType::ReadableEvent:
|
case HandleType::ReadableEvent:
|
||||||
case HandleType::WritableEvent: {
|
case HandleType::WritableEvent:
|
||||||
|
case HandleType::ClientSession:
|
||||||
|
case HandleType::ServerSession:
|
||||||
|
case HandleType::Session: {
|
||||||
Handle handle{};
|
Handle handle{};
|
||||||
Add(&handle, reinterpret_cast<KAutoObject*>(obj), {});
|
Add(&handle, reinterpret_cast<KAutoObject*>(obj), {});
|
||||||
return MakeResult<Handle>(handle);
|
return MakeResult<Handle>(handle);
|
||||||
|
|
|
@ -19,12 +19,12 @@
|
||||||
#include "core/hle/kernel/k_readable_event.h"
|
#include "core/hle/kernel/k_readable_event.h"
|
||||||
#include "core/hle/kernel/k_scheduler.h"
|
#include "core/hle/kernel/k_scheduler.h"
|
||||||
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
|
#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
|
||||||
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
#include "core/hle/kernel/k_writable_event.h"
|
#include "core/hle/kernel/k_writable_event.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
|
||||||
#include "core/hle/kernel/svc_results.h"
|
#include "core/hle/kernel/svc_results.h"
|
||||||
#include "core/hle/kernel/time_manager.h"
|
#include "core/hle/kernel/time_manager.h"
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
@ -35,24 +35,19 @@ SessionRequestHandler::SessionRequestHandler() = default;
|
||||||
|
|
||||||
SessionRequestHandler::~SessionRequestHandler() = default;
|
SessionRequestHandler::~SessionRequestHandler() = default;
|
||||||
|
|
||||||
void SessionRequestHandler::ClientConnected(std::shared_ptr<ClientSession> client_session,
|
void SessionRequestHandler::ClientConnected(KSession* session) {
|
||||||
std::shared_ptr<ServerSession> server_session) {
|
session->GetServerSession().SetHleHandler(shared_from_this());
|
||||||
server_session->SetHleHandler(shared_from_this());
|
sessions.push_back(session);
|
||||||
client_sessions.push_back(std::move(client_session));
|
|
||||||
server_sessions.push_back(std::move(server_session));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SessionRequestHandler::ClientDisconnected(
|
void SessionRequestHandler::ClientDisconnected(KSession* session) {
|
||||||
const std::shared_ptr<ServerSession>& server_session) {
|
session->GetServerSession().SetHleHandler(nullptr);
|
||||||
server_session->SetHleHandler(nullptr);
|
boost::range::remove_erase(sessions, session);
|
||||||
boost::range::remove_erase(server_sessions, server_session);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_,
|
HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_,
|
||||||
std::shared_ptr<ServerSession> server_session_,
|
KServerSession* server_session_, KThread* thread_)
|
||||||
KThread* thread_)
|
: server_session(server_session_), thread(thread_), kernel{kernel_}, memory{memory_} {
|
||||||
: server_session(std::move(server_session_)),
|
|
||||||
thread(thread_), kernel{kernel_}, memory{memory_} {
|
|
||||||
cmd_buf[0] = 0;
|
cmd_buf[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,10 +39,10 @@ class HandleTable;
|
||||||
class HLERequestContext;
|
class HLERequestContext;
|
||||||
class KernelCore;
|
class KernelCore;
|
||||||
class Process;
|
class Process;
|
||||||
class ClientSession;
|
class KServerSession;
|
||||||
class ServerSession;
|
|
||||||
class KThread;
|
class KThread;
|
||||||
class KReadableEvent;
|
class KReadableEvent;
|
||||||
|
class KSession;
|
||||||
class KWritableEvent;
|
class KWritableEvent;
|
||||||
|
|
||||||
enum class ThreadWakeupReason;
|
enum class ThreadWakeupReason;
|
||||||
|
@ -72,22 +72,20 @@ public:
|
||||||
* associated ServerSession alive for the duration of the connection.
|
* associated ServerSession alive for the duration of the connection.
|
||||||
* @param server_session Owning pointer to the ServerSession associated with the connection.
|
* @param server_session Owning pointer to the ServerSession associated with the connection.
|
||||||
*/
|
*/
|
||||||
void ClientConnected(
|
void ClientConnected(KSession* session);
|
||||||
std::shared_ptr<ClientSession> client_session, std::shared_ptr<ServerSession> server_session);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Signals that a client has just disconnected from this HLE handler and releases the
|
* Signals that a client has just disconnected from this HLE handler and releases the
|
||||||
* associated ServerSession.
|
* associated ServerSession.
|
||||||
* @param server_session ServerSession associated with the connection.
|
* @param server_session ServerSession associated with the connection.
|
||||||
*/
|
*/
|
||||||
void ClientDisconnected(const std::shared_ptr<ServerSession>& server_session);
|
void ClientDisconnected(KSession* session);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// List of sessions that are connected to this handler.
|
/// List of sessions that are connected to this handler.
|
||||||
/// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list
|
/// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list
|
||||||
/// for the duration of the connection.
|
/// for the duration of the connection.
|
||||||
std::vector<std::shared_ptr<ClientSession>> client_sessions;
|
std::vector<KSession*> sessions;
|
||||||
std::vector<std::shared_ptr<ServerSession>> server_sessions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -112,7 +110,7 @@ protected:
|
||||||
class HLERequestContext {
|
class HLERequestContext {
|
||||||
public:
|
public:
|
||||||
explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory,
|
explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory,
|
||||||
std::shared_ptr<ServerSession> session, KThread* thread);
|
KServerSession* session, KThread* thread);
|
||||||
~HLERequestContext();
|
~HLERequestContext();
|
||||||
|
|
||||||
/// Returns a pointer to the IPC command buffer for this request.
|
/// Returns a pointer to the IPC command buffer for this request.
|
||||||
|
@ -124,7 +122,7 @@ public:
|
||||||
* Returns the session through which this request was made. This can be used as a map key to
|
* Returns the session through which this request was made. This can be used as a map key to
|
||||||
* access per-client data on services.
|
* access per-client data on services.
|
||||||
*/
|
*/
|
||||||
const std::shared_ptr<Kernel::ServerSession>& Session() const {
|
Kernel::KServerSession* Session() {
|
||||||
return server_session;
|
return server_session;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +286,7 @@ private:
|
||||||
void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming);
|
void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming);
|
||||||
|
|
||||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
||||||
std::shared_ptr<Kernel::ServerSession> server_session;
|
Kernel::KServerSession* server_session{};
|
||||||
KThread* thread;
|
KThread* thread;
|
||||||
|
|
||||||
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
// TODO(yuriks): Check common usage of this and optimize size accordingly
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "core/hle/kernel/k_event.h"
|
#include "core/hle/kernel/k_event.h"
|
||||||
#include "core/hle/kernel/k_memory_layout.h"
|
#include "core/hle/kernel/k_memory_layout.h"
|
||||||
#include "core/hle/kernel/k_memory_manager.h"
|
#include "core/hle/kernel/k_memory_manager.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
#include "core/hle/kernel/k_shared_memory.h"
|
#include "core/hle/kernel/k_shared_memory.h"
|
||||||
#include "core/hle/kernel/k_system_control.h"
|
#include "core/hle/kernel/k_system_control.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
|
@ -27,7 +28,8 @@ namespace Kernel::Init {
|
||||||
HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \
|
HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \
|
||||||
HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \
|
HANDLER(KThread, (SLAB_COUNT(KThread)), ##__VA_ARGS__) \
|
||||||
HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \
|
HANDLER(KEvent, (SLAB_COUNT(KEvent)), ##__VA_ARGS__) \
|
||||||
HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__)
|
HANDLER(KSharedMemory, (SLAB_COUNT(KSharedMemory)), ##__VA_ARGS__) \
|
||||||
|
HANDLER(KSession, (SLAB_COUNT(KSession)), ##__VA_ARGS__)
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
// Copyright 2021 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "core/hle/kernel/hle_ipc.h"
|
||||||
|
#include "core/hle/kernel/k_client_session.h"
|
||||||
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
|
#include "core/hle/kernel/k_thread.h"
|
||||||
|
#include "core/hle/kernel/svc_results.h"
|
||||||
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
KClientSession::KClientSession(KernelCore& kernel) : KAutoObjectWithSlabHeapAndContainer{kernel} {}
|
||||||
|
KClientSession::~KClientSession() = default;
|
||||||
|
|
||||||
|
void KClientSession::Destroy() {
|
||||||
|
parent->OnClientClosed();
|
||||||
|
parent->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void KClientSession::OnServerClosed() {}
|
||||||
|
|
||||||
|
ResultCode KClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory,
|
||||||
|
Core::Timing::CoreTiming& core_timing) {
|
||||||
|
// Signal the server session that new data is available
|
||||||
|
return parent->GetServerSession().HandleSyncRequest(thread, memory, core_timing);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Kernel
|
|
@ -1,4 +1,4 @@
|
||||||
// Copyright 2019 yuzu emulator team
|
// Copyright 2021 yuzu emulator team
|
||||||
// Licensed under GPLv2 or any later version
|
// Licensed under GPLv2 or any later version
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
@ -7,7 +7,9 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "core/hle/kernel/k_auto_object.h"
|
||||||
#include "core/hle/kernel/k_synchronization_object.h"
|
#include "core/hle/kernel/k_synchronization_object.h"
|
||||||
|
#include "core/hle/kernel/slab_helpers.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
|
|
||||||
union ResultCode;
|
union ResultCode;
|
||||||
|
@ -23,15 +25,41 @@ class CoreTiming;
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
class KernelCore;
|
class KernelCore;
|
||||||
class Session;
|
class KSession;
|
||||||
class KThread;
|
class KThread;
|
||||||
|
|
||||||
class ClientSession final : public KSynchronizationObject {
|
class KClientSession final
|
||||||
public:
|
: public KAutoObjectWithSlabHeapAndContainer<KClientSession, KAutoObjectWithList> {
|
||||||
explicit ClientSession(KernelCore& kernel);
|
KERNEL_AUTOOBJECT_TRAITS(KClientSession, KAutoObject);
|
||||||
~ClientSession() override;
|
|
||||||
|
|
||||||
friend class Session;
|
public:
|
||||||
|
explicit KClientSession(KernelCore& kernel);
|
||||||
|
virtual ~KClientSession();
|
||||||
|
|
||||||
|
void Initialize(KSession* parent_, std::string&& name_) {
|
||||||
|
// Set member variables.
|
||||||
|
parent = parent_;
|
||||||
|
name = std::move(name_);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void Destroy() override;
|
||||||
|
static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
|
||||||
|
|
||||||
|
constexpr KSession* GetParent() const {
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
ResultCode SendSyncRequest(KThread* thread, Core::Memory::Memory& memory,
|
||||||
|
Core::Timing::CoreTiming& core_timing);
|
||||||
|
|
||||||
|
void OnServerClosed();
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
|
|
||||||
|
static constexpr HandleType HANDLE_TYPE = HandleType::ClientSession;
|
||||||
|
HandleType GetHandleType() const override {
|
||||||
|
return HANDLE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
std::string GetTypeName() const override {
|
||||||
return "ClientSession";
|
return "ClientSession";
|
||||||
|
@ -41,25 +69,9 @@ public:
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr HandleType HANDLE_TYPE = HandleType::ClientSession;
|
|
||||||
HandleType GetHandleType() const override {
|
|
||||||
return HANDLE_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResultCode SendSyncRequest(KThread* thread, Core::Memory::Memory& memory,
|
|
||||||
Core::Timing::CoreTiming& core_timing);
|
|
||||||
|
|
||||||
bool IsSignaled() const override;
|
|
||||||
|
|
||||||
void Finalize() override {}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ResultVal<std::shared_ptr<ClientSession>> Create(KernelCore& kernel,
|
|
||||||
std::shared_ptr<Session> parent,
|
|
||||||
std::string name = "Unknown");
|
|
||||||
|
|
||||||
/// The parent session, which links to the server endpoint.
|
/// The parent session, which links to the server endpoint.
|
||||||
std::shared_ptr<Session> parent;
|
KSession* parent{};
|
||||||
|
|
||||||
/// Name of the client session (optional)
|
/// Name of the client session (optional)
|
||||||
std::string name;
|
std::string name;
|
|
@ -11,43 +11,38 @@
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/hle_ipc.h"
|
#include "core/hle/kernel/hle_ipc.h"
|
||||||
#include "core/hle/kernel/k_scheduler.h"
|
#include "core/hle/kernel/k_scheduler.h"
|
||||||
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/process.h"
|
#include "core/hle/kernel/process.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
|
||||||
#include "core/hle/kernel/session.h"
|
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
|
||||||
ServerSession::ServerSession(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
KServerSession::KServerSession(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
||||||
|
|
||||||
ServerSession::~ServerSession() {
|
KServerSession::~KServerSession() {
|
||||||
kernel.ReleaseServiceThread(service_thread);
|
kernel.ReleaseServiceThread(service_thread);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel,
|
void KServerSession::Initialize(KSession* parent_, std::string&& name_) {
|
||||||
std::shared_ptr<Session> parent,
|
// Set member variables.
|
||||||
std::string name) {
|
parent = parent_;
|
||||||
std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)};
|
name = std::move(name_);
|
||||||
|
service_thread = kernel.CreateServiceThread(name);
|
||||||
session->name = std::move(name);
|
|
||||||
session->parent = std::move(parent);
|
|
||||||
session->service_thread = kernel.CreateServiceThread(session->name);
|
|
||||||
|
|
||||||
return MakeResult(std::move(session));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ServerSession::IsSignaled() const {
|
void KServerSession::Destroy() {
|
||||||
// Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
|
parent->OnServerClosed();
|
||||||
return !parent->Client();
|
|
||||||
|
parent->Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerSession::ClientDisconnected() {
|
void KServerSession::OnClientClosed() {
|
||||||
// We keep a shared pointer to the hle handler to keep it alive throughout
|
// We keep a shared pointer to the hle handler to keep it alive throughout
|
||||||
// the call to ClientDisconnected, as ClientDisconnected invalidates the
|
// the call to ClientDisconnected, as ClientDisconnected invalidates the
|
||||||
// hle_handler member itself during the course of the function executing.
|
// hle_handler member itself during the course of the function executing.
|
||||||
|
@ -55,19 +50,31 @@ void ServerSession::ClientDisconnected() {
|
||||||
if (handler) {
|
if (handler) {
|
||||||
// Note that after this returns, this server session's hle_handler is
|
// Note that after this returns, this server session's hle_handler is
|
||||||
// invalidated (set to null).
|
// invalidated (set to null).
|
||||||
handler->ClientDisconnected(SharedFrom(this));
|
handler->ClientDisconnected(parent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerSession::AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler) {
|
bool KServerSession::IsSignaled() const {
|
||||||
|
ASSERT(kernel.GlobalSchedulerContext().IsLocked());
|
||||||
|
|
||||||
|
// If the client is closed, we're always signaled.
|
||||||
|
if (parent->IsClientClosed()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, we're signaled if we have a request and aren't handling one.
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KServerSession::AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler) {
|
||||||
domain_request_handlers.push_back(std::move(handler));
|
domain_request_handlers.push_back(std::move(handler));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t ServerSession::NumDomainRequestHandlers() const {
|
std::size_t KServerSession::NumDomainRequestHandlers() const {
|
||||||
return domain_request_handlers.size();
|
return domain_request_handlers.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
|
ResultCode KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
|
||||||
if (!context.HasDomainMessageHeader()) {
|
if (!context.HasDomainMessageHeader()) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -106,21 +113,21 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory) {
|
ResultCode KServerSession::QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory) {
|
||||||
u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))};
|
u32* cmd_buf{reinterpret_cast<u32*>(memory.GetPointer(thread->GetTLSAddress()))};
|
||||||
auto context = std::make_shared<HLERequestContext>(kernel, memory, SharedFrom(this), thread);
|
auto context = std::make_shared<HLERequestContext>(kernel, memory, this, thread);
|
||||||
|
|
||||||
context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
|
context->PopulateFromIncomingCommandBuffer(kernel.CurrentProcess()->GetHandleTable(), cmd_buf);
|
||||||
|
|
||||||
if (auto strong_ptr = service_thread.lock()) {
|
if (auto strong_ptr = service_thread.lock()) {
|
||||||
strong_ptr->QueueSyncRequest(*this, std::move(context));
|
strong_ptr->QueueSyncRequest(*parent, std::move(context));
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ServerSession::CompleteSyncRequest(HLERequestContext& context) {
|
ResultCode KServerSession::CompleteSyncRequest(HLERequestContext& context) {
|
||||||
ResultCode result = RESULT_SUCCESS;
|
ResultCode result = RESULT_SUCCESS;
|
||||||
// If the session has been converted to a domain, handle the domain request
|
// If the session has been converted to a domain, handle the domain request
|
||||||
if (IsDomain() && context.HasDomainMessageHeader()) {
|
if (IsDomain() && context.HasDomainMessageHeader()) {
|
||||||
|
@ -149,8 +156,8 @@ ResultCode ServerSession::CompleteSyncRequest(HLERequestContext& context) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultCode ServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
|
ResultCode KServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
|
||||||
Core::Timing::CoreTiming& core_timing) {
|
Core::Timing::CoreTiming& core_timing) {
|
||||||
return QueueSyncRequest(thread, memory);
|
return QueueSyncRequest(thread, memory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,55 +27,34 @@ namespace Kernel {
|
||||||
|
|
||||||
class HLERequestContext;
|
class HLERequestContext;
|
||||||
class KernelCore;
|
class KernelCore;
|
||||||
class Session;
|
class KSession;
|
||||||
class SessionRequestHandler;
|
class SessionRequestHandler;
|
||||||
class KThread;
|
class KThread;
|
||||||
|
|
||||||
/**
|
class KServerSession final : public KSynchronizationObject {
|
||||||
* Kernel object representing the server endpoint of an IPC session. Sessions are the basic CTR-OS
|
KERNEL_AUTOOBJECT_TRAITS(KServerSession, KSynchronizationObject);
|
||||||
* primitive for communication between different processes, and are used to implement service calls
|
|
||||||
* to the various system services.
|
|
||||||
*
|
|
||||||
* To make a service call, the client must write the command header and parameters to the buffer
|
|
||||||
* located at offset 0x80 of the TLS (Thread-Local Storage) area, then execute a SendSyncRequest
|
|
||||||
* SVC call with its ClientSession handle. The kernel will read the command header, using it to
|
|
||||||
* marshall the parameters to the process at the server endpoint of the session.
|
|
||||||
* After the server replies to the request, the response is marshalled back to the caller's
|
|
||||||
* TLS buffer and control is transferred back to it.
|
|
||||||
*/
|
|
||||||
class ServerSession final : public KSynchronizationObject {
|
|
||||||
friend class ServiceThread;
|
friend class ServiceThread;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ServerSession(KernelCore& kernel);
|
explicit KServerSession(KernelCore& kernel);
|
||||||
~ServerSession() override;
|
virtual ~KServerSession() override;
|
||||||
|
|
||||||
friend class Session;
|
virtual void Destroy() override;
|
||||||
|
|
||||||
static ResultVal<std::shared_ptr<ServerSession>> Create(KernelCore& kernel,
|
void Initialize(KSession* parent_, std::string&& name_);
|
||||||
std::shared_ptr<Session> parent,
|
|
||||||
std::string name = "Unknown");
|
|
||||||
|
|
||||||
std::string GetTypeName() const override {
|
constexpr KSession* GetParent() {
|
||||||
return "ServerSession";
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string GetName() const override {
|
constexpr const KSession* GetParent() const {
|
||||||
return name;
|
return parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr HandleType HANDLE_TYPE = HandleType::ServerSession;
|
virtual bool IsSignaled() const override;
|
||||||
HandleType GetHandleType() const override {
|
|
||||||
return HANDLE_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
Session* GetParent() {
|
void OnClientClosed();
|
||||||
return parent.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
const Session* GetParent() const {
|
|
||||||
return parent.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the HLE handler for the session. This handler will be called to service IPC requests
|
* Sets the HLE handler for the session. This handler will be called to service IPC requests
|
||||||
|
@ -98,9 +77,6 @@ public:
|
||||||
ResultCode HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
|
ResultCode HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
|
||||||
Core::Timing::CoreTiming& core_timing);
|
Core::Timing::CoreTiming& core_timing);
|
||||||
|
|
||||||
/// Called when a client disconnection occurs.
|
|
||||||
void ClientDisconnected();
|
|
||||||
|
|
||||||
/// Adds a new domain request handler to the collection of request handlers within
|
/// Adds a new domain request handler to the collection of request handlers within
|
||||||
/// this ServerSession instance.
|
/// this ServerSession instance.
|
||||||
void AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler);
|
void AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler);
|
||||||
|
@ -124,9 +100,20 @@ public:
|
||||||
convert_to_domain = true;
|
convert_to_domain = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IsSignaled() const override;
|
// DEPRECATED
|
||||||
|
|
||||||
void Finalize() override {}
|
std::string GetTypeName() const override {
|
||||||
|
return "ServerSession";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetName() const override {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr HandleType HANDLE_TYPE = HandleType::ServerSession;
|
||||||
|
HandleType GetHandleType() const override {
|
||||||
|
return HANDLE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// Queues a sync request from the emulated application.
|
/// Queues a sync request from the emulated application.
|
||||||
|
@ -139,9 +126,6 @@ private:
|
||||||
/// object handle.
|
/// object handle.
|
||||||
ResultCode HandleDomainSyncRequest(Kernel::HLERequestContext& context);
|
ResultCode HandleDomainSyncRequest(Kernel::HLERequestContext& context);
|
||||||
|
|
||||||
/// The parent session, which links to the client endpoint.
|
|
||||||
std::shared_ptr<Session> parent;
|
|
||||||
|
|
||||||
/// This session's HLE request handler (applicable when not a domain)
|
/// This session's HLE request handler (applicable when not a domain)
|
||||||
std::shared_ptr<SessionRequestHandler> hle_handler;
|
std::shared_ptr<SessionRequestHandler> hle_handler;
|
||||||
|
|
||||||
|
@ -156,6 +140,9 @@ private:
|
||||||
|
|
||||||
/// Thread to dispatch service requests
|
/// Thread to dispatch service requests
|
||||||
std::weak_ptr<ServiceThread> service_thread;
|
std::weak_ptr<ServiceThread> service_thread;
|
||||||
|
|
||||||
|
/// KSession that owns this KServerSession
|
||||||
|
KSession* parent{};
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
|
@ -0,0 +1,67 @@
|
||||||
|
// Copyright 2019 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#include "common/assert.h"
|
||||||
|
#include "core/hle/kernel/k_client_session.h"
|
||||||
|
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
||||||
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
KSession::KSession(KernelCore& kernel)
|
||||||
|
: KAutoObjectWithSlabHeapAndContainer{kernel}, server{kernel}, client{kernel} {}
|
||||||
|
KSession::~KSession() = default;
|
||||||
|
|
||||||
|
void KSession::Initialize(std::string&& name_) {
|
||||||
|
// Increment reference count.
|
||||||
|
// Because reference count is one on creation, this will result
|
||||||
|
// in a reference count of two. Thus, when both server and client are closed
|
||||||
|
// this object will be destroyed.
|
||||||
|
Open();
|
||||||
|
|
||||||
|
// Create our sub sessions.
|
||||||
|
KAutoObject::Create(std::addressof(server));
|
||||||
|
KAutoObject::Create(std::addressof(client));
|
||||||
|
|
||||||
|
// Initialize our sub sessions.
|
||||||
|
server.Initialize(this, name_ + ":Server");
|
||||||
|
client.Initialize(this, name_ + ":Client");
|
||||||
|
|
||||||
|
// Set state and name.
|
||||||
|
SetState(State::Normal);
|
||||||
|
name = std::move(name_);
|
||||||
|
|
||||||
|
// Set our owner process.
|
||||||
|
process = kernel.CurrentProcess();
|
||||||
|
process->Open();
|
||||||
|
|
||||||
|
// Mark initialized.
|
||||||
|
initialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSession::Finalize() {}
|
||||||
|
|
||||||
|
void KSession::OnServerClosed() {
|
||||||
|
if (GetState() == State::Normal) {
|
||||||
|
SetState(State::ServerClosed);
|
||||||
|
client.OnServerClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSession::OnClientClosed() {
|
||||||
|
if (GetState() == State::Normal) {
|
||||||
|
SetState(State::ClientClosed);
|
||||||
|
server.OnClientClosed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KSession::PostDestroy(uintptr_t arg) {
|
||||||
|
// Release the session count resource the owner process holds.
|
||||||
|
Process* owner = reinterpret_cast<Process*>(arg);
|
||||||
|
owner->GetResourceLimit()->Release(LimitableResource::Sessions, 1);
|
||||||
|
owner->Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Kernel
|
|
@ -0,0 +1,108 @@
|
||||||
|
// Copyright 2021 yuzu emulator team
|
||||||
|
// Licensed under GPLv2 or any later version
|
||||||
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <atomic>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "core/hle/kernel/k_client_session.h"
|
||||||
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
|
#include "core/hle/kernel/slab_helpers.h"
|
||||||
|
|
||||||
|
namespace Kernel {
|
||||||
|
|
||||||
|
class KSession final : public KAutoObjectWithSlabHeapAndContainer<KSession, KAutoObjectWithList> {
|
||||||
|
KERNEL_AUTOOBJECT_TRAITS(KSession, KAutoObject);
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum class State : u8 {
|
||||||
|
Invalid = 0,
|
||||||
|
Normal = 1,
|
||||||
|
ClientClosed = 2,
|
||||||
|
ServerClosed = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit KSession(KernelCore& kernel);
|
||||||
|
virtual ~KSession() override;
|
||||||
|
|
||||||
|
void Initialize(std::string&& name_);
|
||||||
|
|
||||||
|
virtual void Finalize() override;
|
||||||
|
|
||||||
|
virtual bool IsInitialized() const override {
|
||||||
|
return initialized;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual uintptr_t GetPostDestroyArgument() const override {
|
||||||
|
return reinterpret_cast<uintptr_t>(process);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PostDestroy(uintptr_t arg);
|
||||||
|
|
||||||
|
void OnServerClosed();
|
||||||
|
|
||||||
|
void OnClientClosed();
|
||||||
|
|
||||||
|
bool IsServerClosed() const {
|
||||||
|
return this->GetState() != State::Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsClientClosed() const {
|
||||||
|
return this->GetState() != State::Normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
KClientSession& GetClientSession() {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
KServerSession& GetServerSession() {
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KClientSession& GetClientSession() const {
|
||||||
|
return client;
|
||||||
|
}
|
||||||
|
|
||||||
|
const KServerSession& GetServerSession() const {
|
||||||
|
return server;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ClientPort* GetParent() const {
|
||||||
|
return port;
|
||||||
|
}
|
||||||
|
|
||||||
|
// DEPRECATED
|
||||||
|
|
||||||
|
std::string GetName() const override {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
static constexpr HandleType HANDLE_TYPE = HandleType::Session;
|
||||||
|
HandleType GetHandleType() const override {
|
||||||
|
return HANDLE_TYPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void SetState(State state) {
|
||||||
|
atomic_state = static_cast<u8>(state);
|
||||||
|
}
|
||||||
|
|
||||||
|
State GetState() const {
|
||||||
|
return static_cast<State>(atomic_state.load());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
KServerSession server;
|
||||||
|
KClientSession client;
|
||||||
|
std::atomic<std::underlying_type<State>::type> atomic_state{
|
||||||
|
static_cast<std::underlying_type<State>::type>(State::Invalid)};
|
||||||
|
ClientPort* port{};
|
||||||
|
std::string name;
|
||||||
|
Process* process{};
|
||||||
|
bool initialized{};
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Kernel
|
|
@ -33,11 +33,13 @@ class ClientPort;
|
||||||
class GlobalSchedulerContext;
|
class GlobalSchedulerContext;
|
||||||
class HandleTable;
|
class HandleTable;
|
||||||
class KAutoObjectWithListContainer;
|
class KAutoObjectWithListContainer;
|
||||||
|
class KClientSession;
|
||||||
class KEvent;
|
class KEvent;
|
||||||
class KLinkedListNode;
|
class KLinkedListNode;
|
||||||
class KMemoryManager;
|
class KMemoryManager;
|
||||||
class KResourceLimit;
|
class KResourceLimit;
|
||||||
class KScheduler;
|
class KScheduler;
|
||||||
|
class KSession;
|
||||||
class KSharedMemory;
|
class KSharedMemory;
|
||||||
class KThread;
|
class KThread;
|
||||||
class KWritableEvent;
|
class KWritableEvent;
|
||||||
|
@ -272,6 +274,10 @@ public:
|
||||||
return slab_heap_container->linked_list_node;
|
return slab_heap_container->linked_list_node;
|
||||||
} else if constexpr (std::is_same_v<T, KWritableEvent>) {
|
} else if constexpr (std::is_same_v<T, KWritableEvent>) {
|
||||||
return slab_heap_container->writeable_event;
|
return slab_heap_container->writeable_event;
|
||||||
|
} else if constexpr (std::is_same_v<T, KClientSession>) {
|
||||||
|
return slab_heap_container->client_session;
|
||||||
|
} else if constexpr (std::is_same_v<T, KSession>) {
|
||||||
|
return slab_heap_container->session;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -312,6 +318,8 @@ private:
|
||||||
KSlabHeap<KSharedMemory> shared_memory;
|
KSlabHeap<KSharedMemory> shared_memory;
|
||||||
KSlabHeap<KLinkedListNode> linked_list_node;
|
KSlabHeap<KLinkedListNode> linked_list_node;
|
||||||
KSlabHeap<KWritableEvent> writeable_event;
|
KSlabHeap<KWritableEvent> writeable_event;
|
||||||
|
KSlabHeap<KClientSession> client_session;
|
||||||
|
KSlabHeap<KSession> session;
|
||||||
};
|
};
|
||||||
|
|
||||||
std::unique_ptr<SlabHeapContainer> slab_heap_container;
|
std::unique_ptr<SlabHeapContainer> slab_heap_container;
|
||||||
|
|
|
@ -5,10 +5,10 @@
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
#include "core/hle/kernel/object.h"
|
#include "core/hle/kernel/object.h"
|
||||||
#include "core/hle/kernel/server_port.h"
|
#include "core/hle/kernel/server_port.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
|
||||||
#include "core/hle/kernel/svc_results.h"
|
#include "core/hle/kernel/svc_results.h"
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
|
@ -16,17 +16,17 @@ namespace Kernel {
|
||||||
ServerPort::ServerPort(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
ServerPort::ServerPort(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
||||||
ServerPort::~ServerPort() = default;
|
ServerPort::~ServerPort() = default;
|
||||||
|
|
||||||
ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
|
ResultVal<KServerSession*> ServerPort::Accept() {
|
||||||
if (pending_sessions.empty()) {
|
if (pending_sessions.empty()) {
|
||||||
return ResultNotFound;
|
return ResultNotFound;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto session = std::move(pending_sessions.back());
|
auto* session = pending_sessions.back();
|
||||||
pending_sessions.pop_back();
|
pending_sessions.pop_back();
|
||||||
return MakeResult(std::move(session));
|
return MakeResult(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServerPort::AppendPendingSession(std::shared_ptr<ServerSession> pending_session) {
|
void ServerPort::AppendPendingSession(KServerSession* pending_session) {
|
||||||
pending_sessions.push_back(std::move(pending_session));
|
pending_sessions.push_back(std::move(pending_session));
|
||||||
if (pending_sessions.size() == 1) {
|
if (pending_sessions.size() == 1) {
|
||||||
NotifyAvailable();
|
NotifyAvailable();
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace Kernel {
|
||||||
|
|
||||||
class ClientPort;
|
class ClientPort;
|
||||||
class KernelCore;
|
class KernelCore;
|
||||||
class ServerSession;
|
class KServerSession;
|
||||||
class SessionRequestHandler;
|
class SessionRequestHandler;
|
||||||
|
|
||||||
class ServerPort final : public KSynchronizationObject {
|
class ServerPort final : public KSynchronizationObject {
|
||||||
|
@ -55,7 +55,7 @@ public:
|
||||||
* Accepts a pending incoming connection on this port. If there are no pending sessions, will
|
* Accepts a pending incoming connection on this port. If there are no pending sessions, will
|
||||||
* return ERR_NO_PENDING_SESSIONS.
|
* return ERR_NO_PENDING_SESSIONS.
|
||||||
*/
|
*/
|
||||||
ResultVal<std::shared_ptr<ServerSession>> Accept();
|
ResultVal<KServerSession*> Accept();
|
||||||
|
|
||||||
/// Whether or not this server port has an HLE handler available.
|
/// Whether or not this server port has an HLE handler available.
|
||||||
bool HasHLEHandler() const {
|
bool HasHLEHandler() const {
|
||||||
|
@ -77,7 +77,7 @@ public:
|
||||||
|
|
||||||
/// Appends a ServerSession to the collection of ServerSessions
|
/// Appends a ServerSession to the collection of ServerSessions
|
||||||
/// waiting to be accepted by this port.
|
/// waiting to be accepted by this port.
|
||||||
void AppendPendingSession(std::shared_ptr<ServerSession> pending_session);
|
void AppendPendingSession(KServerSession* pending_session);
|
||||||
|
|
||||||
bool IsSignaled() const override;
|
bool IsSignaled() const override;
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// ServerSessions waiting to be accepted by the port
|
/// ServerSessions waiting to be accepted by the port
|
||||||
std::vector<std::shared_ptr<ServerSession>> pending_sessions;
|
std::vector<KServerSession*> pending_sessions;
|
||||||
|
|
||||||
/// This session's HLE request handler template (optional)
|
/// This session's HLE request handler template (optional)
|
||||||
/// ServerSessions created from this port inherit a reference to this handler.
|
/// ServerSessions created from this port inherit a reference to this handler.
|
||||||
|
|
|
@ -13,8 +13,8 @@
|
||||||
#include "common/scope_exit.h"
|
#include "common/scope_exit.h"
|
||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
|
||||||
#include "core/hle/kernel/service_thread.h"
|
#include "core/hle/kernel/service_thread.h"
|
||||||
#include "core/hle/lock.h"
|
#include "core/hle/lock.h"
|
||||||
#include "video_core/renderer_base.h"
|
#include "video_core/renderer_base.h"
|
||||||
|
@ -26,7 +26,7 @@ public:
|
||||||
explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name);
|
explicit Impl(KernelCore& kernel, std::size_t num_threads, const std::string& name);
|
||||||
~Impl();
|
~Impl();
|
||||||
|
|
||||||
void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context);
|
void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
|
@ -69,18 +69,27 @@ ServiceThread::Impl::Impl(KernelCore& kernel, std::size_t num_threads, const std
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void ServiceThread::Impl::QueueSyncRequest(ServerSession& session,
|
void ServiceThread::Impl::QueueSyncRequest(KSession& session,
|
||||||
std::shared_ptr<HLERequestContext>&& context) {
|
std::shared_ptr<HLERequestContext>&& context) {
|
||||||
{
|
{
|
||||||
std::unique_lock lock{queue_mutex};
|
std::unique_lock lock{queue_mutex};
|
||||||
|
|
||||||
// ServerSession owns the service thread, so we cannot caption a strong pointer here in the
|
// Open a reference to the session to ensure it is not closes while the service request
|
||||||
// event that the ServerSession is terminated.
|
// completes asynchronously.
|
||||||
std::weak_ptr<ServerSession> weak_ptr{SharedFrom(&session)};
|
session.Open();
|
||||||
requests.emplace([weak_ptr, context{std::move(context)}]() {
|
|
||||||
if (auto strong_ptr = weak_ptr.lock()) {
|
requests.emplace([session_ptr{&session}, context{std::move(context)}]() {
|
||||||
strong_ptr->CompleteSyncRequest(*context);
|
// Close the reference.
|
||||||
|
SCOPE_EXIT({ session_ptr->Close(); });
|
||||||
|
|
||||||
|
// If the session has been closed, we are done.
|
||||||
|
if (session_ptr->IsServerClosed()) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Complete the service request.
|
||||||
|
KScopedAutoObject server_session{&session_ptr->GetServerSession()};
|
||||||
|
server_session->CompleteSyncRequest(*context);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
condition.notify_one();
|
condition.notify_one();
|
||||||
|
@ -102,7 +111,7 @@ ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const
|
||||||
|
|
||||||
ServiceThread::~ServiceThread() = default;
|
ServiceThread::~ServiceThread() = default;
|
||||||
|
|
||||||
void ServiceThread::QueueSyncRequest(ServerSession& session,
|
void ServiceThread::QueueSyncRequest(KSession& session,
|
||||||
std::shared_ptr<HLERequestContext>&& context) {
|
std::shared_ptr<HLERequestContext>&& context) {
|
||||||
impl->QueueSyncRequest(session, std::move(context));
|
impl->QueueSyncRequest(session, std::move(context));
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,14 +11,14 @@ namespace Kernel {
|
||||||
|
|
||||||
class HLERequestContext;
|
class HLERequestContext;
|
||||||
class KernelCore;
|
class KernelCore;
|
||||||
class ServerSession;
|
class KSession;
|
||||||
|
|
||||||
class ServiceThread final {
|
class ServiceThread final {
|
||||||
public:
|
public:
|
||||||
explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name);
|
explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name);
|
||||||
~ServiceThread();
|
~ServiceThread();
|
||||||
|
|
||||||
void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context);
|
void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Impl;
|
class Impl;
|
||||||
|
|
|
@ -1,41 +0,0 @@
|
||||||
// Copyright 2019 yuzu emulator team
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#include "common/assert.h"
|
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/kernel/k_scoped_resource_reservation.h"
|
|
||||||
#include "core/hle/kernel/server_session.h"
|
|
||||||
#include "core/hle/kernel/session.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
Session::Session(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
|
||||||
Session::~Session() {
|
|
||||||
// Release reserved resource when the Session pair was created.
|
|
||||||
kernel.GetSystemResourceLimit()->Release(LimitableResource::Sessions, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
Session::SessionPair Session::Create(KernelCore& kernel, std::string name) {
|
|
||||||
// Reserve a new session from the resource limit.
|
|
||||||
KScopedResourceReservation session_reservation(kernel.GetSystemResourceLimit(),
|
|
||||||
LimitableResource::Sessions);
|
|
||||||
ASSERT(session_reservation.Succeeded());
|
|
||||||
auto session{std::make_shared<Session>(kernel)};
|
|
||||||
auto client_session{Kernel::ClientSession::Create(kernel, session, name + "_Client").Unwrap()};
|
|
||||||
auto server_session{Kernel::ServerSession::Create(kernel, session, name + "_Server").Unwrap()};
|
|
||||||
|
|
||||||
session->name = std::move(name);
|
|
||||||
session->client = client_session;
|
|
||||||
session->server = server_session;
|
|
||||||
|
|
||||||
session_reservation.Commit();
|
|
||||||
return std::make_pair(std::move(client_session), std::move(server_session));
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Session::IsSignaled() const {
|
|
||||||
UNIMPLEMENTED();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace Kernel
|
|
|
@ -1,64 +0,0 @@
|
||||||
// Copyright 2019 yuzu emulator team
|
|
||||||
// Licensed under GPLv2 or any later version
|
|
||||||
// Refer to the license.txt file included.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
#include "core/hle/kernel/k_synchronization_object.h"
|
|
||||||
|
|
||||||
namespace Kernel {
|
|
||||||
|
|
||||||
class ClientSession;
|
|
||||||
class ServerSession;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parent structure to link the client and server endpoints of a session with their associated
|
|
||||||
* client port.
|
|
||||||
*/
|
|
||||||
class Session final : public KSynchronizationObject {
|
|
||||||
public:
|
|
||||||
explicit Session(KernelCore& kernel);
|
|
||||||
~Session() override;
|
|
||||||
|
|
||||||
using SessionPair = std::pair<std::shared_ptr<ClientSession>, std::shared_ptr<ServerSession>>;
|
|
||||||
|
|
||||||
static SessionPair Create(KernelCore& kernel, std::string name = "Unknown");
|
|
||||||
|
|
||||||
std::string GetName() const override {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static constexpr HandleType HANDLE_TYPE = HandleType::Session;
|
|
||||||
HandleType GetHandleType() const override {
|
|
||||||
return HANDLE_TYPE;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool IsSignaled() const override;
|
|
||||||
|
|
||||||
void Finalize() override {}
|
|
||||||
|
|
||||||
std::shared_ptr<ClientSession> Client() {
|
|
||||||
if (auto result{client.lock()}) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
std::shared_ptr<ServerSession> Server() {
|
|
||||||
if (auto result{server.lock()}) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::string name;
|
|
||||||
std::weak_ptr<ClientSession> client;
|
|
||||||
std::weak_ptr<ServerSession> server;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace Kernel
|
|
|
@ -22,9 +22,9 @@
|
||||||
#include "core/core_timing_util.h"
|
#include "core/core_timing_util.h"
|
||||||
#include "core/cpu_manager.h"
|
#include "core/cpu_manager.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/kernel/handle_table.h"
|
#include "core/hle/kernel/handle_table.h"
|
||||||
#include "core/hle/kernel/k_address_arbiter.h"
|
#include "core/hle/kernel/k_address_arbiter.h"
|
||||||
|
#include "core/hle/kernel/k_client_session.h"
|
||||||
#include "core/hle/kernel/k_condition_variable.h"
|
#include "core/hle/kernel/k_condition_variable.h"
|
||||||
#include "core/hle/kernel/k_event.h"
|
#include "core/hle/kernel/k_event.h"
|
||||||
#include "core/hle/kernel/k_memory_block.h"
|
#include "core/hle/kernel/k_memory_block.h"
|
||||||
|
@ -323,12 +323,12 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle,
|
||||||
|
|
||||||
auto client_port = it->second;
|
auto client_port = it->second;
|
||||||
|
|
||||||
std::shared_ptr<ClientSession> client_session;
|
KClientSession* client_session{};
|
||||||
CASCADE_RESULT(client_session, client_port->Connect());
|
CASCADE_RESULT(client_session, client_port->Connect());
|
||||||
|
|
||||||
// Return the client session
|
// Return the client session
|
||||||
auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
||||||
CASCADE_RESULT(*out_handle, handle_table.Create(client_session.get()));
|
CASCADE_RESULT(*out_handle, handle_table.Create(client_session));
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,16 +340,14 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle,
|
||||||
|
|
||||||
/// Makes a blocking IPC call to an OS service.
|
/// Makes a blocking IPC call to an OS service.
|
||||||
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
static ResultCode SendSyncRequest(Core::System& system, Handle handle) {
|
||||||
auto& kernel = system.Kernel();
|
|
||||||
const auto& handle_table = kernel.CurrentProcess()->GetHandleTable();
|
|
||||||
auto session = handle_table.Get<ClientSession>(handle);
|
|
||||||
if (!session) {
|
|
||||||
LOG_ERROR(Kernel_SVC, "called with invalid handle=0x{:08X}", handle);
|
|
||||||
return ResultInvalidHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
|
LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
|
||||||
|
|
||||||
|
auto& kernel = system.Kernel();
|
||||||
|
|
||||||
|
KScopedAutoObject session =
|
||||||
|
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
|
||||||
|
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||||
|
|
||||||
auto thread = kernel.CurrentScheduler()->GetCurrentThread();
|
auto thread = kernel.CurrentScheduler()->GetCurrentThread();
|
||||||
{
|
{
|
||||||
KScopedSchedulerLock lock(kernel);
|
KScopedSchedulerLock lock(kernel);
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "core/frontend/applets/web_browser.h"
|
#include "core/frontend/applets/web_browser.h"
|
||||||
#include "core/hle/kernel/k_readable_event.h"
|
#include "core/hle/kernel/k_readable_event.h"
|
||||||
#include "core/hle/kernel/k_writable_event.h"
|
#include "core/hle/kernel/k_writable_event.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
|
||||||
#include "core/hle/service/am/am.h"
|
#include "core/hle/service/am/am.h"
|
||||||
#include "core/hle/service/am/applet_ae.h"
|
#include "core/hle/service/am/applet_ae.h"
|
||||||
#include "core/hle/service/am/applet_oe.h"
|
#include "core/hle/service/am/applet_oe.h"
|
||||||
|
|
|
@ -14,7 +14,6 @@
|
||||||
#include "core/hardware_properties.h"
|
#include "core/hardware_properties.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/kernel/k_readable_event.h"
|
#include "core/hle/kernel/k_readable_event.h"
|
||||||
#include "core/hle/kernel/k_shared_memory.h"
|
#include "core/hle/kernel/k_shared_memory.h"
|
||||||
#include "core/hle/kernel/k_writable_event.h"
|
#include "core/hle/kernel/k_writable_event.h"
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/service/mm/mm_u.h"
|
#include "core/hle/service/mm/mm_u.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,8 @@ class System;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class ClientPort;
|
|
||||||
class ServerPort;
|
|
||||||
class ServerSession;
|
|
||||||
class HLERequestContext;
|
class HLERequestContext;
|
||||||
} // namespace Kernel
|
}
|
||||||
|
|
||||||
namespace Service {
|
namespace Service {
|
||||||
|
|
||||||
|
|
|
@ -5,9 +5,9 @@
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/k_client_session.h"
|
||||||
#include "core/hle/kernel/server_session.h"
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
#include "core/hle/kernel/session.h"
|
#include "core/hle/kernel/k_session.h"
|
||||||
#include "core/hle/service/sm/controller.h"
|
#include "core/hle/service/sm/controller.h"
|
||||||
|
|
||||||
namespace Service::SM {
|
namespace Service::SM {
|
||||||
|
@ -30,7 +30,7 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushMoveObjects(ctx.Session()->GetParent()->Client().get());
|
rb.PushMoveObjects(ctx.Session()->GetParent()->GetClientSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
|
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
|
@ -7,7 +7,9 @@
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
#include "core/hle/kernel/k_client_session.h"
|
||||||
|
#include "core/hle/kernel/k_server_session.h"
|
||||||
|
#include "core/hle/kernel/k_session.h"
|
||||||
#include "core/hle/kernel/server_port.h"
|
#include "core/hle/kernel/server_port.h"
|
||||||
#include "core/hle/result.h"
|
#include "core/hle/result.h"
|
||||||
#include "core/hle/service/sm/controller.h"
|
#include "core/hle/service/sm/controller.h"
|
||||||
|
@ -89,13 +91,6 @@ ResultVal<std::shared_ptr<Kernel::ClientPort>> ServiceManager::GetServicePort(
|
||||||
return MakeResult(it->second);
|
return MakeResult(it->second);
|
||||||
}
|
}
|
||||||
|
|
||||||
ResultVal<std::shared_ptr<Kernel::ClientSession>> ServiceManager::ConnectToService(
|
|
||||||
const std::string& name) {
|
|
||||||
|
|
||||||
CASCADE_RESULT(auto client_port, GetServicePort(name));
|
|
||||||
return client_port->Connect();
|
|
||||||
}
|
|
||||||
|
|
||||||
SM::~SM() = default;
|
SM::~SM() = default;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -130,19 +125,20 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto [client, server] = Kernel::Session::Create(kernel, name);
|
auto* session = Kernel::KSession::Create(kernel);
|
||||||
|
session->Initialize(std::move(name));
|
||||||
|
|
||||||
const auto& server_port = client_port.Unwrap()->GetServerPort();
|
const auto& server_port = client_port.Unwrap()->GetServerPort();
|
||||||
if (server_port->GetHLEHandler()) {
|
if (server_port->GetHLEHandler()) {
|
||||||
server_port->GetHLEHandler()->ClientConnected(client, server);
|
server_port->GetHLEHandler()->ClientConnected(session);
|
||||||
} else {
|
} else {
|
||||||
server_port->AppendPendingSession(server);
|
server_port->AppendPendingSession(&session->GetServerSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG(Service_SM, "called service={} -> session={}", name, client->GetObjectId());
|
LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetObjectId());
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
||||||
rb.Push(RESULT_SUCCESS);
|
rb.Push(RESULT_SUCCESS);
|
||||||
rb.PushMoveObjects(client.get());
|
rb.PushMoveObjects(session->GetClientSession());
|
||||||
}
|
}
|
||||||
|
|
||||||
void SM::RegisterService(Kernel::HLERequestContext& ctx) {
|
void SM::RegisterService(Kernel::HLERequestContext& ctx) {
|
||||||
|
|
|
@ -22,7 +22,7 @@ class System;
|
||||||
|
|
||||||
namespace Kernel {
|
namespace Kernel {
|
||||||
class ClientPort;
|
class ClientPort;
|
||||||
class ClientSession;
|
class KClientSession;
|
||||||
class KernelCore;
|
class KernelCore;
|
||||||
class ServerPort;
|
class ServerPort;
|
||||||
class SessionRequestHandler;
|
class SessionRequestHandler;
|
||||||
|
@ -59,7 +59,6 @@ public:
|
||||||
u32 max_sessions);
|
u32 max_sessions);
|
||||||
ResultCode UnregisterService(const std::string& name);
|
ResultCode UnregisterService(const std::string& name);
|
||||||
ResultVal<std::shared_ptr<Kernel::ClientPort>> GetServicePort(const std::string& name);
|
ResultVal<std::shared_ptr<Kernel::ClientPort>> GetServicePort(const std::string& name);
|
||||||
ResultVal<std::shared_ptr<Kernel::ClientSession>> ConnectToService(const std::string& name);
|
|
||||||
|
|
||||||
template <Common::DerivedFrom<Kernel::SessionRequestHandler> T>
|
template <Common::DerivedFrom<Kernel::SessionRequestHandler> T>
|
||||||
std::shared_ptr<T> GetService(const std::string& service_name) const {
|
std::shared_ptr<T> GetService(const std::string& service_name) const {
|
||||||
|
@ -81,7 +80,7 @@ private:
|
||||||
std::weak_ptr<SM> sm_interface;
|
std::weak_ptr<SM> sm_interface;
|
||||||
std::unique_ptr<Controller> controller_interface;
|
std::unique_ptr<Controller> controller_interface;
|
||||||
|
|
||||||
/// Map of registered services, retrieved using GetServicePort or ConnectToService.
|
/// Map of registered services, retrieved using GetServicePort.
|
||||||
std::unordered_map<std::string, std::shared_ptr<Kernel::ClientPort>> registered_services;
|
std::unordered_map<std::string, std::shared_ptr<Kernel::ClientPort>> registered_services;
|
||||||
|
|
||||||
/// Kernel context
|
/// Kernel context
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
#include "core/hardware_properties.h"
|
#include "core/hardware_properties.h"
|
||||||
#include "core/hle/ipc_helpers.h"
|
#include "core/hle/ipc_helpers.h"
|
||||||
#include "core/hle/kernel/client_port.h"
|
#include "core/hle/kernel/client_port.h"
|
||||||
#include "core/hle/kernel/client_session.h"
|
|
||||||
#include "core/hle/kernel/k_scheduler.h"
|
#include "core/hle/kernel/k_scheduler.h"
|
||||||
#include "core/hle/kernel/kernel.h"
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/service/time/interface.h"
|
#include "core/hle/service/time/interface.h"
|
||||||
|
|
Loading…
Reference in New Issue