Implement shutting down the write-side only
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user