hle: kernel: Migrate KSession, KClientSession, and KServerSession to KAutoObject.

master
bunnei 2021-04-13 17:48:37 +07:00
parent 2cb6106523
commit 7444963bbb
31 changed files with 416 additions and 360 deletions

@ -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,7 +156,7 @@ 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"