From cf76d5b4dc766749ba0db0bc33413ae745c678c5 Mon Sep 17 00:00:00 2001 From: momo5502 Date: Fri, 17 Jan 2025 18:02:35 +0100 Subject: [PATCH] Extract connection handling --- src/gdb-stub/connection_handler.cpp | 59 ++++++++++++++++++++++++++++ src/gdb-stub/connection_handler.hpp | 21 ++++++++++ src/gdb-stub/gdb_stub.cpp | 60 ++++++++++------------------- 3 files changed, 100 insertions(+), 40 deletions(-) create mode 100644 src/gdb-stub/connection_handler.cpp create mode 100644 src/gdb-stub/connection_handler.hpp diff --git a/src/gdb-stub/connection_handler.cpp b/src/gdb-stub/connection_handler.cpp new file mode 100644 index 00000000..664ef59f --- /dev/null +++ b/src/gdb-stub/connection_handler.cpp @@ -0,0 +1,59 @@ +#include "connection_handler.hpp" +#include "checksum.hpp" + +#include + +using namespace std::literals; + +namespace gdb_stub +{ + namespace + { + bool read_from_socket(stream_processor& processor, network::tcp_client_socket& client) + { + const auto data = client.receive(); + if (!data) + { + return false; + } + + processor.push_stream_data(*data); + return true; + } + } + + connection_handler::connection_handler(network::tcp_client_socket& client) + : client_(client) + { + this->client_.set_blocking(false); + } + + std::optional connection_handler::get_packet() + { + while (this->client_.is_valid() && !this->processor_.has_packet()) + { + if (!read_from_socket(this->processor_, this->client_)) + { + std::this_thread::sleep_for(100ms); + } + } + + if (this->processor_.has_packet()) + { + return this->processor_.get_next_packet(); + } + + return std::nullopt; + } + + void connection_handler::send_packet(const std::string_view data) const + { + const auto checksum = compute_checksum_as_string(data); + this->send_raw_data("$" + std::string(data) + "#" + checksum); + } + + void connection_handler::send_raw_data(const std::string_view data) const + { + (void)this->client_.send(data); + } +} diff --git a/src/gdb-stub/connection_handler.hpp b/src/gdb-stub/connection_handler.hpp new file mode 100644 index 00000000..1e9c2f9e --- /dev/null +++ b/src/gdb-stub/connection_handler.hpp @@ -0,0 +1,21 @@ +#pragma once +#include "stream_processor.hpp" +#include + +namespace gdb_stub +{ + class connection_handler + { + public: + connection_handler(network::tcp_client_socket& client); + + std::optional get_packet(); + + void send_packet(std::string_view data) const; + void send_raw_data(std::string_view data) const; + + private: + network::tcp_client_socket& client_; + stream_processor processor_{}; + }; +} diff --git a/src/gdb-stub/gdb_stub.cpp b/src/gdb-stub/gdb_stub.cpp index 4647ec64..38040ead 100644 --- a/src/gdb-stub/gdb_stub.cpp +++ b/src/gdb-stub/gdb_stub.cpp @@ -2,9 +2,9 @@ #include -#include "stream_processor.hpp" -#include "async_handler.hpp" #include "checksum.hpp" +#include "async_handler.hpp" +#include "connection_handler.hpp" using namespace std::literals; @@ -20,12 +20,6 @@ namespace gdb_stub step, }; - bool send_packet_reply(const network::tcp_client_socket& socket, const std::string_view data) - { - const auto checksum = compute_checksum_as_string(data); - return socket.send("$" + std::string(data) + "#" + checksum); - } - network::tcp_client_socket accept_client(const network::address& bind_address) { network::tcp_server_socket server{bind_address.get_family()}; @@ -37,19 +31,7 @@ namespace gdb_stub return server.accept(); } - void read_from_socket(stream_processor& processor, network::tcp_client_socket& client) - { - while (client.is_ready(true)) - { - const auto data = client.receive(); - if (data) - { - processor.push_stream_data(*data); - } - } - } - - void process_query(const network::tcp_client_socket& client, const std::string_view payload) + void process_query(const connection_handler& connection, const std::string_view payload) { auto name = payload; std::string_view args{}; @@ -64,11 +46,11 @@ namespace gdb_stub if (name == "Supported") { - send_packet_reply(client, "PacketSize=1024;qXfer:features:read+"); + connection.send_packet("PacketSize=1024;qXfer:features:read+"); } else if (name == "Attached") { - send_packet_reply(client, "1"); + connection.send_packet("1"); } else if (name == "Xfer") { @@ -76,15 +58,15 @@ namespace gdb_stub } else if (name == "Symbol") { - send_packet_reply(client, "OK"); + connection.send_packet("OK"); } else { - send_packet_reply(client, {}); + connection.send_packet({}); } } - continuation_event handle_command(const network::tcp_client_socket& client, const uint8_t command, + continuation_event handle_command(const connection_handler& connection, const uint8_t command, const std::string_view data) { auto event = continuation_event::none; @@ -92,20 +74,20 @@ namespace gdb_stub switch (command) { case 'q': - process_query(client, data); + process_query(connection, data); break; default: - send_packet_reply(client, {}); + connection.send_packet({}); break; } return event; } - void process_packet(const network::tcp_client_socket& client, const std::string_view packet) + void process_packet(const connection_handler& connection, const std::string_view packet) { - (void)client.send("+"); + (void)connection.send_raw_data("+"); if (packet.empty()) { @@ -113,7 +95,7 @@ namespace gdb_stub } const auto command = packet.front(); - const auto event = handle_command(client, command, packet.substr(1)); + const auto event = handle_command(connection, command, packet.substr(1)); (void)event; } @@ -125,8 +107,6 @@ namespace gdb_stub bool run_gdb_stub(const network::address& bind_address, gdb_stub_handler& handler) { - stream_processor processor{}; - auto client = accept_client(bind_address); if (!client) { @@ -148,17 +128,17 @@ namespace gdb_stub } }}; - client.set_blocking(false); + connection_handler connection{client}; - while (client.is_valid()) + while (true) { - read_from_socket(processor, client); - - while (processor.has_packet()) + const auto packet = connection.get_packet(); + if (!packet) { - const auto packet = processor.get_next_packet(); - process_packet(client, packet); + break; } + + process_packet(connection, *packet); } return true;