mirror of
https://github.com/yuzu-mirror/yuzu
synced 2024-12-20 05:33:09 +00:00
hle: kernel: Migrate KSession, KClientSession, and KServerSession to KAutoObject.
This commit is contained in:
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/client_port.cpp
|
||||
hle/kernel/client_port.h
|
||||
hle/kernel/client_session.cpp
|
||||
hle/kernel/client_session.h
|
||||
hle/kernel/code_set.cpp
|
||||
hle/kernel/code_set.h
|
||||
hle/kernel/svc_results.h
|
||||
|
@ -170,6 +168,8 @@ add_library(core STATIC
|
|||
hle/kernel/k_affinity_mask.h
|
||||
hle/kernel/k_class_token.cpp
|
||||
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.h
|
||||
hle/kernel/k_event.cpp
|
||||
|
@ -205,6 +205,10 @@ add_library(core STATIC
|
|||
hle/kernel/k_scoped_lock.h
|
||||
hle/kernel/k_scoped_resource_reservation.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.h
|
||||
hle/kernel/k_slab_heap.h
|
||||
|
@ -233,12 +237,8 @@ add_library(core STATIC
|
|||
hle/kernel/process_capability.h
|
||||
hle/kernel/server_port.cpp
|
||||
hle/kernel/server_port.h
|
||||
hle/kernel/server_session.cpp
|
||||
hle/kernel/server_session.h
|
||||
hle/kernel/service_thread.cpp
|
||||
hle/kernel/service_thread.h
|
||||
hle/kernel/session.cpp
|
||||
hle/kernel/session.h
|
||||
hle/kernel/slab_helpers.h
|
||||
hle/kernel/svc.cpp
|
||||
hle/kernel/svc.h
|
||||
|
|
|
@ -14,11 +14,9 @@
|
|||
#include "common/common_types.h"
|
||||
#include "core/hle/ipc.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/k_session.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"
|
||||
|
||||
namespace IPC {
|
||||
|
@ -137,9 +135,11 @@ public:
|
|||
if (context->Session()->IsDomain()) {
|
||||
context->AddDomainObject(std::move(iface));
|
||||
} else {
|
||||
auto [client, server] = Kernel::Session::Create(kernel, iface->GetServiceName());
|
||||
context->AddMoveObject(client.get());
|
||||
iface->ClientConnected(std::move(client), std::move(server));
|
||||
auto* session = Kernel::KSession::Create(kernel);
|
||||
session->Initialize(iface->GetServiceName());
|
||||
|
||||
context->AddMoveObject(&session->GetClientSession());
|
||||
iface->ClientConnected(session);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,10 @@
|
|||
// Refer to the license.txt file included.
|
||||
|
||||
#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/k_session.h"
|
||||
#include "core/hle/kernel/object.h"
|
||||
#include "core/hle/kernel/server_port.h"
|
||||
#include "core/hle/kernel/session.h"
|
||||
#include "core/hle/kernel/svc_results.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
@ -19,21 +18,22 @@ std::shared_ptr<ServerPort> ClientPort::GetServerPort() const {
|
|||
return server_port;
|
||||
}
|
||||
|
||||
ResultVal<std::shared_ptr<ClientSession>> ClientPort::Connect() {
|
||||
ResultVal<KClientSession*> ClientPort::Connect() {
|
||||
if (active_sessions >= max_sessions) {
|
||||
return ResultOutOfSessions;
|
||||
}
|
||||
active_sessions++;
|
||||
|
||||
auto [client, server] = Kernel::Session::Create(kernel, name);
|
||||
auto* session = Kernel::KSession::Create(kernel);
|
||||
session->Initialize(name + ":ClientPort");
|
||||
|
||||
if (server_port->HasHLEHandler()) {
|
||||
server_port->GetHLEHandler()->ClientConnected(client, std::move(server));
|
||||
server_port->GetHLEHandler()->ClientConnected(session);
|
||||
} 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() {
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
namespace Kernel {
|
||||
|
||||
class ClientSession;
|
||||
class KClientSession;
|
||||
class KernelCore;
|
||||
class ServerPort;
|
||||
|
||||
|
@ -43,7 +43,7 @@ public:
|
|||
* waiting on it to awake.
|
||||
* @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,
|
||||
|
|
|
@ -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::Process:
|
||||
case HandleType::ReadableEvent:
|
||||
case HandleType::WritableEvent: {
|
||||
case HandleType::WritableEvent:
|
||||
case HandleType::ClientSession:
|
||||
case HandleType::ServerSession:
|
||||
case HandleType::Session: {
|
||||
Handle handle{};
|
||||
Add(&handle, reinterpret_cast<KAutoObject*>(obj), {});
|
||||
return MakeResult<Handle>(handle);
|
||||
|
|
|
@ -19,12 +19,12 @@
|
|||
#include "core/hle/kernel/k_readable_event.h"
|
||||
#include "core/hle/kernel/k_scheduler.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_writable_event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/object.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/time_manager.h"
|
||||
#include "core/memory.h"
|
||||
|
@ -35,24 +35,19 @@ SessionRequestHandler::SessionRequestHandler() = default;
|
|||
|
||||
SessionRequestHandler::~SessionRequestHandler() = default;
|
||||
|
||||
void SessionRequestHandler::ClientConnected(std::shared_ptr<ClientSession> client_session,
|
||||
std::shared_ptr<ServerSession> server_session) {
|
||||
server_session->SetHleHandler(shared_from_this());
|
||||
client_sessions.push_back(std::move(client_session));
|
||||
server_sessions.push_back(std::move(server_session));
|
||||
void SessionRequestHandler::ClientConnected(KSession* session) {
|
||||
session->GetServerSession().SetHleHandler(shared_from_this());
|
||||
sessions.push_back(session);
|
||||
}
|
||||
|
||||
void SessionRequestHandler::ClientDisconnected(
|
||||
const std::shared_ptr<ServerSession>& server_session) {
|
||||
server_session->SetHleHandler(nullptr);
|
||||
boost::range::remove_erase(server_sessions, server_session);
|
||||
void SessionRequestHandler::ClientDisconnected(KSession* session) {
|
||||
session->GetServerSession().SetHleHandler(nullptr);
|
||||
boost::range::remove_erase(sessions, session);
|
||||
}
|
||||
|
||||
HLERequestContext::HLERequestContext(KernelCore& kernel_, Core::Memory::Memory& memory_,
|
||||
std::shared_ptr<ServerSession> server_session_,
|
||||
KThread* thread_)
|
||||
: server_session(std::move(server_session_)),
|
||||
thread(thread_), kernel{kernel_}, memory{memory_} {
|
||||
KServerSession* server_session_, KThread* thread_)
|
||||
: server_session(server_session_), thread(thread_), kernel{kernel_}, memory{memory_} {
|
||||
cmd_buf[0] = 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -39,10 +39,10 @@ class HandleTable;
|
|||
class HLERequestContext;
|
||||
class KernelCore;
|
||||
class Process;
|
||||
class ClientSession;
|
||||
class ServerSession;
|
||||
class KServerSession;
|
||||
class KThread;
|
||||
class KReadableEvent;
|
||||
class KSession;
|
||||
class KWritableEvent;
|
||||
|
||||
enum class ThreadWakeupReason;
|
||||
|
@ -72,22 +72,20 @@ public:
|
|||
* associated ServerSession alive for the duration of the connection.
|
||||
* @param server_session Owning pointer to the ServerSession associated with the connection.
|
||||
*/
|
||||
void ClientConnected(
|
||||
std::shared_ptr<ClientSession> client_session, std::shared_ptr<ServerSession> server_session);
|
||||
void ClientConnected(KSession* session);
|
||||
|
||||
/**
|
||||
* Signals that a client has just disconnected from this HLE handler and releases the
|
||||
* associated ServerSession.
|
||||
* @param server_session ServerSession associated with the connection.
|
||||
*/
|
||||
void ClientDisconnected(const std::shared_ptr<ServerSession>& server_session);
|
||||
void ClientDisconnected(KSession* session);
|
||||
|
||||
protected:
|
||||
/// List of sessions that are connected to this handler.
|
||||
/// A ServerSession whose server endpoint is an HLE implementation is kept alive by this list
|
||||
/// for the duration of the connection.
|
||||
std::vector<std::shared_ptr<ClientSession>> client_sessions;
|
||||
std::vector<std::shared_ptr<ServerSession>> server_sessions;
|
||||
std::vector<KSession*> sessions;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -112,7 +110,7 @@ protected:
|
|||
class HLERequestContext {
|
||||
public:
|
||||
explicit HLERequestContext(KernelCore& kernel, Core::Memory::Memory& memory,
|
||||
std::shared_ptr<ServerSession> session, KThread* thread);
|
||||
KServerSession* session, KThread* thread);
|
||||
~HLERequestContext();
|
||||
|
||||
/// 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
|
||||
* access per-client data on services.
|
||||
*/
|
||||
const std::shared_ptr<Kernel::ServerSession>& Session() const {
|
||||
Kernel::KServerSession* Session() {
|
||||
return server_session;
|
||||
}
|
||||
|
||||
|
@ -288,7 +286,7 @@ private:
|
|||
void ParseCommandBuffer(const HandleTable& handle_table, u32_le* src_cmdbuf, bool incoming);
|
||||
|
||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
||||
std::shared_ptr<Kernel::ServerSession> server_session;
|
||||
Kernel::KServerSession* server_session{};
|
||||
KThread* thread;
|
||||
|
||||
// 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_memory_layout.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_system_control.h"
|
||||
#include "core/hle/kernel/k_thread.h"
|
||||
|
@ -27,7 +28,8 @@ namespace Kernel::Init {
|
|||
HANDLER(Process, (SLAB_COUNT(Process)), ##__VA_ARGS__) \
|
||||
HANDLER(KThread, (SLAB_COUNT(KThread)), ##__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 {
|
||||
|
||||
|
|
31
src/core/hle/kernel/k_client_session.cpp
Normal file
31
src/core/hle/kernel/k_client_session.cpp
Normal file
|
@ -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
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
|
@ -7,7 +7,9 @@
|
|||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#include "core/hle/kernel/k_auto_object.h"
|
||||
#include "core/hle/kernel/k_synchronization_object.h"
|
||||
#include "core/hle/kernel/slab_helpers.h"
|
||||
#include "core/hle/result.h"
|
||||
|
||||
union ResultCode;
|
||||
|
@ -23,15 +25,41 @@ class CoreTiming;
|
|||
namespace Kernel {
|
||||
|
||||
class KernelCore;
|
||||
class Session;
|
||||
class KSession;
|
||||
class KThread;
|
||||
|
||||
class ClientSession final : public KSynchronizationObject {
|
||||
public:
|
||||
explicit ClientSession(KernelCore& kernel);
|
||||
~ClientSession() override;
|
||||
class KClientSession final
|
||||
: public KAutoObjectWithSlabHeapAndContainer<KClientSession, KAutoObjectWithList> {
|
||||
KERNEL_AUTOOBJECT_TRAITS(KClientSession, KAutoObject);
|
||||
|
||||
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 {
|
||||
return "ClientSession";
|
||||
|
@ -41,25 +69,9 @@ public:
|
|||
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:
|
||||
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.
|
||||
std::shared_ptr<Session> parent;
|
||||
KSession* parent{};
|
||||
|
||||
/// Name of the client session (optional)
|
||||
std::string name;
|
|
@ -11,43 +11,38 @@
|
|||
#include "core/core_timing.h"
|
||||
#include "core/hle/ipc_helpers.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/hle_ipc.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/kernel.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/kernel/server_session.h"
|
||||
#include "core/hle/kernel/session.h"
|
||||
#include "core/memory.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
ServerSession::ServerSession(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
||||
KServerSession::KServerSession(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
||||
|
||||
ServerSession::~ServerSession() {
|
||||
KServerSession::~KServerSession() {
|
||||
kernel.ReleaseServiceThread(service_thread);
|
||||
}
|
||||
|
||||
ResultVal<std::shared_ptr<ServerSession>> ServerSession::Create(KernelCore& kernel,
|
||||
std::shared_ptr<Session> parent,
|
||||
std::string name) {
|
||||
std::shared_ptr<ServerSession> session{std::make_shared<ServerSession>(kernel)};
|
||||
|
||||
session->name = std::move(name);
|
||||
session->parent = std::move(parent);
|
||||
session->service_thread = kernel.CreateServiceThread(session->name);
|
||||
|
||||
return MakeResult(std::move(session));
|
||||
void KServerSession::Initialize(KSession* parent_, std::string&& name_) {
|
||||
// Set member variables.
|
||||
parent = parent_;
|
||||
name = std::move(name_);
|
||||
service_thread = kernel.CreateServiceThread(name);
|
||||
}
|
||||
|
||||
bool ServerSession::IsSignaled() const {
|
||||
// Closed sessions should never wait, an error will be returned from svcReplyAndReceive.
|
||||
return !parent->Client();
|
||||
void KServerSession::Destroy() {
|
||||
parent->OnServerClosed();
|
||||
|
||||
parent->Close();
|
||||
}
|
||||
|
||||
void ServerSession::ClientDisconnected() {
|
||||
void KServerSession::OnClientClosed() {
|
||||
// We keep a shared pointer to the hle handler to keep it alive throughout
|
||||
// the call to ClientDisconnected, as ClientDisconnected invalidates the
|
||||
// hle_handler member itself during the course of the function executing.
|
||||
|
@ -55,19 +50,31 @@ void ServerSession::ClientDisconnected() {
|
|||
if (handler) {
|
||||
// Note that after this returns, this server session's hle_handler is
|
||||
// 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));
|
||||
}
|
||||
|
||||
std::size_t ServerSession::NumDomainRequestHandlers() const {
|
||||
std::size_t KServerSession::NumDomainRequestHandlers() const {
|
||||
return domain_request_handlers.size();
|
||||
}
|
||||
|
||||
ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
|
||||
ResultCode KServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
|
||||
if (!context.HasDomainMessageHeader()) {
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
@ -106,21 +113,21 @@ ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& con
|
|||
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()))};
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
ResultCode ServerSession::CompleteSyncRequest(HLERequestContext& context) {
|
||||
ResultCode KServerSession::CompleteSyncRequest(HLERequestContext& context) {
|
||||
ResultCode result = RESULT_SUCCESS;
|
||||
// If the session has been converted to a domain, handle the domain request
|
||||
if (IsDomain() && context.HasDomainMessageHeader()) {
|
||||
|
@ -149,7 +156,7 @@ ResultCode ServerSession::CompleteSyncRequest(HLERequestContext& context) {
|
|||
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) {
|
||||
return QueueSyncRequest(thread, memory);
|
||||
}
|
|
@ -27,55 +27,34 @@ namespace Kernel {
|
|||
|
||||
class HLERequestContext;
|
||||
class KernelCore;
|
||||
class Session;
|
||||
class KSession;
|
||||
class SessionRequestHandler;
|
||||
class KThread;
|
||||
|
||||
/**
|
||||
* Kernel object representing the server endpoint of an IPC session. Sessions are the basic CTR-OS
|
||||
* 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 {
|
||||
class KServerSession final : public KSynchronizationObject {
|
||||
KERNEL_AUTOOBJECT_TRAITS(KServerSession, KSynchronizationObject);
|
||||
|
||||
friend class ServiceThread;
|
||||
|
||||
public:
|
||||
explicit ServerSession(KernelCore& kernel);
|
||||
~ServerSession() override;
|
||||
explicit KServerSession(KernelCore& kernel);
|
||||
virtual ~KServerSession() override;
|
||||
|
||||
friend class Session;
|
||||
virtual void Destroy() override;
|
||||
|
||||
static ResultVal<std::shared_ptr<ServerSession>> Create(KernelCore& kernel,
|
||||
std::shared_ptr<Session> parent,
|
||||
std::string name = "Unknown");
|
||||
void Initialize(KSession* parent_, std::string&& name_);
|
||||
|
||||
std::string GetTypeName() const override {
|
||||
return "ServerSession";
|
||||
constexpr KSession* GetParent() {
|
||||
return parent;
|
||||
}
|
||||
|
||||
std::string GetName() const override {
|
||||
return name;
|
||||
constexpr const KSession* GetParent() const {
|
||||
return parent;
|
||||
}
|
||||
|
||||
static constexpr HandleType HANDLE_TYPE = HandleType::ServerSession;
|
||||
HandleType GetHandleType() const override {
|
||||
return HANDLE_TYPE;
|
||||
}
|
||||
virtual bool IsSignaled() const override;
|
||||
|
||||
Session* GetParent() {
|
||||
return parent.get();
|
||||
}
|
||||
|
||||
const Session* GetParent() const {
|
||||
return parent.get();
|
||||
}
|
||||
void OnClientClosed();
|
||||
|
||||
/**
|
||||
* 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,
|
||||
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
|
||||
/// this ServerSession instance.
|
||||
void AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler);
|
||||
|
@ -124,9 +100,20 @@ public:
|
|||
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:
|
||||
/// Queues a sync request from the emulated application.
|
||||
|
@ -139,9 +126,6 @@ private:
|
|||
/// object handle.
|
||||
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)
|
||||
std::shared_ptr<SessionRequestHandler> hle_handler;
|
||||
|
||||
|
@ -156,6 +140,9 @@ private:
|
|||
|
||||
/// Thread to dispatch service requests
|
||||
std::weak_ptr<ServiceThread> service_thread;
|
||||
|
||||
/// KSession that owns this KServerSession
|
||||
KSession* parent{};
|
||||
};
|
||||
|
||||
} // namespace Kernel
|
67
src/core/hle/kernel/k_session.cpp
Normal file
67
src/core/hle/kernel/k_session.cpp
Normal file
|
@ -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
|
108
src/core/hle/kernel/k_session.h
Normal file
108
src/core/hle/kernel/k_session.h
Normal file
|
@ -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 HandleTable;
|
||||
class KAutoObjectWithListContainer;
|
||||
class KClientSession;
|
||||
class KEvent;
|
||||
class KLinkedListNode;
|
||||
class KMemoryManager;
|
||||
class KResourceLimit;
|
||||
class KScheduler;
|
||||
class KSession;
|
||||
class KSharedMemory;
|
||||
class KThread;
|
||||
class KWritableEvent;
|
||||
|
@ -272,6 +274,10 @@ public:
|
|||
return slab_heap_container->linked_list_node;
|
||||
} else if constexpr (std::is_same_v<T, KWritableEvent>) {
|
||||
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<KLinkedListNode> linked_list_node;
|
||||
KSlabHeap<KWritableEvent> writeable_event;
|
||||
KSlabHeap<KClientSession> client_session;
|
||||
KSlabHeap<KSession> session;
|
||||
};
|
||||
|
||||
std::unique_ptr<SlabHeapContainer> slab_heap_container;
|
||||
|
|
|
@ -5,10 +5,10 @@
|
|||
#include <tuple>
|
||||
#include "common/assert.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/object.h"
|
||||
#include "core/hle/kernel/server_port.h"
|
||||
#include "core/hle/kernel/server_session.h"
|
||||
#include "core/hle/kernel/svc_results.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
@ -16,17 +16,17 @@ namespace Kernel {
|
|||
ServerPort::ServerPort(KernelCore& kernel) : KSynchronizationObject{kernel} {}
|
||||
ServerPort::~ServerPort() = default;
|
||||
|
||||
ResultVal<std::shared_ptr<ServerSession>> ServerPort::Accept() {
|
||||
ResultVal<KServerSession*> ServerPort::Accept() {
|
||||
if (pending_sessions.empty()) {
|
||||
return ResultNotFound;
|
||||
}
|
||||
|
||||
auto session = std::move(pending_sessions.back());
|
||||
auto* session = pending_sessions.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));
|
||||
if (pending_sessions.size() == 1) {
|
||||
NotifyAvailable();
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Kernel {
|
|||
|
||||
class ClientPort;
|
||||
class KernelCore;
|
||||
class ServerSession;
|
||||
class KServerSession;
|
||||
class SessionRequestHandler;
|
||||
|
||||
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
|
||||
* 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.
|
||||
bool HasHLEHandler() const {
|
||||
|
@ -77,7 +77,7 @@ public:
|
|||
|
||||
/// Appends a ServerSession to the collection of ServerSessions
|
||||
/// waiting to be accepted by this port.
|
||||
void AppendPendingSession(std::shared_ptr<ServerSession> pending_session);
|
||||
void AppendPendingSession(KServerSession* pending_session);
|
||||
|
||||
bool IsSignaled() const override;
|
||||
|
||||
|
@ -85,7 +85,7 @@ public:
|
|||
|
||||
private:
|
||||
/// 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)
|
||||
/// ServerSessions created from this port inherit a reference to this handler.
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
#include "common/scope_exit.h"
|
||||
#include "common/thread.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/k_session.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/server_session.h"
|
||||
#include "core/hle/kernel/service_thread.h"
|
||||
#include "core/hle/lock.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);
|
||||
~Impl();
|
||||
|
||||
void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context);
|
||||
void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context);
|
||||
|
||||
private:
|
||||
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::unique_lock lock{queue_mutex};
|
||||
|
||||
// ServerSession owns the service thread, so we cannot caption a strong pointer here in the
|
||||
// event that the ServerSession is terminated.
|
||||
std::weak_ptr<ServerSession> weak_ptr{SharedFrom(&session)};
|
||||
requests.emplace([weak_ptr, context{std::move(context)}]() {
|
||||
if (auto strong_ptr = weak_ptr.lock()) {
|
||||
strong_ptr->CompleteSyncRequest(*context);
|
||||
// Open a reference to the session to ensure it is not closes while the service request
|
||||
// completes asynchronously.
|
||||
session.Open();
|
||||
|
||||
requests.emplace([session_ptr{&session}, context{std::move(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();
|
||||
|
@ -102,7 +111,7 @@ ServiceThread::ServiceThread(KernelCore& kernel, std::size_t num_threads, const
|
|||
|
||||
ServiceThread::~ServiceThread() = default;
|
||||
|
||||
void ServiceThread::QueueSyncRequest(ServerSession& session,
|
||||
void ServiceThread::QueueSyncRequest(KSession& session,
|
||||
std::shared_ptr<HLERequestContext>&& context) {
|
||||
impl->QueueSyncRequest(session, std::move(context));
|
||||
}
|
||||
|
|
|
@ -11,14 +11,14 @@ namespace Kernel {
|
|||
|
||||
class HLERequestContext;
|
||||
class KernelCore;
|
||||
class ServerSession;
|
||||
class KSession;
|
||||
|
||||
class ServiceThread final {
|
||||
public:
|
||||
explicit ServiceThread(KernelCore& kernel, std::size_t num_threads, const std::string& name);
|
||||
~ServiceThread();
|
||||
|
||||
void QueueSyncRequest(ServerSession& session, std::shared_ptr<HLERequestContext>&& context);
|
||||
void QueueSyncRequest(KSession& session, std::shared_ptr<HLERequestContext>&& context);
|
||||
|
||||
private:
|
||||
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/cpu_manager.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/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_event.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;
|
||||
|
||||
std::shared_ptr<ClientSession> client_session;
|
||||
KClientSession* client_session{};
|
||||
CASCADE_RESULT(client_session, client_port->Connect());
|
||||
|
||||
// Return the client session
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -340,16 +340,14 @@ static ResultCode ConnectToNamedPort32(Core::System& system, Handle* out_handle,
|
|||
|
||||
/// Makes a blocking IPC call to an OS service.
|
||||
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());
|
||||
|
||||
auto& kernel = system.Kernel();
|
||||
|
||||
KScopedAutoObject session =
|
||||
kernel.CurrentProcess()->GetHandleTable().GetObject<KClientSession>(handle);
|
||||
R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
|
||||
|
||||
auto thread = kernel.CurrentScheduler()->GetCurrentThread();
|
||||
{
|
||||
KScopedSchedulerLock lock(kernel);
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "core/frontend/applets/web_browser.h"
|
||||
#include "core/hle/kernel/k_readable_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/applet_ae.h"
|
||||
#include "core/hle/service/am/applet_oe.h"
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/ipc_helpers.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_shared_memory.h"
|
||||
#include "core/hle/kernel/k_writable_event.h"
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
#include "common/logging/log.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/sm/sm.h"
|
||||
|
||||
|
|
|
@ -21,11 +21,8 @@ class System;
|
|||
}
|
||||
|
||||
namespace Kernel {
|
||||
class ClientPort;
|
||||
class ServerPort;
|
||||
class ServerSession;
|
||||
class HLERequestContext;
|
||||
} // namespace Kernel
|
||||
}
|
||||
|
||||
namespace Service {
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@
|
|||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/kernel/server_session.h"
|
||||
#include "core/hle/kernel/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/service/sm/controller.h"
|
||||
|
||||
namespace Service::SM {
|
||||
|
@ -30,7 +30,7 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) {
|
|||
|
||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(ctx.Session()->GetParent()->Client().get());
|
||||
rb.PushMoveObjects(ctx.Session()->GetParent()->GetClientSession());
|
||||
}
|
||||
|
||||
void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) {
|
||||
|
|
|
@ -7,7 +7,9 @@
|
|||
#include "core/core.h"
|
||||
#include "core/hle/ipc_helpers.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/result.h"
|
||||
#include "core/hle/service/sm/controller.h"
|
||||
|
@ -89,13 +91,6 @@ ResultVal<std::shared_ptr<Kernel::ClientPort>> ServiceManager::GetServicePort(
|
|||
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;
|
||||
|
||||
/**
|
||||
|
@ -130,19 +125,20 @@ void SM::GetService(Kernel::HLERequestContext& ctx) {
|
|||
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();
|
||||
if (server_port->GetHLEHandler()) {
|
||||
server_port->GetHLEHandler()->ClientConnected(client, server);
|
||||
server_port->GetHLEHandler()->ClientConnected(session);
|
||||
} 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};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(client.get());
|
||||
rb.PushMoveObjects(session->GetClientSession());
|
||||
}
|
||||
|
||||
void SM::RegisterService(Kernel::HLERequestContext& ctx) {
|
||||
|
|
|
@ -22,7 +22,7 @@ class System;
|
|||
|
||||
namespace Kernel {
|
||||
class ClientPort;
|
||||
class ClientSession;
|
||||
class KClientSession;
|
||||
class KernelCore;
|
||||
class ServerPort;
|
||||
class SessionRequestHandler;
|
||||
|
@ -59,7 +59,6 @@ public:
|
|||
u32 max_sessions);
|
||||
ResultCode UnregisterService(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>
|
||||
std::shared_ptr<T> GetService(const std::string& service_name) const {
|
||||
|
@ -81,7 +80,7 @@ private:
|
|||
std::weak_ptr<SM> sm_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;
|
||||
|
||||
/// Kernel context
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
#include "core/hardware_properties.h"
|
||||
#include "core/hle/ipc_helpers.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/kernel.h"
|
||||
#include "core/hle/service/time/interface.h"
|
||||
|
|
Loading…
Reference in a new issue