From 58f5fe7d79cd7d23c8c3bcfc037cac35d7906dd8 Mon Sep 17 00:00:00 2001 From: Timothy Flynn Date: Sat, 9 Aug 2025 13:04:48 -0400 Subject: [PATCH] RequestServer: Add an IPC method to reconnect N request clients Similar to the same IPC on ImageDecoder, this just avoids IPC churn. --- .../RequestServer/ConnectionFromClient.cpp | 45 ++++++++++++++----- Services/RequestServer/ConnectionFromClient.h | 4 ++ Services/RequestServer/RequestServer.ipc | 1 + 3 files changed, 40 insertions(+), 10 deletions(-) diff --git a/Services/RequestServer/ConnectionFromClient.cpp b/Services/RequestServer/ConnectionFromClient.cpp index 730182af504..bb1ea39088d 100644 --- a/Services/RequestServer/ConnectionFromClient.cpp +++ b/Services/RequestServer/ConnectionFromClient.cpp @@ -365,25 +365,50 @@ Messages::RequestServer::InitTransportResponse ConnectionFromClient::init_transp } Messages::RequestServer::ConnectNewClientResponse ConnectionFromClient::connect_new_client() +{ + auto client_socket = create_client_socket(); + if (client_socket.is_error()) { + dbgln("Failed to create client socket: {}", client_socket.error()); + return IPC::File {}; + } + + return client_socket.release_value(); +} + +Messages::RequestServer::ConnectNewClientsResponse ConnectionFromClient::connect_new_clients(size_t count) +{ + Vector files; + files.ensure_capacity(count); + + for (size_t i = 0; i < count; ++i) { + auto client_socket = create_client_socket(); + if (client_socket.is_error()) { + dbgln("Failed to create client socket: {}", client_socket.error()); + return Vector {}; + } + + files.unchecked_append(client_socket.release_value()); + } + + return files; +} + +ErrorOr ConnectionFromClient::create_client_socket() { // TODO: Mach IPC int socket_fds[2] {}; - if (auto err = Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds); err.is_error()) { - dbgln("Failed to create client socketpair: {}", err.error()); - return IPC::File {}; - } + TRY(Core::System::socketpair(AF_LOCAL, SOCK_STREAM, 0, socket_fds)); - auto client_socket_or_error = Core::LocalSocket::adopt_fd(socket_fds[0]); - if (client_socket_or_error.is_error()) { + auto client_socket = Core::LocalSocket::adopt_fd(socket_fds[0]); + if (client_socket.is_error()) { close(socket_fds[0]); close(socket_fds[1]); - dbgln("Failed to adopt client socket: {}", client_socket_or_error.error()); - return IPC::File {}; + return client_socket.release_error(); } - auto client_socket = client_socket_or_error.release_value(); + // Note: A ref is stored in the static s_connections map - auto client = adopt_ref(*new ConnectionFromClient(make(move(client_socket)))); + auto client = adopt_ref(*new ConnectionFromClient(make(client_socket.release_value()))); return IPC::File::adopt_fd(socket_fds[1]); } diff --git a/Services/RequestServer/ConnectionFromClient.h b/Services/RequestServer/ConnectionFromClient.h index bd9a8cfd24a..0a6baaa1618 100644 --- a/Services/RequestServer/ConnectionFromClient.h +++ b/Services/RequestServer/ConnectionFromClient.h @@ -39,6 +39,8 @@ private: virtual Messages::RequestServer::InitTransportResponse init_transport(int peer_pid) override; virtual Messages::RequestServer::ConnectNewClientResponse connect_new_client() override; + virtual Messages::RequestServer::ConnectNewClientsResponse connect_new_clients(size_t count) override; + virtual Messages::RequestServer::IsSupportedProtocolResponse is_supported_protocol(ByteString) override; virtual void set_dns_server(ByteString host_or_address, u16 port, bool use_tls, bool validate_dnssec_locally) override; virtual void set_use_system_dns() override; @@ -57,6 +59,8 @@ private: struct ActiveRequest; friend struct ActiveRequest; + static ErrorOr create_client_socket(); + static int on_socket_callback(void*, int sockfd, int what, void* user_data, void*); static int on_timeout_callback(void*, long timeout_ms, void* user_data); static size_t on_header_received(void* buffer, size_t size, size_t nmemb, void* user_data); diff --git a/Services/RequestServer/RequestServer.ipc b/Services/RequestServer/RequestServer.ipc index 98dfa31f79c..ea4979d66b4 100644 --- a/Services/RequestServer/RequestServer.ipc +++ b/Services/RequestServer/RequestServer.ipc @@ -7,6 +7,7 @@ endpoint RequestServer { init_transport(int peer_pid) => (int peer_pid) connect_new_client() => (IPC::File client_socket) + connect_new_clients(size_t count) => (Vector sockets) // use_tls: enable DNS over TLS set_dns_server(ByteString host_or_address, u16 port, bool use_tls, bool validate_dnssec_locally) =|