diff options
author | Yann Ylavic <ylavic@apache.org> | 2024-06-21 17:38:47 +0200 |
---|---|---|
committer | Yann Ylavic <ylavic@apache.org> | 2024-06-21 17:38:47 +0200 |
commit | b40ccd9ab2fa0e8148b39dee7e44fd5f3f4c515b (patch) | |
tree | 1aafc98be07fd8b395ed94cda24e3f832e71f5d7 /server/mpm/event/event.c | |
parent | mpm_event: Follow up to r1918482: CONN_STATE_ASYNC_WAITIO > CONN_STATE_LINGER. (diff) | |
download | apache2-b40ccd9ab2fa0e8148b39dee7e44fd5f3f4c515b.tar.xz apache2-b40ccd9ab2fa0e8148b39dee7e44fd5f3f4c515b.zip |
mpm_event: Follow up to r1918482: CONN_STATE_LINGER* are not the last anymore.
Since CONN_STATE_ASYNC_WAITIO, we cannot check for < or >= CONN_STATE_LINGER
anymore to determine if in an lingering close state, so let's add a new
CONN_STATE_IS_LINGERING_CLOSE() macro for this and use it in mpm_event.
The test for state == CONN_STATE_LINGER in process_lingering_close() is a
bit weak too in order to call ap_start_lingering_close() the first time only,
so have a conn_state->linger_started flag instead.
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1918491 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server/mpm/event/event.c')
-rw-r--r-- | server/mpm/event/event.c | 23 |
1 files changed, 15 insertions, 8 deletions
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index 0e6ce8a2ee..403f9a3c93 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -152,6 +152,8 @@ #define apr_time_from_msec(x) (x * 1000) #endif +#define CONN_STATE_IS_LINGERING_CLOSE(s) ((s) >= CONN_STATE_LINGER && \ + (s) <= CONN_STATE_LINGER_SHORT) #ifndef MAX_SECS_TO_LINGER #define MAX_SECS_TO_LINGER 30 #endif @@ -252,8 +254,11 @@ struct event_conn_state_t { conn_state_t pub; /** chaining in defer_linger_chain */ struct event_conn_state_t *chain; - /** Is lingering close from defer_lingering_close()? */ - int deferred_linger; + unsigned int + /** Is lingering close from defer_lingering_close()? */ + deferred_linger :1, + /** Has ap_start_lingering_close() been called? */ + linger_started :1; }; APR_RING_HEAD(timeout_head_t, event_conn_state_t); @@ -933,7 +938,7 @@ static void close_connection(event_conn_state_t *cs) */ static int shutdown_connection(event_conn_state_t *cs) { - if (cs->pub.state < CONN_STATE_LINGER) { + if (!CONN_STATE_IS_LINGERING_CLOSE(cs->pub.state)) { apr_table_setn(cs->c->notes, "short-lingering-close", "1"); defer_lingering_close(cs); } @@ -1114,7 +1119,7 @@ static void process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * soc c->id = conn_id; } - if (cs->pub.state >= CONN_STATE_LINGER) { + if (CONN_STATE_IS_LINGERING_CLOSE(cs->pub.state)) { goto lingering_close; } @@ -1349,7 +1354,7 @@ static apr_status_t event_resume_suspended (conn_rec *c) apr_atomic_dec32(&suspended_count); c->suspended_baton = NULL; - if (cs->pub.state < CONN_STATE_LINGER) { + if (!CONN_STATE_IS_LINGERING_CLOSE(cs->pub.state)) { cs->queue_timestamp = apr_time_now(); notify_suspend(cs); @@ -1362,7 +1367,6 @@ static apr_status_t event_resume_suspended (conn_rec *c) apr_thread_mutex_unlock(timeout_mutex); } else { - cs->pub.state = CONN_STATE_LINGER; process_lingering_close(cs); } @@ -1769,9 +1773,12 @@ static void process_lingering_close(event_conn_state_t *cs) ap_log_cerror(APLOG_MARK, APLOG_TRACE6, 0, cs->c, "lingering close from state %i", (int)cs->pub.state); - AP_DEBUG_ASSERT(cs->pub.state >= CONN_STATE_LINGER); + AP_DEBUG_ASSERT(CONN_STATE_IS_LINGERING_CLOSE(cs->pub.state)); + + if (!cs->linger_started) { + cs->pub.state = CONN_STATE_LINGER; + cs->linger_started = 1; - if (cs->pub.state == CONN_STATE_LINGER) { /* defer_lingering_close() may have bumped lingering_count already */ if (!cs->deferred_linger) { apr_atomic_inc32(&lingering_count); |