More cleanup
This commit is contained in:
@@ -45,8 +45,7 @@ Connection::Connection(struct sockaddr_storage addr, int fd, int64_t id,
|
||||
: fd_(fd), id_(id), epoll_index_(epoll_index), addr_(addr),
|
||||
handler_(handler), server_(std::move(server)) {
|
||||
auto server_ref = server_.lock();
|
||||
// This should only be called from a member of Server itself, so I should
|
||||
// hope it's alive.
|
||||
// Should only be called from the io thread
|
||||
assert(server_ref);
|
||||
server_ref->active_connections_.fetch_add(1, std::memory_order_relaxed);
|
||||
|
||||
@@ -96,19 +95,23 @@ void Connection::append_message(std::span<std::string_view> data_parts,
|
||||
bool was_empty = message_queue_.empty();
|
||||
|
||||
// Add message to queue
|
||||
// TODO this allocates while holding the connection lock
|
||||
message_queue_.emplace_back(
|
||||
Message{std::move(arena), data_parts, close_after_send});
|
||||
outgoing_bytes_queued_ += total_bytes;
|
||||
|
||||
// If queue was empty, we need to add EPOLLOUT interest.
|
||||
if (was_empty && fd_ >= 0) {
|
||||
if (was_empty) {
|
||||
auto server = server_.lock();
|
||||
if (server) {
|
||||
if (fd_ >= 0 && server) {
|
||||
// Add EPOLLOUT interest - pipeline thread manages epoll
|
||||
struct epoll_event event;
|
||||
event.data.fd = fd_;
|
||||
event.events = EPOLLIN | EPOLLOUT;
|
||||
tsan_release();
|
||||
// I think we have to call epoll_ctl while holding mutex_. Otherwise a
|
||||
// call that clears the write interest could get reordered with one that
|
||||
// sets it and we would hang.
|
||||
epoll_ctl(server->epoll_fds_[epoll_index_], EPOLL_CTL_MOD, fd_, &event);
|
||||
}
|
||||
}
|
||||
@@ -133,9 +136,8 @@ int Connection::readBytes(char *buf, size_t buffer_size) {
|
||||
}
|
||||
|
||||
// Increment bytes read metric
|
||||
if (r > 0) {
|
||||
bytes_read.inc(r);
|
||||
}
|
||||
assert(r > 0);
|
||||
bytes_read.inc(r);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -196,9 +198,7 @@ uint32_t Connection::write_bytes() {
|
||||
if (errno == EAGAIN) {
|
||||
// Increment EAGAIN failure metric
|
||||
write_eagain_failures.inc();
|
||||
if (total_bytes_written > 0) {
|
||||
bytes_written.inc(total_bytes_written);
|
||||
}
|
||||
bytes_written.inc(total_bytes_written);
|
||||
return result;
|
||||
}
|
||||
perror("sendmsg");
|
||||
@@ -221,7 +221,6 @@ uint32_t Connection::write_bytes() {
|
||||
|
||||
while (bytes_remaining > 0 && !message_queue_.empty()) {
|
||||
auto &front_message = message_queue_.front();
|
||||
bool message_complete = true;
|
||||
|
||||
for (auto &part : front_message.data_parts) {
|
||||
if (part.empty())
|
||||
@@ -236,22 +235,17 @@ uint32_t Connection::write_bytes() {
|
||||
part = std::string_view(part.data() + bytes_remaining,
|
||||
part.size() - bytes_remaining);
|
||||
bytes_remaining = 0;
|
||||
message_complete = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (message_complete) {
|
||||
if (front_message.close_after_send) {
|
||||
result |= Close;
|
||||
}
|
||||
// Move arena to thread-local vector for deferred cleanup
|
||||
g_arenas_to_free.emplace_back(std::move(front_message.arena));
|
||||
message_queue_.pop_front();
|
||||
if (result & Close) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (front_message.close_after_send) {
|
||||
result |= Close;
|
||||
}
|
||||
// Move arena to thread-local vector for deferred cleanup
|
||||
g_arenas_to_free.emplace_back(std::move(front_message.arena));
|
||||
message_queue_.pop_front();
|
||||
if (result & Close) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -269,18 +263,19 @@ uint32_t Connection::write_bytes() {
|
||||
event.data.fd = fd_;
|
||||
event.events = EPOLLIN; // Remove EPOLLOUT
|
||||
tsan_release();
|
||||
// I think we have to call epoll_ctl while holding mutex_. Otherwise a
|
||||
// call that clears the write interest could get reordered with one that
|
||||
// sets it and we would hang.
|
||||
epoll_ctl(server->epoll_fds_[epoll_index_], EPOLL_CTL_MOD, fd_, &event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Increment bytes written metric
|
||||
if (total_bytes_written > 0) {
|
||||
bytes_written.inc(total_bytes_written);
|
||||
}
|
||||
bytes_written.inc(total_bytes_written);
|
||||
|
||||
// Clean up arenas after all mutex operations are complete
|
||||
// This avoids holding the connection mutex while free() potentially contends
|
||||
// This avoids holding the connection mutex while calling free()
|
||||
g_arenas_to_free.clear();
|
||||
|
||||
return result;
|
||||
|
||||
Reference in New Issue
Block a user