From: Rainer Jung Date: Sat, 4 Aug 2012 21:30:11 +0000 (+0000) Subject: MPM event: X-Git-Tag: 2.4.3~119 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=606cd1761757e511a7892b9303f7619596fe52b0;p=apache MPM event: - Keep track of the number of clogged, lingering, and suspended connections. - Don't count connections in lingering close state when calculating how many additional connections may be accepted Backport of r1361773 and r 1361778 from trunk. Submitted by: sf Reviewed by: rjung, jim Backported by: rjung git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1369473 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 2d7102df1a..b611310093 100644 --- a/CHANGES +++ b/CHANGES @@ -7,6 +7,10 @@ Changes with Apache 2.4.3 possible XSS for a site where untrusted users can upload files to a location with MultiViews enabled. [Niels Heinen ] + *) mpm_event: Don't count connections in lingering close state when + calculating how many additional connections may be accepted. + [Stefan Fritsch] + *) mod_ssl: If exiting during initialization because of a fatal error, log a message to the main error log pointing to the appropriate virtual host error log. [Stefan Fritsch] diff --git a/STATUS b/STATUS index bee2f487e8..74e72ddc1e 100644 --- a/STATUS +++ b/STATUS @@ -88,14 +88,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * event: Keep track of the number of clogged, lingering, and suspended connections. - Don't count connections in lingering close state when calculating - how many additional connections may be accepted - trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1361773 and - trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1361778 - 2.4.x patch: Trunk patch applies. - +1: rjung, jim, sf - * mod_lua: resync 2.4.x with sf's refactoring/fixes in trunk (and Covener's notes) trunk patch: http://svn.apache.org/viewvc?view=revision&revision=1201460 http://svn.apache.org/viewvc?view=revision&revision=1351012 diff --git a/docs/manual/mod/event.xml b/docs/manual/mod/event.xml index 81275a3a75..c27136058d 100644 --- a/docs/manual/mod/event.xml +++ b/docs/manual/mod/event.xml @@ -166,7 +166,8 @@ of consuming threads only for connections with active processing

This directive can be used to fine-tune the per-process connection limit. A process will only accept new connections if the current number of - connections is lower than:

+ connections (not counting connections in the "closing" state) is lower + than:

ThreadsPerChild + diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index ddeb0aac86..fa724688c3 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -175,6 +175,9 @@ static int num_listensocks = 0; static apr_int32_t conns_this_child; /* MaxConnectionsPerChild, only access in listener thread */ static apr_uint32_t connection_count = 0; /* Number of open connections */ +static apr_uint32_t lingering_count = 0; /* Number of connections in lingering close */ +static apr_uint32_t suspended_count = 0; /* Number of suspended connections */ +static apr_uint32_t clogged_count = 0; /* Number of threads processing ssl conns */ static int resource_shortage = 0; static fd_queue_t *worker_queue; static fd_queue_info_t *worker_queue_info; @@ -374,8 +377,12 @@ static void enable_listensocks(int process_slot) int i; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00457) "Accepting new connections again: " - "%u active conns, %u idle workers", + "%u active conns (%u lingering/%u clogged/%u suspended), " + "%u idle workers", apr_atomic_read32(&connection_count), + apr_atomic_read32(&lingering_count), + apr_atomic_read32(&clogged_count), + apr_atomic_read32(&suspended_count), ap_queue_info_get_idlers(worker_queue_info)); for (i = 0; i < num_listensocks; i++) apr_pollset_add(event_pollset, &listener_pollfd[i]); @@ -589,7 +596,20 @@ static int child_fatal; static int volatile shutdown_pending; static int volatile restart_pending; -static apr_status_t decrement_connection_count(void *dummy) { +static apr_status_t decrement_connection_count(void *cs_) +{ + event_conn_state_t *cs = cs_; + switch (cs->pub.state) { + case CONN_STATE_LINGER_NORMAL: + case CONN_STATE_LINGER_SHORT: + apr_atomic_dec32(&lingering_count); + break; + case CONN_STATE_SUSPENDED: + apr_atomic_dec32(&suspended_count); + break; + default: + break; + } apr_atomic_dec32(&connection_count); return APR_SUCCESS; } @@ -767,6 +787,7 @@ static int start_lingering_close_common(event_conn_state_t *cs) q = &linger_q; cs->pub.state = CONN_STATE_LINGER_NORMAL; } + apr_atomic_inc32(&lingering_count); apr_thread_mutex_lock(timeout_mutex); TO_QUEUE_APPEND(*q, cs); cs->pfd.reqevents = APR_POLLIN | APR_POLLHUP | APR_POLLERR; @@ -879,7 +900,8 @@ static void process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * soc return; } apr_atomic_inc32(&connection_count); - apr_pool_cleanup_register(c->pool, NULL, decrement_connection_count, apr_pool_cleanup_null); + apr_pool_cleanup_register(c->pool, cs, decrement_connection_count, + apr_pool_cleanup_null); c->current_thread = thd; cs->c = c; c->cs = &(cs->pub); @@ -928,10 +950,12 @@ static void process_socket(apr_thread_t *thd, apr_pool_t * p, apr_socket_t * soc * like mod_ssl, lets just do the normal read from input filters, * like the Worker MPM does. */ + apr_atomic_inc32(&clogged_count); ap_run_process_connection(c); if (cs->pub.state != CONN_STATE_SUSPENDED) { cs->pub.state = CONN_STATE_LINGER; } + apr_atomic_dec32(&clogged_count); } read_request: @@ -1019,6 +1043,9 @@ read_request: AP_DEBUG_ASSERT(rc == APR_SUCCESS); } } + else if (cs->pub.state == CONN_STATE_SUSPENDED) { + apr_atomic_inc32(&suspended_count); + } /* * Prevent this connection from writing to our connection state after it * is no longer associated with this thread. This would happen if the EOR @@ -1398,11 +1425,14 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) last_log = now; apr_thread_mutex_lock(timeout_mutex); ap_log_error(APLOG_MARK, APLOG_TRACE6, 0, ap_server_conf, - "connections: %d (write-completion: %d " - "keep-alive: %d lingering: %d)", - connection_count, write_completion_q.count, + "connections: %u (clogged: %u write-completion: %d " + "keep-alive: %d lingering: %d suspended: %u)", + apr_atomic_read32(&connection_count), + apr_atomic_read32(&clogged_count), + write_completion_q.count, keepalive_q.count, - linger_q.count + short_linger_q.count); + apr_atomic_read32(&lingering_count), + apr_atomic_read32(&suspended_count)); apr_thread_mutex_unlock(timeout_mutex); } } @@ -1535,9 +1565,11 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) "All workers busy, not accepting new conns" "in this process"); } - else if (apr_atomic_read32(&connection_count) > threads_per_child - + ap_queue_info_get_idlers(worker_queue_info) * - worker_factor / WORKER_FACTOR_SCALE) + else if ( (int)apr_atomic_read32(&connection_count) + - (int)apr_atomic_read32(&lingering_count) + > threads_per_child + + ap_queue_info_get_idlers(worker_queue_info) * + worker_factor / WORKER_FACTOR_SCALE) { if (!listeners_disabled) disable_listensocks(process_slot); @@ -1658,17 +1690,18 @@ static void * APR_THREAD_FUNC listener_thread(apr_thread_t * thd, void *dummy) ps = ap_get_scoreboard_process(process_slot); ps->write_completion = write_completion_q.count; - ps->lingering_close = linger_q.count + short_linger_q.count; ps->keep_alive = keepalive_q.count; apr_thread_mutex_unlock(timeout_mutex); ps->connections = apr_atomic_read32(&connection_count); - /* XXX: should count CONN_STATE_SUSPENDED and set ps->suspended */ - } - if (listeners_disabled && !workers_were_busy && - (int)apr_atomic_read32(&connection_count) < - ((int)ap_queue_info_get_idlers(worker_queue_info) - 1) * - worker_factor / WORKER_FACTOR_SCALE + threads_per_child) + ps->suspended = apr_atomic_read32(&suspended_count); + ps->lingering_close = apr_atomic_read32(&lingering_count); + } + if (listeners_disabled && !workers_were_busy + && (int)apr_atomic_read32(&connection_count) + - (int)apr_atomic_read32(&lingering_count) + < ((int)ap_queue_info_get_idlers(worker_queue_info) - 1) + * worker_factor / WORKER_FACTOR_SCALE + threads_per_child) { listeners_disabled = 0; enable_listensocks(process_slot);