File httpd-2.2.x-bnc789828-mod_balancer.diff of Package apache2

diff -rNU 20 ../httpd-2.2.21-o/modules/proxy/mod_proxy_balancer.c ./modules/proxy/mod_proxy_balancer.c
--- ../httpd-2.2.21-o/modules/proxy/mod_proxy_balancer.c	2010-10-07 20:51:18.000000000 +0200
+++ ./modules/proxy/mod_proxy_balancer.c	2013-01-28 14:19:44.000000000 +0100
@@ -414,40 +414,52 @@
             if (!(worker->s->status & PROXY_WORKER_IN_ERROR)) {
                 ok = 1;
                 break;
             }
         }
     }
     if (!ok) {
         /* If all workers are in error state force the recovery.
          */
         worker = (proxy_worker *)balancer->workers->elts;
         for (i = 0; i < balancer->workers->nelts; i++, worker++) {
             ++worker->s->retries;
             worker->s->status &= ~PROXY_WORKER_IN_ERROR;
             ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
                          "proxy: BALANCER: (%s). Forcing recovery for worker (%s)",
                          balancer->name, worker->hostname);
         }
     }
 }
 
+
+static apr_status_t decrement_busy_count(void *worker_)
+{
+    proxy_worker *worker = worker_;
+    
+    if (worker->s->busy) {
+        worker->s->busy--;
+    }
+
+    return APR_SUCCESS;
+}
+
 static int proxy_balancer_pre_request(proxy_worker **worker,
                                       proxy_balancer **balancer,
                                       request_rec *r,
                                       proxy_server_conf *conf, char **url)
 {
     int access_status;
     proxy_worker *runtime;
     char *route = NULL;
     char *sticky = NULL;
     apr_status_t rv;
 
     *worker = NULL;
     /* Step 1: check if the url is for us
      * The url we can handle starts with 'balancer://'
      * If balancer is already provided skip the search
      * for balancer, because this is failover attempt.
      */
     if (!*balancer &&
         !(*balancer = ap_proxy_get_balancer(r->pool, conf, *url)))
         return DECLINED;
@@ -536,40 +548,44 @@
                          (*balancer)->name);
 
             return HTTP_SERVICE_UNAVAILABLE;
         }
         if ((*balancer)->sticky && runtime) {
             /*
              * This balancer has sticky sessions and the client either has not
              * supplied any routing information or all workers for this route
              * including possible redirect and hotstandby workers are in error
              * state, but we have found another working worker for this
              * balancer where we can send the request. Thus notice that we have
              * changed the route to the backend.
              */
             apr_table_setn(r->subprocess_env, "BALANCER_ROUTE_CHANGED", "1");
         }
         *worker = runtime;
     }
 
     (*worker)->s->busy++;
 
+    apr_pool_cleanup_register(r->pool, *worker, decrement_busy_count,
+		apr_pool_cleanup_null);
+
+
     /* Add balancer/worker info to env. */
     apr_table_setn(r->subprocess_env,
                    "BALANCER_NAME", (*balancer)->name);
     apr_table_setn(r->subprocess_env,
                    "BALANCER_WORKER_NAME", (*worker)->name);
     apr_table_setn(r->subprocess_env,
                    "BALANCER_WORKER_ROUTE", (*worker)->s->route);
 
     /* Rewrite the url from 'balancer://url'
      * to the 'worker_scheme://worker_hostname[:worker_port]/url'
      * This replaces the balancers fictional name with the
      * real hostname of the elected worker.
      */
     access_status = rewrite_url(r, *worker, url);
     /* Add the session route to request notes if present */
     if (route) {
         apr_table_setn(r->notes, "session-sticky", sticky);
         apr_table_setn(r->notes, "session-route", route);
 
         /* Add session info to env. */
@@ -605,43 +621,40 @@
             int val = ((int *)balancer->errstatuses->elts)[i];
             if (r->status == val) {
                 ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
                              "proxy: BALANCER: (%s).  Forcing recovery for worker (%s), failonstatus %d",
                              balancer->name, worker->name, val);
                 worker->s->status |= PROXY_WORKER_IN_ERROR;
                 worker->s->error_time = apr_time_now();
                 break;
             }
         }
     }
 
     if ((rv = PROXY_THREAD_UNLOCK(balancer)) != APR_SUCCESS) {
         ap_log_error(APLOG_MARK, APLOG_ERR, rv, r->server,
             "proxy: BALANCER: (%s). Unlock failed for post_request",
             balancer->name);
     }
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
                  "proxy_balancer_post_request for (%s)", balancer->name);
 
-    if (worker && worker->s->busy)
-        worker->s->busy--;
-
     return OK;
 
 }
 
 static void recalc_factors(proxy_balancer *balancer)
 {
     int i;
     proxy_worker *workers;
 
 
     /* Recalculate lbfactors */
     workers = (proxy_worker *)balancer->workers->elts;
     /* Special case if there is only one worker it's
      * load factor will always be 1
      */
     if (balancer->workers->nelts == 1) {
         workers->s->lbstatus = workers->s->lbfactor = 1;
         return;
     }
     for (i = 0; i < balancer->workers->nelts; i++) {
openSUSE Build Service is sponsored by