citra/src/core/hle/kernel/server_session.h

104 lines
3.8 KiB
C++
Raw Normal View History

// Copyright 2014 Citra Emulator Project
2014-12-17 05:38:14 +00:00
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
2015-06-21 12:40:28 +00:00
#include <string>
#include "common/assert.h"
#include "common/common_types.h"
#include "core/hle/kernel/object.h"
#include "core/hle/kernel/wait_object.h"
2015-06-21 12:40:28 +00:00
#include "core/hle/result.h"
#include "core/memory.h"
namespace Kernel {
class ClientSession;
class ClientPort;
class ServerSession;
class Session;
class SessionRequestHandler;
class Thread;
/**
* 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 WaitObject {
public:
std::string GetName() const override {
return name;
}
2016-12-01 04:28:31 +00:00
std::string GetTypeName() const override {
return "ServerSession";
}
static const HandleType HANDLE_TYPE = HandleType::ServerSession;
2016-12-01 04:28:31 +00:00
HandleType GetHandleType() const override {
return HANDLE_TYPE;
}
/**
* Sets the HLE handler for the session. This handler will be called to service IPC requests
* instead of the regular IPC machinery. (The regular IPC machinery is currently not
* implemented.)
*/
void SetHleHandler(std::shared_ptr<SessionRequestHandler> hle_handler_) {
hle_handler = std::move(hle_handler_);
}
/**
* Handle a sync request from the emulated application.
* @param thread Thread that initiated the request.
* @returns ResultCode from the operation.
*/
ResultCode HandleSyncRequest(SharedPtr<Thread> thread);
2015-01-19 01:40:53 +00:00
bool ShouldWait(Thread* thread) const override;
void Acquire(Thread* thread) override;
std::string name; ///< The name of this session (optional)
std::shared_ptr<Session> parent; ///< The parent session, which links to the client endpoint.
std::shared_ptr<SessionRequestHandler>
hle_handler; ///< This session's HLE request handler (optional)
/// 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;
private:
2018-10-13 20:11:20 +00:00
explicit ServerSession(KernelSystem& kernel);
~ServerSession() override;
/**
* Creates a server session. The server session can have an optional HLE handler,
* which will be invoked to handle the IPC requests that this session receives.
2018-10-13 20:11:20 +00:00
* @param kernel The kernel instance to create the server session on
* @param name Optional name of the server session.
* @return The created server session
*/
2018-10-13 20:11:20 +00:00
static ResultVal<SharedPtr<ServerSession>> Create(KernelSystem& kernel,
std::string name = "Unknown");
friend class KernelSystem;
};
} // namespace Kernel