mirror of
https://github.com/PabloMK7/citra.git
synced 2024-11-24 08:24:18 +00:00
core: Cleanup RPC (#6674)
This commit is contained in:
parent
bbf833bceb
commit
7a7f485640
10 changed files with 69 additions and 83 deletions
|
@ -416,7 +416,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
|
|||
|
||||
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
||||
|
||||
rpc_server = std::make_unique<RPC::RPCServer>();
|
||||
rpc_server = std::make_unique<RPC::RPCServer>(*this);
|
||||
|
||||
service_manager = std::make_unique<Service::SM::ServiceManager>(*this);
|
||||
archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this);
|
||||
|
|
|
@ -32,7 +32,7 @@ namespace AudioCore {
|
|||
class DspInterface;
|
||||
}
|
||||
|
||||
namespace RPC {
|
||||
namespace Core::RPC {
|
||||
class RPCServer;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,19 @@
|
|||
// Copyright 2019 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
||||
#include "core/rpc/packet.h"
|
||||
|
||||
namespace RPC {
|
||||
|
||||
Packet::Packet(const PacketHeader& header, u8* data,
|
||||
std::function<void(Packet&)> send_reply_callback)
|
||||
: header(header), send_reply_callback(std::move(send_reply_callback)) {
|
||||
namespace Core::RPC {
|
||||
|
||||
Packet::Packet(const PacketHeader& header_, u8* data,
|
||||
std::function<void(Packet&)> send_reply_callback_)
|
||||
: header{header_}, send_reply_callback{std::move(send_reply_callback_)} {
|
||||
std::memcpy(packet_data.data(), data, std::min(header.packet_size, MAX_PACKET_DATA_SIZE));
|
||||
}
|
||||
|
||||
}; // namespace RPC
|
||||
Packet::~Packet() = default;
|
||||
|
||||
}; // namespace Core::RPC
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
#include <span>
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace RPC {
|
||||
namespace Core::RPC {
|
||||
|
||||
enum class PacketType {
|
||||
enum class PacketType : u32 {
|
||||
Undefined = 0,
|
||||
ReadMemory,
|
||||
WriteMemory,
|
||||
ReadMemory = 1,
|
||||
WriteMemory = 2,
|
||||
};
|
||||
|
||||
struct PacketHeader {
|
||||
|
@ -32,7 +32,9 @@ constexpr u32 MAX_READ_SIZE = MAX_PACKET_DATA_SIZE;
|
|||
|
||||
class Packet {
|
||||
public:
|
||||
Packet(const PacketHeader& header, u8* data, std::function<void(Packet&)> send_reply_callback);
|
||||
explicit Packet(const PacketHeader& header, u8* data,
|
||||
std::function<void(Packet&)> send_reply_callback);
|
||||
~Packet();
|
||||
|
||||
u32 GetVersion() const {
|
||||
return header.version;
|
||||
|
@ -54,7 +56,7 @@ public:
|
|||
return header;
|
||||
}
|
||||
|
||||
std::array<u8, MAX_PACKET_DATA_SIZE>& GetPacketData() {
|
||||
std::span<u8, MAX_PACKET_DATA_SIZE> GetPacketData() {
|
||||
return packet_data;
|
||||
}
|
||||
|
||||
|
@ -76,4 +78,4 @@ private:
|
|||
std::function<void(Packet&)> send_reply_callback;
|
||||
};
|
||||
|
||||
} // namespace RPC
|
||||
} // namespace Core::RPC
|
||||
|
|
|
@ -1,28 +1,22 @@
|
|||
// Copyright 2019 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/memory.h"
|
||||
#include "core/rpc/packet.h"
|
||||
#include "core/rpc/rpc_server.h"
|
||||
|
||||
namespace RPC {
|
||||
namespace Core::RPC {
|
||||
|
||||
RPCServer::RPCServer() : server(*this) {
|
||||
LOG_INFO(RPC_Server, "Starting RPC server ...");
|
||||
|
||||
Start();
|
||||
|
||||
LOG_INFO(RPC_Server, "RPC started.");
|
||||
RPCServer::RPCServer(Core::System& system_) : system{system_}, server{*this} {
|
||||
LOG_INFO(RPC_Server, "Starting RPC server.");
|
||||
request_handler_thread =
|
||||
std::jthread([this](std::stop_token stop_token) { HandleRequestsLoop(stop_token); });
|
||||
}
|
||||
|
||||
RPCServer::~RPCServer() {
|
||||
LOG_INFO(RPC_Server, "Stopping RPC ...");
|
||||
|
||||
Stop();
|
||||
|
||||
LOG_INFO(RPC_Server, "RPC stopped.");
|
||||
}
|
||||
RPCServer::~RPCServer() = default;
|
||||
|
||||
void RPCServer::HandleReadMemory(Packet& packet, u32 address, u32 data_size) {
|
||||
if (data_size > MAX_READ_SIZE) {
|
||||
|
@ -30,9 +24,7 @@ void RPCServer::HandleReadMemory(Packet& packet, u32 address, u32 data_size) {
|
|||
}
|
||||
|
||||
// Note: Memory read occurs asynchronously from the state of the emulator
|
||||
Core::System::GetInstance().Memory().ReadBlock(
|
||||
*Core::System::GetInstance().Kernel().GetCurrentProcess(), address,
|
||||
packet.GetPacketData().data(), data_size);
|
||||
system.Memory().ReadBlock(address, packet.GetPacketData().data(), data_size);
|
||||
packet.SetPacketDataSize(data_size);
|
||||
packet.SendReply();
|
||||
}
|
||||
|
@ -43,13 +35,11 @@ void RPCServer::HandleWriteMemory(Packet& packet, u32 address, std::span<const u
|
|||
(address >= Memory::HEAP_VADDR && address <= Memory::HEAP_VADDR_END) ||
|
||||
(address >= Memory::N3DS_EXTRA_RAM_VADDR && address <= Memory::N3DS_EXTRA_RAM_VADDR_END)) {
|
||||
// Note: Memory write occurs asynchronously from the state of the emulator
|
||||
Core::System::GetInstance().Memory().WriteBlock(
|
||||
*Core::System::GetInstance().Kernel().GetCurrentProcess(), address, data.data(),
|
||||
data.size());
|
||||
system.Memory().WriteBlock(address, data.data(), data.size());
|
||||
// If the memory happens to be executable code, make sure the changes become visible
|
||||
|
||||
// Is current core correct here?
|
||||
Core::System::GetInstance().InvalidateCacheRange(address, data.size());
|
||||
system.InvalidateCacheRange(address, data.size());
|
||||
}
|
||||
packet.SetPacketDataSize(0);
|
||||
packet.SendReply();
|
||||
|
@ -73,7 +63,7 @@ bool RPCServer::ValidatePacket(const PacketHeader& packet_header) {
|
|||
|
||||
void RPCServer::HandleSingleRequest(std::unique_ptr<Packet> request_packet) {
|
||||
bool success = false;
|
||||
const auto& packet_data = request_packet->GetPacketData();
|
||||
const auto packet_data = request_packet->GetPacketData();
|
||||
|
||||
if (ValidatePacket(request_packet->GetHeader())) {
|
||||
// Currently, all request types use the address/data_size wire format
|
||||
|
@ -91,7 +81,7 @@ void RPCServer::HandleSingleRequest(std::unique_ptr<Packet> request_packet) {
|
|||
break;
|
||||
case PacketType::WriteMemory:
|
||||
if (data_size > 0 && data_size <= MAX_PACKET_DATA_SIZE - (sizeof(u32) * 2)) {
|
||||
const auto data = std::span{packet_data}.subspan(sizeof(u32) * 2, data_size);
|
||||
const auto data = packet_data.subspan(sizeof(u32) * 2, data_size);
|
||||
HandleWriteMemory(*request_packet, address, data);
|
||||
success = true;
|
||||
}
|
||||
|
@ -108,12 +98,12 @@ void RPCServer::HandleSingleRequest(std::unique_ptr<Packet> request_packet) {
|
|||
}
|
||||
}
|
||||
|
||||
void RPCServer::HandleRequestsLoop() {
|
||||
void RPCServer::HandleRequestsLoop(std::stop_token stop_token) {
|
||||
std::unique_ptr<RPC::Packet> request_packet;
|
||||
|
||||
LOG_INFO(RPC_Server, "Request handler started.");
|
||||
|
||||
while ((request_packet = request_queue.PopWait())) {
|
||||
while ((request_packet = request_queue.PopWait(stop_token))) {
|
||||
HandleSingleRequest(std::move(request_packet));
|
||||
}
|
||||
}
|
||||
|
@ -122,15 +112,4 @@ void RPCServer::QueueRequest(std::unique_ptr<RPC::Packet> request) {
|
|||
request_queue.Push(std::move(request));
|
||||
}
|
||||
|
||||
void RPCServer::Start() {
|
||||
const auto threadFunction = [this]() { HandleRequestsLoop(); };
|
||||
request_handler_thread = std::thread(threadFunction);
|
||||
server.Start();
|
||||
}
|
||||
|
||||
void RPCServer::Stop() {
|
||||
server.Stop();
|
||||
request_handler_thread.join();
|
||||
}
|
||||
|
||||
}; // namespace RPC
|
||||
}; // namespace Core::RPC
|
||||
|
|
|
@ -6,36 +6,39 @@
|
|||
|
||||
#include <condition_variable>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <span>
|
||||
#include <thread>
|
||||
#include "common/polyfill_thread.h"
|
||||
#include "common/threadsafe_queue.h"
|
||||
#include "core/rpc/server.h"
|
||||
|
||||
namespace RPC {
|
||||
namespace Core {
|
||||
class System;
|
||||
}
|
||||
|
||||
namespace Core::RPC {
|
||||
|
||||
class Packet;
|
||||
struct PacketHeader;
|
||||
|
||||
class RPCServer {
|
||||
public:
|
||||
RPCServer();
|
||||
explicit RPCServer(Core::System& system);
|
||||
~RPCServer();
|
||||
|
||||
void QueueRequest(std::unique_ptr<RPC::Packet> request);
|
||||
|
||||
private:
|
||||
void Start();
|
||||
void Stop();
|
||||
void HandleReadMemory(Packet& packet, u32 address, u32 data_size);
|
||||
void HandleWriteMemory(Packet& packet, u32 address, std::span<const u8> data);
|
||||
bool ValidatePacket(const PacketHeader& packet_header);
|
||||
void HandleSingleRequest(std::unique_ptr<Packet> request);
|
||||
void HandleRequestsLoop();
|
||||
void HandleRequestsLoop(std::stop_token stop_token);
|
||||
|
||||
private:
|
||||
Core::System& system;
|
||||
Server server;
|
||||
Common::SPSCQueue<std::unique_ptr<Packet>> request_queue;
|
||||
std::thread request_handler_thread;
|
||||
Common::SPSCQueue<std::unique_ptr<Packet>, true> request_queue;
|
||||
std::jthread request_handler_thread;
|
||||
};
|
||||
|
||||
} // namespace RPC
|
||||
} // namespace Core::RPC
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
// Copyright 2019 Citra Emulator Project
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <functional>
|
||||
#include "core/core.h"
|
||||
#include "core/rpc/packet.h"
|
||||
#include "core/rpc/rpc_server.h"
|
||||
#include "core/rpc/server.h"
|
||||
#include "core/rpc/udp_server.h"
|
||||
|
||||
namespace RPC {
|
||||
namespace Core::RPC {
|
||||
|
||||
Server::Server(RPCServer& rpc_server) : rpc_server(rpc_server) {}
|
||||
|
||||
Server::~Server() = default;
|
||||
|
||||
void Server::Start() {
|
||||
Server::Server(RPCServer& rpc_server) : rpc_server(rpc_server) {
|
||||
const auto callback = [this](std::unique_ptr<Packet> new_request) {
|
||||
NewRequestCallback(std::move(new_request));
|
||||
};
|
||||
|
@ -23,7 +22,7 @@ void Server::Start() {
|
|||
}
|
||||
}
|
||||
|
||||
void Server::Stop() {
|
||||
Server::~Server() {
|
||||
udp_server.reset();
|
||||
NewRequestCallback(nullptr); // Notify the RPC server to end
|
||||
}
|
||||
|
@ -39,4 +38,4 @@ void Server::NewRequestCallback(std::unique_ptr<RPC::Packet> new_request) {
|
|||
rpc_server.QueueRequest(std::move(new_request));
|
||||
}
|
||||
|
||||
}; // namespace RPC
|
||||
}; // namespace Core::RPC
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
namespace RPC {
|
||||
namespace Core::RPC {
|
||||
|
||||
class RPCServer;
|
||||
class UDPServer;
|
||||
|
@ -14,10 +14,9 @@ class Packet;
|
|||
|
||||
class Server {
|
||||
public:
|
||||
Server(RPCServer& rpc_server);
|
||||
explicit Server(RPCServer& rpc_server);
|
||||
~Server();
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
void NewRequestCallback(std::unique_ptr<Packet> new_request);
|
||||
|
||||
private:
|
||||
|
@ -25,4 +24,4 @@ private:
|
|||
std::unique_ptr<UDPServer> udp_server;
|
||||
};
|
||||
|
||||
} // namespace RPC
|
||||
} // namespace Core::RPC
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "core/rpc/packet.h"
|
||||
#include "core/rpc/udp_server.h"
|
||||
|
||||
namespace RPC {
|
||||
namespace Core::RPC {
|
||||
|
||||
class UDPServer::Impl {
|
||||
public:
|
||||
|
@ -93,4 +93,4 @@ UDPServer::UDPServer(std::function<void(std::unique_ptr<Packet>)> new_request_ca
|
|||
|
||||
UDPServer::~UDPServer() = default;
|
||||
|
||||
} // namespace RPC
|
||||
} // namespace Core::RPC
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
#include <functional>
|
||||
#include <memory>
|
||||
|
||||
namespace RPC {
|
||||
namespace Core::RPC {
|
||||
|
||||
class Packet;
|
||||
|
||||
|
@ -21,4 +21,4 @@ private:
|
|||
std::unique_ptr<Impl> impl;
|
||||
};
|
||||
|
||||
} // namespace RPC
|
||||
} // namespace Core::RPC
|
||||
|
|
Loading…
Reference in a new issue