Implement shutting down the write-side only

This commit is contained in:
2025-09-15 15:39:28 -04:00
parent 6b52c4289c
commit 55f6ebc02b
4 changed files with 37 additions and 21 deletions

View File

@@ -89,7 +89,7 @@ void Connection::close() {
// Called from I/O thread only
void Connection::append_bytes(std::span<std::string_view> data_parts,
Arena arena, bool close_after_send) {
Arena arena, ConnectionShutdown shutdown_mode) {
// Calculate total bytes for this message. Don't need to hold the lock yet.
size_t total_bytes = 0;
for (const auto &part : data_parts) {
@@ -98,17 +98,17 @@ void Connection::append_bytes(std::span<std::string_view> data_parts,
std::unique_lock lock(mutex_);
// Prevent queueing messages after close has been requested
if (close_requested_) {
// Prevent queueing messages after shutdown has been requested
if (shutdown_requested_ != ConnectionShutdown::None) {
return;
}
// Check if queue was empty to determine if we need to enable EPOLLOUT
bool was_empty = message_queue_.empty();
// Set close_requested flag if this message requests close
if (close_after_send) {
close_requested_ = true;
// Set shutdown mode if requested
if (shutdown_mode != ConnectionShutdown::None) {
shutdown_requested_ = shutdown_mode;
}
// Add message to queue
@@ -137,8 +137,8 @@ void Connection::send_response(void *protocol_context,
std::string_view response_json, Arena arena) {
std::unique_lock lock(mutex_);
// Prevent queueing responses after close has been requested
if (close_requested_) {
// Prevent queueing responses after shutdown has been requested
if (shutdown_requested_ != ConnectionShutdown::None) {
return;
}
@@ -307,7 +307,11 @@ uint32_t Connection::write_bytes() {
// sets it and we would hang.
epoll_ctl(server->epoll_fds_[epoll_index_], EPOLL_CTL_MOD, fd_, &event);
}
if (close_requested_) {
// Handle shutdown modes after all messages are sent
if (shutdown_requested_ == ConnectionShutdown::WriteOnly) {
// Shutdown write side but keep connection alive for reading
shutdown(fd_, SHUT_WR);
} else if (shutdown_requested_ == ConnectionShutdown::Full) {
result |= Close;
}
}