mirror of
https://git.h3cjp.net/H3cJP/yuzu.git
synced 2024-12-15 07:15:01 +00:00
kernel/server_session: Make data members private
Makes it much nicer to locally reason about server session behavior, as part of its functionality isn't placed around other classes.
This commit is contained in:
parent
7526b6fce3
commit
221613d4ea
|
@ -17,21 +17,11 @@ ClientSession::~ClientSession() {
|
||||||
// This destructor will be called automatically when the last ClientSession handle is closed by
|
// This destructor will be called automatically when the last ClientSession handle is closed by
|
||||||
// the emulated application.
|
// the emulated application.
|
||||||
|
|
||||||
// Local references to ServerSession and SessionRequestHandler are necessary to guarantee they
|
// A local reference to the ServerSession is necessary to guarantee it
|
||||||
// will be kept alive until after ClientDisconnected() returns.
|
// will be kept alive until after ClientDisconnected() returns.
|
||||||
SharedPtr<ServerSession> server = parent->server;
|
SharedPtr<ServerSession> server = parent->server;
|
||||||
if (server) {
|
if (server) {
|
||||||
std::shared_ptr<SessionRequestHandler> hle_handler = server->hle_handler;
|
server->ClientDisconnected();
|
||||||
if (hle_handler)
|
|
||||||
hle_handler->ClientDisconnected(server);
|
|
||||||
|
|
||||||
// TODO(Subv): Force a wake up of all the ServerSession's waiting threads and set
|
|
||||||
// their WaitSynchronization result to 0xC920181A.
|
|
||||||
|
|
||||||
// Clean up the list of client threads with pending requests, they are unneeded now that the
|
|
||||||
// client endpoint is closed.
|
|
||||||
server->pending_requesting_threads.clear();
|
|
||||||
server->currently_handling = nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
parent->client = nullptr;
|
parent->client = nullptr;
|
||||||
|
|
|
@ -264,11 +264,11 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(Thread& thread) {
|
||||||
// Write the domain objects to the command buffer, these go after the raw untranslated data.
|
// Write the domain objects to the command buffer, these go after the raw untranslated data.
|
||||||
// TODO(Subv): This completely ignores C buffers.
|
// TODO(Subv): This completely ignores C buffers.
|
||||||
std::size_t domain_offset = size - domain_message_header->num_objects;
|
std::size_t domain_offset = size - domain_message_header->num_objects;
|
||||||
auto& request_handlers = server_session->domain_request_handlers;
|
|
||||||
|
|
||||||
for (auto& object : domain_objects) {
|
for (const auto& object : domain_objects) {
|
||||||
request_handlers.emplace_back(object);
|
server_session->AppendDomainRequestHandler(object);
|
||||||
dst_cmdbuf[domain_offset++] = static_cast<u32_le>(request_handlers.size());
|
dst_cmdbuf[domain_offset++] =
|
||||||
|
static_cast<u32_le>(server_session->NumDomainRequestHandlers());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,6 +63,34 @@ void ServerSession::Acquire(Thread* thread) {
|
||||||
pending_requesting_threads.pop_back();
|
pending_requesting_threads.pop_back();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ServerSession::ClientDisconnected() {
|
||||||
|
// 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.
|
||||||
|
std::shared_ptr<SessionRequestHandler> handler = hle_handler;
|
||||||
|
if (handler) {
|
||||||
|
// Note that after this returns, this server session's hle_handler is
|
||||||
|
// invalidated (set to null).
|
||||||
|
handler->ClientDisconnected(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(Subv): Force a wake up of all the ServerSession's waiting threads and set
|
||||||
|
// their WaitSynchronization result to 0xC920181A.
|
||||||
|
|
||||||
|
// Clean up the list of client threads with pending requests, they are unneeded now that the
|
||||||
|
// client endpoint is closed.
|
||||||
|
pending_requesting_threads.clear();
|
||||||
|
currently_handling = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ServerSession::AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler) {
|
||||||
|
domain_request_handlers.push_back(std::move(handler));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t ServerSession::NumDomainRequestHandlers() const {
|
||||||
|
return domain_request_handlers.size();
|
||||||
|
}
|
||||||
|
|
||||||
ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
|
ResultCode ServerSession::HandleDomainSyncRequest(Kernel::HLERequestContext& context) {
|
||||||
auto* const domain_message_header = context.GetDomainMessageHeader();
|
auto* const domain_message_header = context.GetDomainMessageHeader();
|
||||||
if (domain_message_header) {
|
if (domain_message_header) {
|
||||||
|
|
|
@ -46,6 +46,14 @@ public:
|
||||||
return HANDLE_TYPE;
|
return HANDLE_TYPE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Session* GetParent() {
|
||||||
|
return parent.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Session* GetParent() const {
|
||||||
|
return parent.get();
|
||||||
|
}
|
||||||
|
|
||||||
using SessionPair = std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>>;
|
using SessionPair = std::tuple<SharedPtr<ServerSession>, SharedPtr<ClientSession>>;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,23 +86,16 @@ public:
|
||||||
|
|
||||||
void Acquire(Thread* thread) override;
|
void Acquire(Thread* thread) override;
|
||||||
|
|
||||||
std::string name; ///< The name of this session (optional)
|
/// Called when a client disconnection occurs.
|
||||||
std::shared_ptr<Session> parent; ///< The parent session, which links to the client endpoint.
|
void ClientDisconnected();
|
||||||
std::shared_ptr<SessionRequestHandler>
|
|
||||||
hle_handler; ///< This session's HLE request handler (applicable when not a domain)
|
|
||||||
|
|
||||||
/// This is the list of domain request handlers (after conversion to a domain)
|
/// Adds a new domain request handler to the collection of request handlers within
|
||||||
std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers;
|
/// this ServerSession instance.
|
||||||
|
void AppendDomainRequestHandler(std::shared_ptr<SessionRequestHandler> handler);
|
||||||
|
|
||||||
/// List of threads that are pending a response after a sync request. This list is processed in
|
/// Retrieves the total number of domain request handlers that have been
|
||||||
/// a LIFO manner, thus, the last request will be dispatched first.
|
/// appended to this ServerSession instance.
|
||||||
/// TODO(Subv): Verify if this is indeed processed in LIFO using a hardware test.
|
std::size_t NumDomainRequestHandlers() const;
|
||||||
std::vector<SharedPtr<Thread>> pending_requesting_threads;
|
|
||||||
|
|
||||||
/// Thread whose request is currently being handled. A request is considered "handled" when a
|
|
||||||
/// response is sent via svcReplyAndReceive.
|
|
||||||
/// TODO(Subv): Find a better name for this.
|
|
||||||
SharedPtr<Thread> currently_handling;
|
|
||||||
|
|
||||||
/// Returns true if the session has been converted to a domain, otherwise False
|
/// Returns true if the session has been converted to a domain, otherwise False
|
||||||
bool IsDomain() const {
|
bool IsDomain() const {
|
||||||
|
@ -129,8 +130,30 @@ 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)
|
||||||
|
std::shared_ptr<SessionRequestHandler> hle_handler;
|
||||||
|
|
||||||
|
/// This is the list of domain request handlers (after conversion to a domain)
|
||||||
|
std::vector<std::shared_ptr<SessionRequestHandler>> domain_request_handlers;
|
||||||
|
|
||||||
|
/// List of threads that are pending a response after a sync request. This list is processed in
|
||||||
|
/// a LIFO manner, thus, the last request will be dispatched first.
|
||||||
|
/// TODO(Subv): Verify if this is indeed processed in LIFO using a hardware test.
|
||||||
|
std::vector<SharedPtr<Thread>> pending_requesting_threads;
|
||||||
|
|
||||||
|
/// Thread whose request is currently being handled. A request is considered "handled" when a
|
||||||
|
/// response is sent via svcReplyAndReceive.
|
||||||
|
/// TODO(Subv): Find a better name for this.
|
||||||
|
SharedPtr<Thread> currently_handling;
|
||||||
|
|
||||||
/// When set to True, converts the session to a domain at the end of the command
|
/// When set to True, converts the session to a domain at the end of the command
|
||||||
bool convert_to_domain{};
|
bool convert_to_domain{};
|
||||||
|
|
||||||
|
/// The name of this session (optional)
|
||||||
|
std::string name;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|
|
@ -30,7 +30,7 @@ void Controller::DuplicateSession(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);
|
||||||
Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->parent->client};
|
Kernel::SharedPtr<Kernel::ClientSession> session{ctx.Session()->GetParent()->client};
|
||||||
rb.PushMoveObjects(session);
|
rb.PushMoveObjects(session);
|
||||||
|
|
||||||
LOG_DEBUG(Service, "session={}", session->GetObjectId());
|
LOG_DEBUG(Service, "session={}", session->GetObjectId());
|
||||||
|
|
Loading…
Reference in a new issue