summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2024-06-21 17:38:47 +0200
committerYann Ylavic <ylavic@apache.org>2024-06-21 17:38:47 +0200
commitb40ccd9ab2fa0e8148b39dee7e44fd5f3f4c515b (patch)
tree1aafc98be07fd8b395ed94cda24e3f832e71f5d7 /server
parentmpm_event: Follow up to r1918482: CONN_STATE_ASYNC_WAITIO > CONN_STATE_LINGER. (diff)
downloadapache2-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')
-rw-r--r--server/mpm/event/event.c23
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);