From 7a7f4856404c462fc715e02b38042630f44c6ca3 Mon Sep 17 00:00:00 2001 From: GPUCode <47210458+GPUCode@users.noreply.github.com> Date: Thu, 13 Jul 2023 04:54:02 +0300 Subject: [PATCH] core: Cleanup RPC (#6674) --- src/core/core.cpp | 2 +- src/core/core.h | 2 +- src/core/rpc/packet.cpp | 18 +++++++----- src/core/rpc/packet.h | 16 ++++++----- src/core/rpc/rpc_server.cpp | 57 ++++++++++++------------------------- src/core/rpc/rpc_server.h | 23 ++++++++------- src/core/rpc/server.cpp | 17 ++++++----- src/core/rpc/server.h | 9 +++--- src/core/rpc/udp_server.cpp | 4 +-- src/core/rpc/udp_server.h | 4 +-- 10 files changed, 69 insertions(+), 83 deletions(-) diff --git a/src/core/core.cpp b/src/core/core.cpp index 4ac4d0fd0..35bcca994 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -416,7 +416,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, telemetry_session = std::make_unique(); - rpc_server = std::make_unique(); + rpc_server = std::make_unique(*this); service_manager = std::make_unique(*this); archive_manager = std::make_unique(*this); diff --git a/src/core/core.h b/src/core/core.h index 3b48912d1..f73be6524 100644 --- a/src/core/core.h +++ b/src/core/core.h @@ -32,7 +32,7 @@ namespace AudioCore { class DspInterface; } -namespace RPC { +namespace Core::RPC { class RPCServer; } diff --git a/src/core/rpc/packet.cpp b/src/core/rpc/packet.cpp index 8ad0d0524..ed8b2bcb7 100644 --- a/src/core/rpc/packet.cpp +++ b/src/core/rpc/packet.cpp @@ -1,15 +1,19 @@ +// Copyright 2019 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include #include - #include "core/rpc/packet.h" -namespace RPC { - -Packet::Packet(const PacketHeader& header, u8* data, - std::function 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 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 diff --git a/src/core/rpc/packet.h b/src/core/rpc/packet.h index 6f34f5c0b..c68200834 100644 --- a/src/core/rpc/packet.h +++ b/src/core/rpc/packet.h @@ -9,12 +9,12 @@ #include #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 send_reply_callback); + explicit Packet(const PacketHeader& header, u8* data, + std::function send_reply_callback); + ~Packet(); u32 GetVersion() const { return header.version; @@ -54,7 +56,7 @@ public: return header; } - std::array& GetPacketData() { + std::span GetPacketData() { return packet_data; } @@ -76,4 +78,4 @@ private: std::function send_reply_callback; }; -} // namespace RPC +} // namespace Core::RPC diff --git a/src/core/rpc/rpc_server.cpp b/src/core/rpc/rpc_server.cpp index 04888b51e..b9114be82 100644 --- a/src/core/rpc/rpc_server.cpp +++ b/src/core/rpc/rpc_server.cpp @@ -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= 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 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 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 request_packet) { } } -void RPCServer::HandleRequestsLoop() { +void RPCServer::HandleRequestsLoop(std::stop_token stop_token) { std::unique_ptr 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 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 diff --git a/src/core/rpc/rpc_server.h b/src/core/rpc/rpc_server.h index 2c821f02b..04b4371c9 100644 --- a/src/core/rpc/rpc_server.h +++ b/src/core/rpc/rpc_server.h @@ -6,36 +6,39 @@ #include #include -#include #include -#include +#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 request); private: - void Start(); - void Stop(); void HandleReadMemory(Packet& packet, u32 address, u32 data_size); void HandleWriteMemory(Packet& packet, u32 address, std::span data); bool ValidatePacket(const PacketHeader& packet_header); void HandleSingleRequest(std::unique_ptr request); - void HandleRequestsLoop(); + void HandleRequestsLoop(std::stop_token stop_token); +private: + Core::System& system; Server server; - Common::SPSCQueue> request_queue; - std::thread request_handler_thread; + Common::SPSCQueue, true> request_queue; + std::jthread request_handler_thread; }; -} // namespace RPC +} // namespace Core::RPC diff --git a/src/core/rpc/server.cpp b/src/core/rpc/server.cpp index abf4b7e4a..ed93dac04 100644 --- a/src/core/rpc/server.cpp +++ b/src/core/rpc/server.cpp @@ -1,17 +1,16 @@ +// Copyright 2019 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + #include -#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 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 new_request) { rpc_server.QueueRequest(std::move(new_request)); } -}; // namespace RPC +}; // namespace Core::RPC diff --git a/src/core/rpc/server.h b/src/core/rpc/server.h index c9f27cd5c..46028e99b 100644 --- a/src/core/rpc/server.h +++ b/src/core/rpc/server.h @@ -6,7 +6,7 @@ #include -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 new_request); private: @@ -25,4 +24,4 @@ private: std::unique_ptr udp_server; }; -} // namespace RPC +} // namespace Core::RPC diff --git a/src/core/rpc/udp_server.cpp b/src/core/rpc/udp_server.cpp index f69e72354..291339962 100644 --- a/src/core/rpc/udp_server.cpp +++ b/src/core/rpc/udp_server.cpp @@ -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)> new_request_ca UDPServer::~UDPServer() = default; -} // namespace RPC +} // namespace Core::RPC diff --git a/src/core/rpc/udp_server.h b/src/core/rpc/udp_server.h index f4ff2ad62..b979649d3 100644 --- a/src/core/rpc/udp_server.h +++ b/src/core/rpc/udp_server.h @@ -7,7 +7,7 @@ #include #include -namespace RPC { +namespace Core::RPC { class Packet; @@ -21,4 +21,4 @@ private: std::unique_ptr impl; }; -} // namespace RPC +} // namespace Core::RPC