5183f0
diff --git a/modules/proxy/mod_proxy.h b/modules/proxy/mod_proxy.h
5183f0
index 57cc92f..fbbd508 100644
5183f0
--- a/modules/proxy/mod_proxy.h
5183f0
+++ b/modules/proxy/mod_proxy.h
5183f0
@@ -288,12 +288,15 @@ typedef struct {
5183f0
 
5183f0
 /* Connection pool */
5183f0
 struct proxy_conn_pool {
5183f0
-    apr_pool_t     *pool;   /* The pool used in constructor and destructor calls */
5183f0
-    apr_sockaddr_t *addr;   /* Preparsed remote address info */
5183f0
-    apr_reslist_t  *res;    /* Connection resource list */
5183f0
-    proxy_conn_rec *conn;   /* Single connection for prefork mpm */
5183f0
+    apr_pool_t     *pool;     /* The pool used in constructor and destructor calls */
5183f0
+    apr_sockaddr_t *addr;     /* Preparsed remote address info */
5183f0
+    apr_reslist_t  *res;      /* Connection resource list */
5183f0
+    proxy_conn_rec *conn;     /* Single connection for prefork mpm */
5183f0
+    apr_pool_t     *dns_pool; /* The pool used for worker scoped DNS resolutions */
5183f0
 };
5183f0
 
5183f0
+#define AP_VOLATILIZE_T(T, x) (*(T volatile *)&(x))
5183f0
+
5183f0
 /* worker status bits */
5183f0
 /*
5183f0
  * NOTE: Keep up-to-date w/ proxy_wstat_tbl[]
5183f0
@@ -475,7 +478,9 @@ struct proxy_worker {
5183f0
     proxy_conn_pool     *cp;    /* Connection pool to use */
5183f0
     proxy_worker_shared   *s;   /* Shared data */
5183f0
     proxy_balancer  *balancer;  /* which balancer am I in? */
5183f0
+#if APR_HAS_THREADS
5183f0
     apr_thread_mutex_t  *tmutex; /* Thread lock for updating address cache */
5183f0
+#endif
5183f0
     void            *context;   /* general purpose storage */
5183f0
     ap_conf_vector_t *section_config; /* <Proxy>-section wherein defined */
5183f0
 };
5183f0
@@ -534,7 +539,9 @@ struct proxy_balancer {
5183f0
     apr_time_t      wupdated;    /* timestamp of last change to workers list */
5183f0
     proxy_balancer_method *lbmethod;
5183f0
     apr_global_mutex_t  *gmutex; /* global lock for updating list of workers */
5183f0
+#if APR_HAS_THREADS
5183f0
     apr_thread_mutex_t  *tmutex; /* Thread lock for updating shm */
5183f0
+#endif
5183f0
     proxy_server_conf *sconf;
5183f0
     void            *context;    /* general purpose storage */
5183f0
     proxy_balancer_shared *s;    /* Shared data */
5183f0
diff --git a/modules/proxy/mod_proxy_balancer.c b/modules/proxy/mod_proxy_balancer.c
5183f0
index c59f5e9..3a28038 100644
5183f0
--- a/modules/proxy/mod_proxy_balancer.c
5183f0
+++ b/modules/proxy/mod_proxy_balancer.c
5183f0
@@ -346,23 +346,27 @@ static proxy_worker *find_best_worker(proxy_balancer *balancer,
5183f0
     proxy_worker *candidate = NULL;
5183f0
     apr_status_t rv;
5183f0
 
5183f0
+#if APR_HAS_THREADS
5183f0
     if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
5183f0
         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01163)
5183f0
                       "%s: Lock failed for find_best_worker()",
5183f0
                       balancer->s->name);
5183f0
         return NULL;
5183f0
     }
5183f0
+#endif
5183f0
 
5183f0
     candidate = (*balancer->lbmethod->finder)(balancer, r);
5183f0
 
5183f0
     if (candidate)
5183f0
         candidate->s->elected++;
5183f0
 
5183f0
+#if APR_HAS_THREADS
5183f0
     if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
5183f0
         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01164)
5183f0
                       "%s: Unlock failed for find_best_worker()",
5183f0
                       balancer->s->name);
5183f0
     }
5183f0
+#endif
5183f0
 
5183f0
     if (candidate == NULL) {
5183f0
         /* All the workers are in error state or disabled.
5183f0
@@ -492,11 +496,13 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
5183f0
     /* Step 2: Lock the LoadBalancer
5183f0
      * XXX: perhaps we need the process lock here
5183f0
      */
5183f0
+#if APR_HAS_THREADS
5183f0
     if ((rv = PROXY_THREAD_LOCK(*balancer)) != APR_SUCCESS) {
5183f0
         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01166)
5183f0
                       "%s: Lock failed for pre_request", (*balancer)->s->name);
5183f0
         return DECLINED;
5183f0
     }
5183f0
+#endif
5183f0
 
5183f0
     /* Step 3: force recovery */
5183f0
     force_recovery(*balancer, r->server);
5183f0
@@ -557,20 +563,24 @@ static int proxy_balancer_pre_request(proxy_worker **worker,
5183f0
             ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(01167)
5183f0
                           "%s: All workers are in error state for route (%s)",
5183f0
                           (*balancer)->s->name, route);
5183f0
+#if APR_HAS_THREADS
5183f0
             if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
5183f0
                 ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01168)
5183f0
                               "%s: Unlock failed for pre_request",
5183f0
                               (*balancer)->s->name);
5183f0
             }
5183f0
+#endif
5183f0
             return HTTP_SERVICE_UNAVAILABLE;
5183f0
         }
5183f0
     }
5183f0
 
5183f0
+#if APR_HAS_THREADS
5183f0
     if ((rv = PROXY_THREAD_UNLOCK(*balancer)) != APR_SUCCESS) {
5183f0
         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01169)
5183f0
                       "%s: Unlock failed for pre_request",
5183f0
                       (*balancer)->s->name);
5183f0
     }
5183f0
+#endif
5183f0
     if (!*worker) {
5183f0
         runtime = find_best_worker(*balancer, r);
5183f0
         if (!runtime) {
5183f0
@@ -644,12 +654,14 @@ static int proxy_balancer_post_request(proxy_worker *worker,
5183f0
 
5183f0
     apr_status_t rv;
5183f0
 
5183f0
+#if APR_HAS_THREADS
5183f0
     if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
5183f0
         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01173)
5183f0
                       "%s: Lock failed for post_request",
5183f0
                       balancer->s->name);
5183f0
         return HTTP_INTERNAL_SERVER_ERROR;
5183f0
     }
5183f0
+#endif
5183f0
 
5183f0
     if (!apr_is_empty_array(balancer->errstatuses)
5183f0
         && !(worker->s->status & PROXY_WORKER_IGNORE_ERRORS)) {
5183f0
@@ -681,11 +693,12 @@ static int proxy_balancer_post_request(proxy_worker *worker,
5183f0
         worker->s->error_time = apr_time_now();
5183f0
 
5183f0
     }
5183f0
-
5183f0
+#if APR_HAS_THREADS
5183f0
     if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
5183f0
         ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01175)
5183f0
                       "%s: Unlock failed for post_request", balancer->s->name);
5183f0
     }
5183f0
+#endif
5183f0
     ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(01176)
5183f0
                   "proxy_balancer_post_request for (%s)", balancer->s->name);
5183f0
 
5183f0
@@ -945,7 +958,6 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog,
5183f0
             PROXY_STRNCPY(balancer->s->sname, sname); /* We know this will succeed */
5183f0
 
5183f0
             balancer->max_workers = balancer->workers->nelts + balancer->growth;
5183f0
-
5183f0
             /* Create global mutex */
5183f0
             rv = ap_global_mutex_create(&(balancer->gmutex), NULL, balancer_mutex_type,
5183f0
                                         balancer->s->sname, s, pconf, 0);
5183f0
@@ -955,7 +967,6 @@ static int balancer_post_config(apr_pool_t *pconf, apr_pool_t *plog,
5183f0
                              balancer->s->sname);
5183f0
                 return HTTP_INTERNAL_SERVER_ERROR;
5183f0
             }
5183f0
-
5183f0
             apr_pool_cleanup_register(pconf, (void *)s, lock_remove,
5183f0
                                       apr_pool_cleanup_null);
5183f0
 
5183f0
@@ -1135,17 +1146,21 @@ static int balancer_handler(request_rec *r)
5183f0
 
5183f0
     balancer = (proxy_balancer *)conf->balancers->elts;
5183f0
     for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
5183f0
+#if APR_HAS_THREADS
5183f0
         if ((rv = PROXY_THREAD_LOCK(balancer)) != APR_SUCCESS) {
5183f0
             ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01189)
5183f0
                           "%s: Lock failed for balancer_handler",
5183f0
                           balancer->s->name);
5183f0
         }
5183f0
+#endif
5183f0
         ap_proxy_sync_balancer(balancer, r->server, conf);
5183f0
+#if APR_HAS_THREADS
5183f0
         if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
5183f0
             ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01190)
5183f0
                           "%s: Unlock failed for balancer_handler",
5183f0
                           balancer->s->name);
5183f0
         }
5183f0
+#endif
5183f0
     }
5183f0
 
5183f0
     if (r->args && (r->method_number == M_GET)) {
5183f0
@@ -1359,11 +1374,13 @@ static int balancer_handler(request_rec *r)
5183f0
             proxy_worker *nworker;
5183f0
             nworker = ap_proxy_get_worker(r->pool, bsel, conf, val);
5183f0
             if (!nworker && storage->num_free_slots(bsel->wslot)) {
5183f0
+#if APR_HAS_THREADS
5183f0
                 if ((rv = PROXY_GLOBAL_LOCK(bsel)) != APR_SUCCESS) {
5183f0
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01194)
5183f0
                                   "%s: Lock failed for adding worker",
5183f0
                                   bsel->s->name);
5183f0
                 }
5183f0
+#endif
5183f0
                 ret = ap_proxy_define_worker(conf->pool, &nworker, bsel, conf, val, 0);
5183f0
                 if (!ret) {
5183f0
                     unsigned int index;
5183f0
@@ -1372,53 +1389,76 @@ static int balancer_handler(request_rec *r)
5183f0
                     if ((rv = storage->grab(bsel->wslot, &index)) != APR_SUCCESS) {
5183f0
                         ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01195)
5183f0
                                       "worker slotmem_grab failed");
5183f0
+#if APR_HAS_THREADS
5183f0
                         if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
5183f0
                             ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01196)
5183f0
                                           "%s: Unlock failed for adding worker",
5183f0
                                           bsel->s->name);
5183f0
                         }
5183f0
+#endif
5183f0
                         return HTTP_BAD_REQUEST;
5183f0
                     }
5183f0
                     if ((rv = storage->dptr(bsel->wslot, index, (void *)&shm)) != APR_SUCCESS) {
5183f0
                         ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01197)
5183f0
                                       "worker slotmem_dptr failed");
5183f0
+#if APR_HAS_THREADS
5183f0
                         if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
5183f0
                             ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01198)
5183f0
                                           "%s: Unlock failed for adding worker",
5183f0
                                           bsel->s->name);
5183f0
                         }
5183f0
+#endif
5183f0
                         return HTTP_BAD_REQUEST;
5183f0
                     }
5183f0
                     if ((rv = ap_proxy_share_worker(nworker, shm, index)) != APR_SUCCESS) {
5183f0
                         ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01199)
5183f0
                                       "Cannot share worker");
5183f0
+#if APR_HAS_THREADS
5183f0
                         if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
5183f0
                             ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01200)
5183f0
                                           "%s: Unlock failed for adding worker",
5183f0
                                           bsel->s->name);
5183f0
                         }
5183f0
+#endif
5183f0
                         return HTTP_BAD_REQUEST;
5183f0
                     }
5183f0
                     if ((rv = ap_proxy_initialize_worker(nworker, r->server, conf->pool)) != APR_SUCCESS) {
5183f0
                         ap_log_rerror(APLOG_MARK, APLOG_EMERG, rv, r, APLOGNO(01201)
5183f0
                                       "Cannot init worker");
5183f0
+#if APR_HAS_THREADS
5183f0
                         if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
5183f0
                             ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01202)
5183f0
                                           "%s: Unlock failed for adding worker",
5183f0
                                           bsel->s->name);
5183f0
                         }
5183f0
+#endif
5183f0
                         return HTTP_BAD_REQUEST;
5183f0
                     }
5183f0
                     /* sync all timestamps */
5183f0
                     bsel->wupdated = bsel->s->wupdated = nworker->s->updated = apr_time_now();
5183f0
                     /* by default, all new workers are disabled */
5183f0
                     ap_proxy_set_wstatus(PROXY_WORKER_DISABLED_FLAG, 1, nworker);
5183f0
+                } else {
5183f0
+                            ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10163)
5183f0
+                                  "%s: failed to add worker %s",
5183f0
+                                  bsel->s->name, val);
5183f0
+#if APR_HAS_THREADS
5183f0
+                    PROXY_GLOBAL_UNLOCK(bsel);
5183f0
+#endif
5183f0
+                    return HTTP_BAD_REQUEST;
5183f0
                 }
5183f0
+#if APR_HAS_THREADS
5183f0
                 if ((rv = PROXY_GLOBAL_UNLOCK(bsel)) != APR_SUCCESS) {
5183f0
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(01203)
5183f0
                                   "%s: Unlock failed for adding worker",
5183f0
                                   bsel->s->name);
5183f0
                 }
5183f0
+#endif
5183f0
+            } else {
5183f0
+                ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(10164)
5183f0
+                                  "%s: failed to add worker %s",
5183f0
+                                  bsel->s->name, val);
5183f0
+                return HTTP_BAD_REQUEST;
5183f0
             }
5183f0
 
5183f0
         }
5183f0
diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c
5183f0
index 5d9175e..5c4d641 100644
5183f0
--- a/modules/proxy/mod_proxy_ftp.c
5183f0
+++ b/modules/proxy/mod_proxy_ftp.c
5183f0
@@ -979,8 +979,10 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
5183f0
     apr_status_t rv;
5183f0
     conn_rec *origin, *data = NULL;
5183f0
     apr_status_t err = APR_SUCCESS;
5183f0
+#if APR_HAS_THREADS
5183f0
     apr_status_t uerr = APR_SUCCESS;
5183f0
-    apr_bucket_brigade *bb = apr_brigade_create(p, c->bucket_alloc);
5183f0
+#endif
5183f0
+    apr_bucket_brigade *bb;
5183f0
     char *buf, *connectname;
5183f0
     apr_port_t connectport;
5183f0
     char *ftpmessage = NULL;
5183f0
@@ -1120,13 +1122,15 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
5183f0
 
5183f0
     if (worker->s->is_address_reusable) {
5183f0
         if (!worker->cp->addr) {
5183f0
+#if APR_HAS_THREADS
5183f0
             if ((err = PROXY_THREAD_LOCK(worker->balancer)) != APR_SUCCESS) {
5183f0
                 ap_log_rerror(APLOG_MARK, APLOG_ERR, err, r, APLOGNO(01037) "lock");
5183f0
                 return HTTP_INTERNAL_SERVER_ERROR;
5183f0
             }
5183f0
+#endif
5183f0
         }
5183f0
-        connect_addr = worker->cp->addr;
5183f0
-        address_pool = worker->cp->pool;
5183f0
+        connect_addr = AP_VOLATILIZE_T(apr_sockaddr_t *, worker->cp->addr);
5183f0
+        address_pool = worker->cp->dns_pool;
5183f0
     }
5183f0
     else
5183f0
         address_pool = r->pool;
5183f0
@@ -1139,9 +1143,11 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
5183f0
                                     address_pool);
5183f0
     if (worker->s->is_address_reusable && !worker->cp->addr) {
5183f0
         worker->cp->addr = connect_addr;
5183f0
+#if APR_HAS_THREADS
5183f0
         if ((uerr = PROXY_THREAD_UNLOCK(worker->balancer)) != APR_SUCCESS) {
5183f0
             ap_log_rerror(APLOG_MARK, APLOG_ERR, uerr, r, APLOGNO(01038) "unlock");
5183f0
         }
5183f0
+#endif
5183f0
     }
5183f0
     /*
5183f0
      * get all the possible IP addresses for the destname and loop through
5183f0
@@ -1212,6 +1218,7 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker,
5183f0
      * correct directory...
5183f0
      */
5183f0
 
5183f0
+    bb = apr_brigade_create(p, c->bucket_alloc);
5183f0
 
5183f0
     /* possible results: */
5183f0
     /* 120 Service ready in nnn minutes. */
5183f0
diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c
5183f0
index 2bfc8f0..7714b6c 100644
5183f0
--- a/modules/proxy/proxy_util.c
5183f0
+++ b/modules/proxy/proxy_util.c
5183f0
@@ -1167,8 +1167,10 @@ PROXY_DECLARE(char *) ap_proxy_define_balancer(apr_pool_t *p,
5183f0
     lbmethod = ap_lookup_provider(PROXY_LBMETHOD, "byrequests", "0");
5183f0
 
5183f0
     (*balancer)->workers = apr_array_make(p, 5, sizeof(proxy_worker *));
5183f0
+#if APR_HAS_THREADS
5183f0
     (*balancer)->gmutex = NULL;
5183f0
     (*balancer)->tmutex = NULL;
5183f0
+#endif
5183f0
     (*balancer)->lbmethod = lbmethod;
5183f0
 
5183f0
     if (do_malloc)
5183f0
@@ -1257,7 +1259,9 @@ PROXY_DECLARE(apr_status_t) ap_proxy_share_balancer(proxy_balancer *balancer,
5183f0
 
5183f0
 PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balancer, server_rec *s, apr_pool_t *p)
5183f0
 {
5183f0
+#if APR_HAS_THREADS
5183f0
     apr_status_t rv = APR_SUCCESS;
5183f0
+#endif
5183f0
     ap_slotmem_provider_t *storage = balancer->storage;
5183f0
     apr_size_t size;
5183f0
     unsigned int num;
5183f0
@@ -1297,6 +1301,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balance
5183f0
     if (balancer->lbmethod && balancer->lbmethod->reset)
5183f0
         balancer->lbmethod->reset(balancer, s);
5183f0
 
5183f0
+#if APR_HAS_THREADS
5183f0
     if (balancer->tmutex == NULL) {
5183f0
         rv = apr_thread_mutex_create(&(balancer->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
5183f0
         if (rv != APR_SUCCESS) {
5183f0
@@ -1305,6 +1310,7 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_balancer(proxy_balancer *balance
5183f0
             return rv;
5183f0
         }
5183f0
     }
5183f0
+#endif
5183f0
     return APR_SUCCESS;
5183f0
 }
5183f0
 
5183f0
@@ -1446,16 +1452,14 @@ static void socket_cleanup(proxy_conn_rec *conn)
5183f0
 
5183f0
 static apr_status_t conn_pool_cleanup(void *theworker)
5183f0
 {
5183f0
-    proxy_worker *worker = (proxy_worker *)theworker;
5183f0
-    if (worker->cp->res) {
5183f0
-        worker->cp->pool = NULL;
5183f0
-    }
5183f0
+    ((proxy_worker *)theworker)->cp = NULL;
5183f0
     return APR_SUCCESS;
5183f0
 }
5183f0
 
5183f0
 static void init_conn_pool(apr_pool_t *p, proxy_worker *worker)
5183f0
 {
5183f0
     apr_pool_t *pool;
5183f0
+    apr_pool_t *dns_pool;
5183f0
     proxy_conn_pool *cp;
5183f0
 
5183f0
     /*
5183f0
@@ -1466,12 +1470,21 @@ static void init_conn_pool(apr_pool_t *p, proxy_worker *worker)
5183f0
      */
5183f0
     apr_pool_create(&pool, p);
5183f0
     apr_pool_tag(pool, "proxy_worker_cp");
5183f0
+    /*
5183f0
+     * Create a subpool of the connection pool for worker
5183f0
+     * scoped DNS resolutions. This is needed to avoid race
5183f0
+     * conditions in using the connection pool by multiple
5183f0
+     * threads during ramp up.
5183f0
+     */
5183f0
+    apr_pool_create(&dns_pool, pool);
5183f0
+    apr_pool_tag(dns_pool, "proxy_worker_dns");
5183f0
     /*
5183f0
      * Alloc from the same pool as worker.
5183f0
      * proxy_conn_pool is permanently attached to the worker.
5183f0
      */
5183f0
     cp = (proxy_conn_pool *)apr_pcalloc(p, sizeof(proxy_conn_pool));
5183f0
     cp->pool = pool;
5183f0
+    cp->dns_pool = dns_pool;
5183f0
     worker->cp = cp;
5183f0
 }
5183f0
 
5183f0
@@ -1487,14 +1500,6 @@ static apr_status_t connection_cleanup(void *theconn)
5183f0
     proxy_conn_rec *conn = (proxy_conn_rec *)theconn;
5183f0
     proxy_worker *worker = conn->worker;
5183f0
 
5183f0
-    /*
5183f0
-     * If the connection pool is NULL the worker
5183f0
-     * cleanup has been run. Just return.
5183f0
-     */
5183f0
-    if (!worker->cp->pool) {
5183f0
-        return APR_SUCCESS;
5183f0
-    }
5183f0
-
5183f0
     if (conn->r) {
5183f0
         apr_pool_destroy(conn->r->pool);
5183f0
         conn->r = NULL;
5183f0
@@ -1616,7 +1621,7 @@ static apr_status_t connection_destructor(void *resource, void *params,
5183f0
     proxy_worker *worker = params;
5183f0
 
5183f0
     /* Destroy the pool only if not called from reslist_destroy */
5183f0
-    if (worker->cp->pool) {
5183f0
+    if (worker->cp) {
5183f0
         proxy_conn_rec *conn = resource;
5183f0
         apr_pool_destroy(conn->pool);
5183f0
     }
5183f0
@@ -1972,67 +1977,73 @@ PROXY_DECLARE(apr_status_t) ap_proxy_initialize_worker(proxy_worker *worker, ser
5183f0
                      ap_proxy_worker_name(p, worker));
5183f0
     }
5183f0
     else {
5183f0
-        ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927)
5183f0
-                     "initializing worker %s local",
5183f0
-                     ap_proxy_worker_name(p, worker));
5183f0
         apr_global_mutex_lock(proxy_mutex);
5183f0
-        /* Now init local worker data */
5183f0
-        if (worker->tmutex == NULL) {
5183f0
-            rv = apr_thread_mutex_create(&(worker->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
5183f0
-            if (rv != APR_SUCCESS) {
5183f0
-                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00928)
5183f0
-                             "can not create worker thread mutex");
5183f0
+        /* Check again after we got the lock if we are still uninitialized */
5183f0
+        if (!(AP_VOLATILIZE_T(unsigned int, worker->local_status) & PROXY_WORKER_INITIALIZED)) {
5183f0
+            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00927)
5183f0
+                         "initializing worker %s local",
5183f0
+                         ap_proxy_worker_name(p, worker));
5183f0
+            /* Now init local worker data */
5183f0
+#if APR_HAS_THREADS
5183f0
+            if (worker->tmutex == NULL) {
5183f0
+                rv = apr_thread_mutex_create(&(worker->tmutex), APR_THREAD_MUTEX_DEFAULT, p);
5183f0
+                if (rv != APR_SUCCESS) {
5183f0
+                    ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(00928)
5183f0
+                                 "can not create worker thread mutex");
5183f0
+                    apr_global_mutex_unlock(proxy_mutex);
5183f0
+                    return rv;
5183f0
+                }
5183f0
+            }
5183f0
+#endif
5183f0
+            if (worker->cp == NULL)
5183f0
+                init_conn_pool(p, worker);
5183f0
+            if (worker->cp == NULL) {
5183f0
+                ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00929)
5183f0
+                             "can not create connection pool");
5183f0
                 apr_global_mutex_unlock(proxy_mutex);
5183f0
-                return rv;
5183f0
+                return APR_EGENERAL;
5183f0
             }
5183f0
-        }
5183f0
-        if (worker->cp == NULL)
5183f0
-            init_conn_pool(p, worker);
5183f0
-        if (worker->cp == NULL) {
5183f0
-            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(00929)
5183f0
-                         "can not create connection pool");
5183f0
-            apr_global_mutex_unlock(proxy_mutex);
5183f0
-            return APR_EGENERAL;
5183f0
-        }
5183f0
 
5183f0
-        if (worker->s->hmax) {
5183f0
-            rv = apr_reslist_create(&(worker->cp->res),
5183f0
-                                    worker->s->min, worker->s->smax,
5183f0
-                                    worker->s->hmax, worker->s->ttl,
5183f0
-                                    connection_constructor, connection_destructor,
5183f0
-                                    worker, worker->cp->pool);
5183f0
+            if (worker->s->hmax) {
5183f0
+                rv = apr_reslist_create(&(worker->cp->res),
5183f0
+                                        worker->s->min, worker->s->smax,
5183f0
+                                        worker->s->hmax, worker->s->ttl,
5183f0
+                                        connection_constructor, connection_destructor,
5183f0
+                                        worker, worker->cp->pool);
5183f0
 
5183f0
-            apr_pool_cleanup_register(worker->cp->pool, (void *)worker,
5183f0
-                                      conn_pool_cleanup,
5183f0
-                                      apr_pool_cleanup_null);
5183f0
+                apr_pool_pre_cleanup_register(worker->cp->pool, worker,
5183f0
+                                              conn_pool_cleanup);
5183f0
 
5183f0
-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
5183f0
-                "initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",
5183f0
-                 getpid(), worker->s->hostname_ex, worker->s->min,
5183f0
-                 worker->s->hmax, worker->s->smax);
5183f0
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00930)
5183f0
+                    "initialized pool in child %" APR_PID_T_FMT " for (%s) min=%d max=%d smax=%d",
5183f0
+                     getpid(), worker->s->hostname_ex, worker->s->min,
5183f0
+                     worker->s->hmax, worker->s->smax);
5183f0
 
5183f0
-            /* Set the acquire timeout */
5183f0
-            if (rv == APR_SUCCESS && worker->s->acquire_set) {
5183f0
-                apr_reslist_timeout_set(worker->cp->res, worker->s->acquire);
5183f0
-            }
5183f0
+                /* Set the acquire timeout */
5183f0
+                if (rv == APR_SUCCESS && worker->s->acquire_set) {
5183f0
+                    apr_reslist_timeout_set(worker->cp->res, worker->s->acquire);
5183f0
+                }
5183f0
 
5183f0
-        }
5183f0
-        else {
5183f0
-            void *conn;
5183f0
+            }
5183f0
+            else {
5183f0
+                void *conn;
5183f0
 
5183f0
-            rv = connection_constructor(&conn, worker, worker->cp->pool);
5183f0
-            worker->cp->conn = conn;
5183f0
+                rv = connection_constructor(&conn, worker, worker->cp->pool);
5183f0
+                worker->cp->conn = conn;
5183f0
 
5183f0
-            ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(00931)
5183f0
-                 "initialized single connection worker in child %" APR_PID_T_FMT " for (%s)",
5183f0
-                 getpid(), worker->s->hostname_ex);
5183f0
+                ap_log_error(APLOG_MARK, APLOG_DEBUG, rv, s, APLOGNO(00931)
5183f0
+                     "initialized single connection worker in child %" APR_PID_T_FMT " for (%s)",
5183f0
+                     getpid(), worker->s->hostname_ex);
5183f0
+            }
5183f0
+            if (rv == APR_SUCCESS) {
5183f0
+                worker->local_status |= (PROXY_WORKER_INITIALIZED);
5183f0
+            }
5183f0
         }
5183f0
         apr_global_mutex_unlock(proxy_mutex);
5183f0
 
5183f0
     }
5183f0
     if (rv == APR_SUCCESS) {
5183f0
         worker->s->status |= (PROXY_WORKER_INITIALIZED);
5183f0
-        worker->local_status |= (PROXY_WORKER_INITIALIZED);
5183f0
     }
5183f0
     return rv;
5183f0
 }
5183f0
@@ -2292,13 +2303,13 @@ PROXY_DECLARE(int) ap_proxy_acquire_connection(const char *proxy_function,
5183f0
     else {
5183f0
         /* create the new connection if the previous was destroyed */
5183f0
         if (!worker->cp->conn) {
5183f0
-            connection_constructor((void **)conn, worker, worker->cp->pool);
5183f0
+            rv = connection_constructor((void **)conn, worker, worker->cp->pool);
5183f0
         }
5183f0
         else {
5183f0
             *conn = worker->cp->conn;
5183f0
             worker->cp->conn = NULL;
5183f0
+            rv = APR_SUCCESS;
5183f0
         }
5183f0
-        rv = APR_SUCCESS;
5183f0
     }
5183f0
 
5183f0
     if (rv != APR_SUCCESS) {
5183f0
@@ -2344,7 +2355,9 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
5183f0
 {
5183f0
     int server_port;
5183f0
     apr_status_t err = APR_SUCCESS;
5183f0
+#if APR_HAS_THREADS
5183f0
     apr_status_t uerr = APR_SUCCESS;
5183f0
+#endif
5183f0
     const char *uds_path;
5183f0
 
5183f0
     /*
5183f0
@@ -2481,25 +2494,39 @@ ap_proxy_determine_connection(apr_pool_t *p, request_rec *r,
5183f0
              * we can reuse the address.
5183f0
              */
5183f0
             if (!worker->cp->addr) {
5183f0
+#if APR_HAS_THREADS
5183f0
                 if ((err = PROXY_THREAD_LOCK(worker)) != APR_SUCCESS) {
5183f0
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, err, r, APLOGNO(00945) "lock");
5183f0
                     return HTTP_INTERNAL_SERVER_ERROR;
5183f0
                 }
5183f0
+#endif
5183f0
 
5183f0
                 /*
5183f0
-                 * Worker can have the single constant backend address.
5183f0
-                 * The single DNS lookup is used once per worker.
5183f0
-                 * If dynamic change is needed then set the addr to NULL
5183f0
-                 * inside dynamic config to force the lookup.
5183f0
+                 * Recheck addr after we got the lock. This may have changed
5183f0
+                 * while waiting for the lock.
5183f0
                  */
5183f0
-                err = apr_sockaddr_info_get(&(worker->cp->addr),
5183f0
-                                            conn->hostname, APR_UNSPEC,
5183f0
-                                            conn->port, 0,
5183f0
-                                            worker->cp->pool);
5183f0
+                if (!AP_VOLATILIZE_T(apr_sockaddr_t *, worker->cp->addr)) {
5183f0
+
5183f0
+                    apr_sockaddr_t *addr;
5183f0
+
5183f0
+                    /*
5183f0
+                     * Worker can have the single constant backend address.
5183f0
+                     * The single DNS lookup is used once per worker.
5183f0
+                     * If dynamic change is needed then set the addr to NULL
5183f0
+                     * inside dynamic config to force the lookup.
5183f0
+                     */
5183f0
+                    err = apr_sockaddr_info_get(&addr,
5183f0
+                                                conn->hostname, APR_UNSPEC,
5183f0
+                                                conn->port, 0,
5183f0
+                                                worker->cp->dns_pool);
5183f0
+                    worker->cp->addr = addr;
5183f0
+                }
5183f0
                 conn->addr = worker->cp->addr;
5183f0
+#if APR_HAS_THREADS
5183f0
                 if ((uerr = PROXY_THREAD_UNLOCK(worker)) != APR_SUCCESS) {
5183f0
                     ap_log_rerror(APLOG_MARK, APLOG_ERR, uerr, r, APLOGNO(00946) "unlock");
5183f0
                 }
5183f0
+#endif
5183f0
             }
5183f0
             else {
5183f0
                 conn->addr = worker->cp->addr;
5183f0
@@ -3422,7 +3449,9 @@ PROXY_DECLARE(apr_status_t) ap_proxy_sync_balancer(proxy_balancer *b, server_rec
5183f0
             (*runtime)->cp = NULL;
5183f0
             (*runtime)->balancer = b;
5183f0
             (*runtime)->s = shm;
5183f0
+#if APR_HAS_THREADS
5183f0
             (*runtime)->tmutex = NULL;
5183f0
+#endif
5183f0
             rv = ap_proxy_initialize_worker(*runtime, s, conf->pool);
5183f0
             if (rv != APR_SUCCESS) {
5183f0
                 ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(00966) "Cannot init worker");