diff options
Diffstat (limited to 'server')
-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); |