core: Cleanup RPC (#6674)
This commit is contained in:
parent
bbf833bceb
commit
7a7f485640
|
@ -416,7 +416,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window,
|
||||||
|
|
||||||
telemetry_session = std::make_unique<Core::TelemetrySession>();
|
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);
|
service_manager = std::make_unique<Service::SM::ServiceManager>(*this);
|
||||||
archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this);
|
archive_manager = std::make_unique<Service::FS::ArchiveManager>(*this);
|
||||||
|
|
|
@ -32,7 +32,7 @@ namespace AudioCore {
|
||||||
class DspInterface;
|
class DspInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace RPC {
|
namespace Core::RPC {
|
||||||
class RPCServer;
|
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 <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
|
||||||
#include "core/rpc/packet.h"
|
#include "core/rpc/packet.h"
|
||||||
|
|
||||||
namespace RPC {
|
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)) {
|
|
||||||
|
|
||||||
|
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));
|
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 <span>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
|
|
||||||
namespace RPC {
|
namespace Core::RPC {
|
||||||
|
|
||||||
enum class PacketType {
|
enum class PacketType : u32 {
|
||||||
Undefined = 0,
|
Undefined = 0,
|
||||||
ReadMemory,
|
ReadMemory = 1,
|
||||||
WriteMemory,
|
WriteMemory = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PacketHeader {
|
struct PacketHeader {
|
||||||
|
@ -32,7 +32,9 @@ constexpr u32 MAX_READ_SIZE = MAX_PACKET_DATA_SIZE;
|
||||||
|
|
||||||
class Packet {
|
class Packet {
|
||||||
public:
|
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 {
|
u32 GetVersion() const {
|
||||||
return header.version;
|
return header.version;
|
||||||
|
@ -54,7 +56,7 @@ public:
|
||||||
return header;
|
return header;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<u8, MAX_PACKET_DATA_SIZE>& GetPacketData() {
|
std::span<u8, MAX_PACKET_DATA_SIZE> GetPacketData() {
|
||||||
return packet_data;
|
return packet_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,4 +78,4 @@ private:
|
||||||
std::function<void(Packet&)> send_reply_callback;
|
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 "common/logging/log.h"
|
||||||
#include "core/arm/arm_interface.h"
|
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/hle/kernel/process.h"
|
|
||||||
#include "core/memory.h"
|
#include "core/memory.h"
|
||||||
#include "core/rpc/packet.h"
|
#include "core/rpc/packet.h"
|
||||||
#include "core/rpc/rpc_server.h"
|
#include "core/rpc/rpc_server.h"
|
||||||
|
|
||||||
namespace RPC {
|
namespace Core::RPC {
|
||||||
|
|
||||||
RPCServer::RPCServer() : server(*this) {
|
RPCServer::RPCServer(Core::System& system_) : system{system_}, server{*this} {
|
||||||
LOG_INFO(RPC_Server, "Starting RPC server ...");
|
LOG_INFO(RPC_Server, "Starting RPC server.");
|
||||||
|
request_handler_thread =
|
||||||
Start();
|
std::jthread([this](std::stop_token stop_token) { HandleRequestsLoop(stop_token); });
|
||||||
|
|
||||||
LOG_INFO(RPC_Server, "RPC started.");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RPCServer::~RPCServer() {
|
RPCServer::~RPCServer() = default;
|
||||||
LOG_INFO(RPC_Server, "Stopping RPC ...");
|
|
||||||
|
|
||||||
Stop();
|
|
||||||
|
|
||||||
LOG_INFO(RPC_Server, "RPC stopped.");
|
|
||||||
}
|
|
||||||
|
|
||||||
void RPCServer::HandleReadMemory(Packet& packet, u32 address, u32 data_size) {
|
void RPCServer::HandleReadMemory(Packet& packet, u32 address, u32 data_size) {
|
||||||
if (data_size > MAX_READ_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
|
// Note: Memory read occurs asynchronously from the state of the emulator
|
||||||
Core::System::GetInstance().Memory().ReadBlock(
|
system.Memory().ReadBlock(address, packet.GetPacketData().data(), data_size);
|
||||||
*Core::System::GetInstance().Kernel().GetCurrentProcess(), address,
|
|
||||||
packet.GetPacketData().data(), data_size);
|
|
||||||
packet.SetPacketDataSize(data_size);
|
packet.SetPacketDataSize(data_size);
|
||||||
packet.SendReply();
|
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::HEAP_VADDR && address <= Memory::HEAP_VADDR_END) ||
|
||||||
(address >= Memory::N3DS_EXTRA_RAM_VADDR && address <= Memory::N3DS_EXTRA_RAM_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
|
// Note: Memory write occurs asynchronously from the state of the emulator
|
||||||
Core::System::GetInstance().Memory().WriteBlock(
|
system.Memory().WriteBlock(address, data.data(), data.size());
|
||||||
*Core::System::GetInstance().Kernel().GetCurrentProcess(), address, data.data(),
|
|
||||||
data.size());
|
|
||||||
// If the memory happens to be executable code, make sure the changes become visible
|
// If the memory happens to be executable code, make sure the changes become visible
|
||||||
|
|
||||||
// Is current core correct here?
|
// Is current core correct here?
|
||||||
Core::System::GetInstance().InvalidateCacheRange(address, data.size());
|
system.InvalidateCacheRange(address, data.size());
|
||||||
}
|
}
|
||||||
packet.SetPacketDataSize(0);
|
packet.SetPacketDataSize(0);
|
||||||
packet.SendReply();
|
packet.SendReply();
|
||||||
|
@ -73,7 +63,7 @@ bool RPCServer::ValidatePacket(const PacketHeader& packet_header) {
|
||||||
|
|
||||||
void RPCServer::HandleSingleRequest(std::unique_ptr<Packet> request_packet) {
|
void RPCServer::HandleSingleRequest(std::unique_ptr<Packet> request_packet) {
|
||||||
bool success = false;
|
bool success = false;
|
||||||
const auto& packet_data = request_packet->GetPacketData();
|
const auto packet_data = request_packet->GetPacketData();
|
||||||
|
|
||||||
if (ValidatePacket(request_packet->GetHeader())) {
|
if (ValidatePacket(request_packet->GetHeader())) {
|
||||||
// Currently, all request types use the address/data_size wire format
|
// 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;
|
break;
|
||||||
case PacketType::WriteMemory:
|
case PacketType::WriteMemory:
|
||||||
if (data_size > 0 && data_size <= MAX_PACKET_DATA_SIZE - (sizeof(u32) * 2)) {
|
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);
|
HandleWriteMemory(*request_packet, address, data);
|
||||||
success = true;
|
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;
|
std::unique_ptr<RPC::Packet> request_packet;
|
||||||
|
|
||||||
LOG_INFO(RPC_Server, "Request handler started.");
|
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));
|
HandleSingleRequest(std::move(request_packet));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,15 +112,4 @@ void RPCServer::QueueRequest(std::unique_ptr<RPC::Packet> request) {
|
||||||
request_queue.Push(std::move(request));
|
request_queue.Push(std::move(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
void RPCServer::Start() {
|
}; // namespace Core::RPC
|
||||||
const auto threadFunction = [this]() { HandleRequestsLoop(); };
|
|
||||||
request_handler_thread = std::thread(threadFunction);
|
|
||||||
server.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RPCServer::Stop() {
|
|
||||||
server.Stop();
|
|
||||||
request_handler_thread.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // namespace RPC
|
|
||||||
|
|
|
@ -6,36 +6,39 @@
|
||||||
|
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <mutex>
|
|
||||||
#include <span>
|
#include <span>
|
||||||
#include <thread>
|
#include "common/polyfill_thread.h"
|
||||||
#include "common/threadsafe_queue.h"
|
#include "common/threadsafe_queue.h"
|
||||||
#include "core/rpc/server.h"
|
#include "core/rpc/server.h"
|
||||||
|
|
||||||
namespace RPC {
|
namespace Core {
|
||||||
|
class System;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace Core::RPC {
|
||||||
|
|
||||||
class Packet;
|
class Packet;
|
||||||
struct PacketHeader;
|
struct PacketHeader;
|
||||||
|
|
||||||
class RPCServer {
|
class RPCServer {
|
||||||
public:
|
public:
|
||||||
RPCServer();
|
explicit RPCServer(Core::System& system);
|
||||||
~RPCServer();
|
~RPCServer();
|
||||||
|
|
||||||
void QueueRequest(std::unique_ptr<RPC::Packet> request);
|
void QueueRequest(std::unique_ptr<RPC::Packet> request);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Start();
|
|
||||||
void Stop();
|
|
||||||
void HandleReadMemory(Packet& packet, u32 address, u32 data_size);
|
void HandleReadMemory(Packet& packet, u32 address, u32 data_size);
|
||||||
void HandleWriteMemory(Packet& packet, u32 address, std::span<const u8> data);
|
void HandleWriteMemory(Packet& packet, u32 address, std::span<const u8> data);
|
||||||
bool ValidatePacket(const PacketHeader& packet_header);
|
bool ValidatePacket(const PacketHeader& packet_header);
|
||||||
void HandleSingleRequest(std::unique_ptr<Packet> request);
|
void HandleSingleRequest(std::unique_ptr<Packet> request);
|
||||||
void HandleRequestsLoop();
|
void HandleRequestsLoop(std::stop_token stop_token);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Core::System& system;
|
||||||
Server server;
|
Server server;
|
||||||
Common::SPSCQueue<std::unique_ptr<Packet>> request_queue;
|
Common::SPSCQueue<std::unique_ptr<Packet>, true> request_queue;
|
||||||
std::thread request_handler_thread;
|
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 <functional>
|
||||||
#include "core/core.h"
|
|
||||||
#include "core/rpc/packet.h"
|
#include "core/rpc/packet.h"
|
||||||
#include "core/rpc/rpc_server.h"
|
#include "core/rpc/rpc_server.h"
|
||||||
#include "core/rpc/server.h"
|
#include "core/rpc/server.h"
|
||||||
#include "core/rpc/udp_server.h"
|
#include "core/rpc/udp_server.h"
|
||||||
|
|
||||||
namespace RPC {
|
namespace Core::RPC {
|
||||||
|
|
||||||
Server::Server(RPCServer& rpc_server) : rpc_server(rpc_server) {}
|
Server::Server(RPCServer& rpc_server) : rpc_server(rpc_server) {
|
||||||
|
|
||||||
Server::~Server() = default;
|
|
||||||
|
|
||||||
void Server::Start() {
|
|
||||||
const auto callback = [this](std::unique_ptr<Packet> new_request) {
|
const auto callback = [this](std::unique_ptr<Packet> new_request) {
|
||||||
NewRequestCallback(std::move(new_request));
|
NewRequestCallback(std::move(new_request));
|
||||||
};
|
};
|
||||||
|
@ -23,7 +22,7 @@ void Server::Start() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Server::Stop() {
|
Server::~Server() {
|
||||||
udp_server.reset();
|
udp_server.reset();
|
||||||
NewRequestCallback(nullptr); // Notify the RPC server to end
|
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));
|
rpc_server.QueueRequest(std::move(new_request));
|
||||||
}
|
}
|
||||||
|
|
||||||
}; // namespace RPC
|
}; // namespace Core::RPC
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace RPC {
|
namespace Core::RPC {
|
||||||
|
|
||||||
class RPCServer;
|
class RPCServer;
|
||||||
class UDPServer;
|
class UDPServer;
|
||||||
|
@ -14,10 +14,9 @@ class Packet;
|
||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
public:
|
public:
|
||||||
Server(RPCServer& rpc_server);
|
explicit Server(RPCServer& rpc_server);
|
||||||
~Server();
|
~Server();
|
||||||
void Start();
|
|
||||||
void Stop();
|
|
||||||
void NewRequestCallback(std::unique_ptr<Packet> new_request);
|
void NewRequestCallback(std::unique_ptr<Packet> new_request);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -25,4 +24,4 @@ private:
|
||||||
std::unique_ptr<UDPServer> udp_server;
|
std::unique_ptr<UDPServer> udp_server;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RPC
|
} // namespace Core::RPC
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "core/rpc/packet.h"
|
#include "core/rpc/packet.h"
|
||||||
#include "core/rpc/udp_server.h"
|
#include "core/rpc/udp_server.h"
|
||||||
|
|
||||||
namespace RPC {
|
namespace Core::RPC {
|
||||||
|
|
||||||
class UDPServer::Impl {
|
class UDPServer::Impl {
|
||||||
public:
|
public:
|
||||||
|
@ -93,4 +93,4 @@ UDPServer::UDPServer(std::function<void(std::unique_ptr<Packet>)> new_request_ca
|
||||||
|
|
||||||
UDPServer::~UDPServer() = default;
|
UDPServer::~UDPServer() = default;
|
||||||
|
|
||||||
} // namespace RPC
|
} // namespace Core::RPC
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace RPC {
|
namespace Core::RPC {
|
||||||
|
|
||||||
class Packet;
|
class Packet;
|
||||||
|
|
||||||
|
@ -21,4 +21,4 @@ private:
|
||||||
std::unique_ptr<Impl> impl;
|
std::unique_ptr<Impl> impl;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace RPC
|
} // namespace Core::RPC
|
||||||
|
|
Reference in New Issue