Index: modules/proxy/mod_proxy.h =================================================================== --- modules/proxy/mod_proxy.h (revision 1629836) +++ modules/proxy/mod_proxy.h (working copy) @@ -308,6 +308,7 @@ void *context; /* general purpose storage */ apr_size_t busy; /* busyness factor */ int lbset; /* load balancer cluster set */ + unsigned char digest[APR_MD5_DIGESTSIZE]; /* hash of the worker->name */ } proxy_worker_stat; /* Worker configuration */ @@ -772,6 +773,10 @@ ap_proxy_buckets_lifetime_transform(request_rec *r, apr_bucket_brigade *from, apr_bucket_brigade *to); +#if PROXY_HAS_SCOREBOARD +void *ap_proxy_get_scoreboard_lb(proxy_worker *worker); +#endif + #define PROXY_LBMETHOD "proxylbmethod" /* The number of dynamic workers that can be added when reconfiguring. Index: modules/proxy/mod_proxy_balancer.c =================================================================== --- modules/proxy/mod_proxy_balancer.c (revision 1629836) +++ modules/proxy/mod_proxy_balancer.c (working copy) @@ -94,7 +94,7 @@ * If the worker is not initialized check whether its scoreboard * slot is already initialized. */ - slot = (proxy_worker_stat *) ap_get_scoreboard_lb(workers->id); + slot = (proxy_worker_stat *) ap_proxy_get_scoreboard_lb(workers); if (slot) { worker_is_initialized = slot->status & PROXY_WORKER_INITIALIZED; } Index: modules/proxy/proxy_util.c =================================================================== --- modules/proxy/proxy_util.c (revision 1629836) +++ modules/proxy/proxy_util.c (working copy) @@ -1794,6 +1794,39 @@ } #endif +#if PROXY_HAS_SCOREBOARD +void *ap_proxy_get_scoreboard_lb(proxy_worker *worker) { + int i = 0; + proxy_worker_stat *free_slot = NULL; + proxy_worker_stat *s; + apr_md5_ctx_t context; + unsigned char digest[APR_MD5_DIGESTSIZE]; + + if (!ap_scoreboard_image) { + return NULL; + } + + apr_md5_init(&context); + apr_md5_update(&context, (const unsigned char *) worker->name, + strlen(worker->name)); + apr_md5_final(digest, &context); + + /* Try to find out the right shared memory according to the hash + * of worker->name. */ + while ((s = (proxy_worker_stat *)ap_get_scoreboard_lb(i++)) != NULL) { + if (memcmp(s->digest, digest, APR_MD5_DIGESTSIZE) == 0) { + return s; + } + else if (s->status == 0 && free_slot == NULL) { + free_slot = s; + } + } + + /* We failed to find out shared memory, so just use free slot */ + return free_slot; +}; +#endif + /* * ap_proxy_initialize_worker_share() concerns itself * with initializing those parts of worker which @@ -1803,6 +1836,7 @@ proxy_worker *worker, server_rec *s) { + apr_md5_ctx_t context; #if PROXY_HAS_SCOREBOARD lb_score *score = NULL; #else @@ -1819,10 +1853,10 @@ #if PROXY_HAS_SCOREBOARD /* Get scoreboard slot */ if (ap_scoreboard_image) { - score = ap_get_scoreboard_lb(worker->id); + score = ap_proxy_get_scoreboard_lb(worker); if (!score) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, - "proxy: ap_get_scoreboard_lb(%d) failed in child %" APR_PID_T_FMT " for worker %s", + "proxy: ap_proxy_get_scoreboard_lb(%d) failed in child %" APR_PID_T_FMT " for worker %s", worker->id, getpid(), worker->name); } else { @@ -1863,6 +1897,11 @@ *worker->s->redirect = '\0'; } + apr_md5_init(&context); + apr_md5_update(&context, (const unsigned char *) worker->name, + strlen(worker->name)); + apr_md5_final(worker->s->digest, &context); + worker->s->status |= (worker->status | PROXY_WORKER_INITIALIZED); }