]> granicus.if.org Git - apache/commitdiff
Mod_proxy used the global pool w/o mutex. fix.
authorJim Jagielski <jim@apache.org>
Thu, 9 May 2013 13:33:02 +0000 (13:33 +0000)
committerJim Jagielski <jim@apache.org>
Thu, 9 May 2013 13:33:02 +0000 (13:33 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1480627 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/proxy/mod_proxy.c
modules/proxy/mod_proxy.h
modules/proxy/mod_proxy_balancer.c
modules/proxy/proxy_util.c

diff --git a/CHANGES b/CHANGES
index c0f607d73b1b1e2392297cb704bd700e0d06b33f..778aa6dd2a05bf10598709e6c5808fe187526956 100644 (file)
--- 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 <thomas.r.w.eckert gmail.com>, 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.
index 71b5be24e8fd2800f9a1f0460b7282bfec5f6aeb..a10ae4d92540cecd990b9fae9aa1bff78d21689c 100644 (file)
@@ -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,
index 43835b1b767bd554aa83b71cccf1cd6342cee598..f3d34009c1d6b5565ddff0f4b471b6b30b16bdbf 100644 (file)
@@ -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;
 
index b1fd84eeb5846ec259c1ae2abef3cceb8366be4c..1e215126b495d1be4625e5941c8a583a0d4fb461 100644 (file)
@@ -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)
index d5cfb86548be6b243a6d0f7591300a86bcee4369..f0222fe08fb9f0d41816d7948a10c250bc9186a5 100644 (file)
@@ -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;
             }