From: Jim Jagielski Date: Thu, 9 May 2013 13:33:02 +0000 (+0000) Subject: Mod_proxy used the global pool w/o mutex. fix. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=005fdc5adf6921154c8d29b173a5f7e09b316805;p=thirdparty%2Fapache%2Fhttpd.git Mod_proxy used the global pool w/o mutex. fix. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1480627 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index c0f607d73b1..778aa6dd2a0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) mod_proxy: Fix seg-faults when using the global pool on threaded + MPMs [Thomas Eckert , Jim Jagielski] + *) mod_proxy: Ensure network errors detected by the proxy are returned as 504 Gateway Timout as opposed to 502 Bad Gateway, in order to be compliant with RFC2616 14.9.4 Cache Revalidation and Reload Controls. diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 71b5be24e8f..a10ae4d9254 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -1187,8 +1187,10 @@ static void * create_proxy_config(apr_pool_t *p, server_rec *s) ps->badopt_set = 0; ps->source_address = NULL; ps->source_address_set = 0; - ps->pool = p; - + apr_pool_create_ex(&ps->pool, p, NULL, NULL); + apr_global_mutex_create(&ps->mutex, + "mod_proxy_config_mutex", + APR_LOCK_DEFAULT, p); return ps; } @@ -1249,7 +1251,8 @@ static void * merge_proxy_config(apr_pool_t *p, void *basev, void *overridesv) ps->proxy_status_set = overrides->proxy_status_set || base->proxy_status_set; ps->source_address = (overrides->source_address_set == 0) ? base->source_address : overrides->source_address; ps->source_address_set = overrides->source_address_set || base->source_address_set; - ps->pool = p; + ps->pool = base->pool; + ps->mutex = base->mutex; return ps; } static const char *set_source_address(cmd_parms *parms, void *dummy, diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h index 43835b1b767..f3d34009c1d 100644 --- a/modules/proxy/mod_proxy.h +++ b/modules/proxy/mod_proxy.h @@ -164,7 +164,7 @@ typedef struct { status_full } proxy_status; /* Status display options */ apr_sockaddr_t *source_address; - apr_global_mutex_t *mutex; /* global lock (needed??) */ + apr_global_mutex_t *mutex; /* global lock, for pool, etc */ ap_slotmem_instance_t *bslot; /* balancers shm data - runtime */ ap_slotmem_provider_t *storage; diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c index b1fd84eeb58..1e215126b49 100644 --- a/modules/proxy/mod_proxy_balancer.c +++ b/modules/proxy/mod_proxy_balancer.c @@ -1171,7 +1171,7 @@ static int balancer_handler(request_rec *r) (val = apr_table_get(params, "b_nwrkr"))) { char *ret; proxy_worker *nworker; - nworker = ap_proxy_get_worker(conf->pool, bsel, conf, val); + nworker = ap_proxy_get_worker(r->pool, bsel, conf, val); if (!nworker && storage->num_free_slots(bsel->wslot)) { if ((rv = PROXY_GLOBAL_LOCK(bsel)) != APR_SUCCESS) { ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01194) diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index d5cfb86548b..f0222fe08fb 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1681,6 +1681,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser { apr_status_t rv = APR_SUCCESS; int mpm_threads; + proxy_server_conf *conf = (proxy_server_conf *)ap_get_module_config(s->module_config, &proxy_module); if (worker->s->status & PROXY_WORKER_INITIALIZED) { /* The worker is already initialized */ @@ -1730,12 +1731,14 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser else { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927) "initializing worker %s local", worker->s->name); + apr_global_mutex_lock(conf->mutex); /* Now init local worker data */ if (worker->tmutex == NULL) { rv = apr_thread_mutex_create(&(worker->tmutex), APR_THREAD_MUTEX_DEFAULT, p); if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00928) "can not create worker thread mutex"); + apr_global_mutex_unlock(conf->mutex); return rv; } } @@ -1744,6 +1747,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser if (worker->cp == NULL) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00929) "can not create connection pool"); + apr_global_mutex_unlock(conf->mutex); return APR_EGENERAL; } @@ -1779,6 +1783,8 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser "initialized single connection worker in child %" APR_PID_T_FMT " for (%s)", getpid(), worker->s->hostname); } + apr_global_mutex_unlock(conf->mutex); + } if (rv == APR_SUCCESS) { worker->s->status |= (PROXY_WORKER_INITIALIZED); @@ -2893,14 +2899,17 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec if (!found) { proxy_worker **runtime; runtime = apr_array_push(b->workers); + apr_global_mutex_lock(conf->mutex); *runtime = apr_palloc(conf->pool, sizeof(proxy_worker)); + apr_global_mutex_unlock(conf->mutex); (*runtime)->hash = shm->hash; (*runtime)->context = NULL; (*runtime)->cp = NULL; (*runtime)->balancer = b; (*runtime)->s = shm; (*runtime)->tmutex = NULL; - if ((rv = ap_proxy_initialize_worker(*runtime, s, conf->pool)) != APR_SUCCESS) { + rv = ap_proxy_initialize_worker(*runtime, s, conf->pool); + if (rv != APR_SUCCESS) { ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(00966) "Cannot init worker"); return rv; }