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

View file

@ -32,7 +32,7 @@ namespace AudioCore {
class DspInterface; class DspInterface;
} }
namespace RPC { namespace Core::RPC {
class RPCServer; 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 <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

View file

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

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

View file

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

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

View file

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

View file

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

View file

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