core: Cleanup RPC (#6674)

This commit is contained in:
GPUCode 2023-07-13 04:54:02 +03:00 committed by GitHub
parent bbf833bceb
commit 7a7f485640
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 69 additions and 83 deletions

View file

@ -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);

View file

@ -32,7 +32,7 @@ namespace AudioCore {
class DspInterface;
}
namespace RPC {
namespace Core::RPC {
class RPCServer;
}

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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