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-Tag: 2.5.0-alpha~5482 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d7c8ba399248373492d2f42f63f2c3411a693200;p=apache 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 c0f607d73b..778aa6dd2a 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 71b5be24e8..a10ae4d925 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 43835b1b76..f3d34009c1 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 b1fd84eeb5..1e215126b4 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 d5cfb86548..f0222fe08f 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; }