Blob Blame History Raw
diff --git a/modules/proxy/mod_proxy_hcheck.c b/modules/proxy/mod_proxy_hcheck.c
index bd89779..d7c0a68 100644
--- a/modules/proxy/mod_proxy_hcheck.c
+++ b/modules/proxy/mod_proxy_hcheck.c
@@ -33,7 +33,6 @@ module AP_MODULE_DECLARE_DATA proxy_hcheck_module;
 #endif
 #else
 #define HC_USE_THREADS 0
-typedef void apr_thread_pool_t;
 #endif
 
 typedef struct {
@@ -73,7 +72,7 @@ typedef struct {
     proxy_balancer *balancer;
     proxy_worker *worker;
     proxy_worker *hc;
-    apr_time_t now;
+    apr_time_t *now;
 } baton_t;
 
 static void *hc_create_config(apr_pool_t *p, server_rec *s)
@@ -89,7 +88,10 @@ static void *hc_create_config(apr_pool_t *p, server_rec *s)
 }
 
 static ap_watchdog_t *watchdog;
-static int tpsize = HC_THREADPOOL_SIZE;
+#if HC_USE_THREADS
+static apr_thread_pool_t *hctp;
+static int tpsize;
+#endif
 
 /*
  * This serves double duty by not only validating (and creating)
@@ -825,29 +827,28 @@ static void * APR_THREAD_FUNC hc_check(apr_thread_t *thread, void *b)
     server_rec *s = baton->ctx->s;
     proxy_worker *worker = baton->worker;
     proxy_worker *hc = baton->hc;
-    apr_time_t now = baton->now;
+    apr_time_t now;
     apr_status_t rv;
 
     ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(03256)
                  "%sHealth checking %s", (thread ? "Threaded " : ""),
                  worker->s->name);
 
-    worker->s->updated = now;
     if (hc->s->method == TCP) {
         rv = hc_check_tcp(baton);
     }
     else {
         rv = hc_check_http(baton);
     }
+
+    now = apr_time_now();
     if (rv == APR_ENOTIMPL) {
         ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(03257)
                          "Somehow tried to use unimplemented hcheck method: %d",
                          (int)hc->s->method);
-        apr_pool_destroy(baton->ptemp);
-        return NULL;
     }
     /* what state are we in ? */
-    if (PROXY_WORKER_IS_HCFAILED(worker)) {
+    else if (PROXY_WORKER_IS_HCFAILED(worker)) {
         if (rv == APR_SUCCESS) {
             worker->s->pcount += 1;
             if (worker->s->pcount >= worker->s->passes) {
@@ -860,7 +861,8 @@ static void * APR_THREAD_FUNC hc_check(apr_thread_t *thread, void *b)
 
             }
         }
-    } else {
+    }
+    else {
         if (rv != APR_SUCCESS) {
             worker->s->error_time = now;
             worker->s->fcount += 1;
@@ -873,7 +875,12 @@ static void * APR_THREAD_FUNC hc_check(apr_thread_t *thread, void *b)
             }
         }
     }
+    if (baton->now) {
+        *baton->now = now;
+    }
     apr_pool_destroy(baton->ptemp);
+    worker->s->updated = now;
+
     return NULL;
 }
 
@@ -881,12 +888,10 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
                                          apr_pool_t *pool)
 {
     apr_status_t rv = APR_SUCCESS;
-    apr_time_t now = apr_time_now();
     proxy_balancer *balancer;
     sctx_t *ctx = (sctx_t *)data;
     server_rec *s = ctx->s;
     proxy_server_conf *conf;
-    static apr_thread_pool_t *hctp = NULL;
 
     switch (state) {
         case AP_WATCHDOG_STATE_STARTING:
@@ -913,7 +918,6 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
                              "Skipping apr_thread_pool_create()");
                 hctp = NULL;
             }
-
 #endif
             break;
 
@@ -929,45 +933,53 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
                 ctx->s = s;
                 for (i = 0; i < conf->balancers->nelts; i++, balancer++) {
                     int n;
+                    apr_time_t now;
                     proxy_worker **workers;
                     proxy_worker *worker;
                     /* Have any new balancers or workers been added dynamically? */
                     ap_proxy_sync_balancer(balancer, s, conf);
                     workers = (proxy_worker **)balancer->workers->elts;
+                    now = apr_time_now();
                     for (n = 0; n < balancer->workers->nelts; n++) {
                         worker = *workers;
                         if (!PROXY_WORKER_IS(worker, PROXY_WORKER_STOPPED) &&
-                           (worker->s->method != NONE) &&
-                           (now > worker->s->updated + worker->s->interval)) {
+                            (worker->s->method != NONE) &&
+                            (worker->s->updated != 0) &&
+                            (now > worker->s->updated + worker->s->interval)) {
                             baton_t *baton;
                             apr_pool_t *ptemp;
+
                             ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
                                          "Checking %s worker: %s  [%d] (%pp)", balancer->s->name,
                                          worker->s->name, worker->s->method, worker);
 
                             if ((rv = hc_init_worker(ctx, worker)) != APR_SUCCESS) {
+                                worker->s->updated = now;
                                 return rv;
                             }
-                            /* This pool must last the lifetime of the (possible) thread */
+                            worker->s->updated = 0;
+
+                            /* This pool has the lifetime of the check */
                             apr_pool_create(&ptemp, ctx->p);
                             apr_pool_tag(ptemp, "hc_request");
-                            baton = apr_palloc(ptemp, sizeof(baton_t));
+                            baton = apr_pcalloc(ptemp, sizeof(baton_t));
                             baton->ctx = ctx;
-                            baton->now = now;
                             baton->balancer = balancer;
                             baton->worker = worker;
                             baton->ptemp = ptemp;
                             baton->hc = hc_get_hcworker(ctx, worker, ptemp);
-
-                            if (!hctp) {
-                                hc_check(NULL, baton);
-                            }
 #if HC_USE_THREADS
-                            else {
-                                rv = apr_thread_pool_push(hctp, hc_check, (void *)baton,
-                                                          APR_THREAD_TASK_PRIORITY_NORMAL, NULL);
+                            if (hctp) {
+                                apr_thread_pool_push(hctp, hc_check, (void *)baton,
+                                                     APR_THREAD_TASK_PRIORITY_NORMAL,
+                                                     NULL);
                             }
+                            else
 #endif
+                            {
+                                baton->now = &now;
+                                hc_check(NULL, baton);
+                            }
                         }
                         workers++;
                     }
@@ -986,9 +998,9 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
                     ap_log_error(APLOG_MARK, APLOG_INFO, rv, s, APLOGNO(03315)
                                  "apr_thread_pool_destroy() failed");
                 }
+                hctp = NULL;
             }
 #endif
-            hctp = NULL;
             break;
     }
     return rv;
@@ -996,7 +1008,10 @@ static apr_status_t hc_watchdog_callback(int state, void *data,
 static int hc_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
                          apr_pool_t *ptemp)
 {
+#if HC_USE_THREADS
+    hctp = NULL;
     tpsize = HC_THREADPOOL_SIZE;
+#endif
     return OK;
 }
 static int hc_post_config(apr_pool_t *p, apr_pool_t *plog,