mirror of
				https://github.com/PabloMK7/citra.git
				synced 2025-10-31 05:40:04 +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…
	
	Add table
		Add a link
		
	
		Reference in a new issue