From 4e656f53545ceb8b809a91283eb12e332826ca1d Mon Sep 17 00:00:00 2001 From: Glenn Strauss Date: Mon, 3 Aug 2020 12:05:27 -0400 Subject: [PATCH] [core] connection_set_fdevent_interest() extracted from connection_state_machine() (for reuse) include interest for POLLRDHUP unless already received --- src/connections.c | 103 +++++++++++++++++++++++----------------------- 1 file changed, 52 insertions(+), 51 deletions(-) diff --git a/src/connections.c b/src/connections.c index 634808c3..30bbf2cf 100644 --- a/src/connections.c +++ b/src/connections.c @@ -1436,6 +1436,57 @@ connection_state_machine_loop (request_st * const r, connection * const con) } +static void +connection_set_fdevent_interest (request_st * const r, connection * const con) +{ + if (con->fd < 0) return; + + int n = 0; + switch(r->state) { + case CON_STATE_READ: + n = FDEVENT_IN | FDEVENT_RDHUP; + break; + case CON_STATE_WRITE: + if (!chunkqueue_is_empty(con->write_queue) + && 0 == con->is_writable && 0 == con->traffic_limit_reached) + n |= FDEVENT_OUT; + __attribute_fallthrough__ + case CON_STATE_READ_POST: + if (r->conf.stream_request_body & FDEVENT_STREAM_REQUEST_POLLIN) + n |= FDEVENT_IN; + if (!(r->conf.stream_request_body & FDEVENT_STREAM_REQUEST_POLLRDHUP)) + n |= FDEVENT_RDHUP; + break; + case CON_STATE_CLOSE: + n = FDEVENT_IN; + break; + default: + break; + } + + const int events = fdevent_fdnode_interest(con->fdn); + if (con->is_readable < 0) { + con->is_readable = 0; + n |= FDEVENT_IN; + } + if (con->is_writable < 0) { + con->is_writable = 0; + n |= FDEVENT_OUT; + } + if (events & FDEVENT_RDHUP) + n |= FDEVENT_RDHUP; + + if (n == events) return; + + /* update timestamps when enabling interest in events */ + if ((n & FDEVENT_IN) && !(events & FDEVENT_IN)) + con->read_idle_ts = log_epoch_secs; + if ((n & FDEVENT_OUT) && !(events & FDEVENT_OUT)) + con->write_request_ts = log_epoch_secs; + fdevent_fdnode_event_set(con->srv->ev, con->fdn, n); +} + + void connection_state_machine(connection *con) { request_st * const r = &con->request; const int log_state_handling = r->conf.log_state_handling; @@ -1452,57 +1503,7 @@ void connection_state_machine(connection *con) { "state at exit: %d %s", con->fd, connection_get_state(r->state)); } - int rc = 0; - switch(r->state) { - case CON_STATE_READ: - rc = FDEVENT_IN | FDEVENT_RDHUP; - break; - case CON_STATE_WRITE: - /* request write-fdevent only if we really need it - * - if we have data to write - * - if the socket is not writable yet - */ - if (!chunkqueue_is_empty(con->write_queue) && - (con->is_writable == 0) && - (con->traffic_limit_reached == 0)) { - rc |= FDEVENT_OUT; - } - /* fall through */ - case CON_STATE_READ_POST: - if (r->conf.stream_request_body & FDEVENT_STREAM_REQUEST_POLLIN) { - rc |= FDEVENT_IN | FDEVENT_RDHUP; - } - break; - case CON_STATE_CLOSE: - rc = FDEVENT_IN; - break; - default: - break; - } - if (con->fd >= 0) { - const int events = fdevent_fdnode_interest(con->fdn); - if (con->is_readable < 0) { - con->is_readable = 0; - rc |= FDEVENT_IN; - } - if (con->is_writable < 0) { - con->is_writable = 0; - rc |= FDEVENT_OUT; - } - if (events & FDEVENT_RDHUP) { - rc |= FDEVENT_RDHUP; - } - if (rc != events) { - /* update timestamps when enabling interest in events */ - if ((rc & FDEVENT_IN) && !(events & FDEVENT_IN)) { - con->read_idle_ts = log_epoch_secs; - } - if ((rc & FDEVENT_OUT) && !(events & FDEVENT_OUT)) { - con->write_request_ts = log_epoch_secs; - } - fdevent_fdnode_event_set(con->srv->ev, con->fdn, rc); - } - } + connection_set_fdevent_interest(r, con); } static void connection_check_timeout (connection * const con, const time_t cur_ts) {