From a427278cc03b14619afaf62b4ab44c3d3e8d1377 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Fri, 17 Jul 2026 15:39:56 -0400 Subject: [PATCH] Read until EAGAIN To prepare for EPOLLET --- src/connection.cpp | 2 +- src/connection.hpp | 2 +- src/server.cpp | 35 ++++++++++++++++++++++------------- 3 files changed, 24 insertions(+), 15 deletions(-) diff --git a/src/connection.cpp b/src/connection.cpp index fe092e0..1213e87 100644 --- a/src/connection.cpp +++ b/src/connection.cpp @@ -153,7 +153,7 @@ void Connection::send_response(ProtocolHandle handle, } } -int Connection::readBytes(char *buf, size_t buffer_size) { +int Connection::read_bytes(char *buf, size_t buffer_size) { int r; for (;;) { r = read(fd_, buf, buffer_size); diff --git a/src/connection.hpp b/src/connection.hpp index 81903ff..6cb3ab4 100644 --- a/src/connection.hpp +++ b/src/connection.hpp @@ -279,7 +279,7 @@ private: friend Ref make_ref(Args &&...args); // Networking interface - only accessible by Server - int readBytes(char *buf, size_t buffer_size); + int read_bytes(char *buf, size_t buffer_size); enum WriteBytesResult { Error = 1 << 0, Progress = 1 << 1, diff --git a/src/server.cpp b/src/server.cpp index ab0036e..657fb58 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -409,21 +409,30 @@ void Server::process_connection_reads(Ref &conn, int events) { auto buf_size = config_.server.read_buffer_size; g_read_buffer.resize(buf_size); char *buf = g_read_buffer.data(); - int r = conn->readBytes(buf, buf_size); - if (r < 0) { - // Error or EOF - connection should be closed - close_connection(conn); - return; + // Once we do EPOLLET we must drain the socket until read returns EAGAIN. + for (;;) { + int r = conn->read_bytes(buf, buf_size); + + if (r < 0) { + // Error or EOF - connection should be closed + close_connection(conn); + return; + } + + if (r == 0) { + // No data available (EAGAIN) - read side drained + return; + } + + // Call handler with connection reference - server retains ownership. + handler_.on_data_arrived(std::string_view{buf, size_t(r)}, *conn); + + // The connection may have been closed by the handler; stop reading. + if (!conn) { + return; + } } - - if (r == 0) { - // No data available (EAGAIN) - skip read processing but continue - return; - } - - // Call handler with connection reference - server retains ownership - handler_.on_data_arrived(std::string_view{buf, size_t(r)}, *conn); } }