From: Paul Querna Date: Sat, 1 Apr 2006 18:48:05 +0000 (+0000) Subject: Merge r377738 and r377780 from trunk, fixing child-threads using 100% cpu in mod_proxy. X-Git-Tag: 2.2.1~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c51357a3042c67892cf0c949ea831ae0e6d3d2f8;p=thirdparty%2Fapache%2Fhttpd.git Merge r377738 and r377780 from trunk, fixing child-threads using 100% cpu in mod_proxy. PR: 38403 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@390724 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 0b7f2f9085a..373e47bab9c 100644 --- a/CHANGES +++ b/CHANGES @@ -14,6 +14,9 @@ Changes with Apache 2.2.1 made to ap_escape_html so we escape quotes. Reported by JPCERT. [Mark Cox] + *) mod_proxy: Fix incorrect usage of local and shared worker init. + PR 38403. [Jim Jagielski] + *) mod_isapi: Fix compiler errors on Unix platforms. [William Rowe] diff --git a/STATUS b/STATUS index d22551fd499..d3daeaf829b 100644 --- a/STATUS +++ b/STATUS @@ -73,16 +73,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_proxy: Fix PR38403 (Child-Thread uses 100%CPU usage, mod_proxy ?) - due to incorrect usage of local and shared worker inits and - information. - Trunk version of patch: - http://svn.apache.org/viewcvs?rev=377738&view=rev - http://svn.apache.org/viewcvs?rev=377780&view=rev - Backport version for 2.2.x of patch: - Trunk version of patch works - +1: rpluem, jim, pquerna - * mod_proxy_ajp: Remove the Flushing Bandaid from compile time to a more admin-friendly runtime setting. http://svn.apache.org/viewcvs?rev=384580&view=rev diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index d6855976681..a52a146b839 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1570,6 +1570,11 @@ static apr_status_t connection_destructor(void *resource, void *params, } #endif +/* + * ap_proxy_initialize_worker_share() concerns itself + * with initializing those parts of worker which + * are, or could be, shared. Basically worker->s + */ PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, proxy_worker *worker, server_rec *s) @@ -1580,32 +1585,47 @@ PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, void *score = NULL; #endif - if (worker->s && worker->s->status & PROXY_WORKER_INITIALIZED) { + if (worker->s && (worker->s->status & PROXY_WORKER_INITIALIZED)) { /* The worker share is already initialized */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: worker %s already initialized", + worker->name); return; } #if PROXY_HAS_SCOREBOARD /* Get scoreboard slot */ if (ap_scoreboard_image) { score = ap_get_scoreboard_lb(worker->id); - if (!score) - ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "proxy: ap_get_scoreboard_lb(%d) failed for worker %s", - worker->id, worker->name); - } - else { - ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "proxy: initialized scoreboard slot %d for worker %s", - worker->id, worker->name); + if (!score) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, + "proxy: ap_get_scoreboard_lb(%d) failed in child %" APR_PID_T_FMT " for worker %s", + worker->id, getpid(), worker->name); + } + else { + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: grabbed scoreboard slot %d in child %" APR_PID_T_FMT " for worker %s", + worker->id, getpid(), worker->name); + } } #endif if (!score) { score = apr_pcalloc(conf->pool, sizeof(proxy_worker_stat)); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, - "proxy: initialized plain memory for worker %s", - worker->name); + "proxy: initialized plain memory in child %" APR_PID_T_FMT " for worker %s", + getpid(), worker->name); } worker->s = (proxy_worker_stat *)score; + /* + * recheck to see if we've already been here. Possible + * if proxy is using scoreboard to hold shared stats + */ + if (worker->s->status & PROXY_WORKER_INITIALIZED) { + /* The worker share is already initialized */ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, + "proxy: worker %s already initialized", + worker->name); + return; + } if (worker->route) strcpy(worker->s->route, worker->route); else @@ -1614,11 +1634,8 @@ PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, strcpy(worker->s->redirect, worker->redirect); else *worker->s->redirect = '\0'; - /* Set default parameters */ - if (!worker->retry) - worker->retry = apr_time_from_sec(PROXY_WORKER_DEFAULT_RETRY); - /* By default address is reusable */ - worker->is_address_reusable = 1; + + worker->s->status |= (worker->status | PROXY_WORKER_INITIALIZED); } @@ -1630,11 +1647,17 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser int mpm_threads; #endif - if (worker->s->status & PROXY_WORKER_INITIALIZED) { + if (worker->status & PROXY_WORKER_INITIALIZED) { /* The worker is already initialized */ return APR_SUCCESS; } + /* Set default parameters */ + if (!worker->retry) + worker->retry = apr_time_from_sec(PROXY_WORKER_DEFAULT_RETRY); + /* By default address is reusable */ + worker->is_address_reusable = 1; + #if APR_HAS_THREADS ap_mpm_query(AP_MPMQ_MAX_THREADS, &mpm_threads); if (mpm_threads > 1) { @@ -1682,8 +1705,9 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser "proxy: initialized single connection worker %d in child %" APR_PID_T_FMT " for (%s)", worker->id, getpid(), worker->hostname); } - if (rv == APR_SUCCESS) - worker->s->status |= (worker->status | PROXY_WORKER_INITIALIZED); + if (rv == APR_SUCCESS) { + worker->status |= (PROXY_WORKER_INITIALIZED); + } return rv; }