diff --git a/include/scoreboard.h b/include/scoreboard.h index 7e6cfa920a..a9729ddea2 100644 --- a/include/scoreboard.h +++ b/include/scoreboard.h @@ -205,6 +205,12 @@ AP_DECLARE_HOOK(int, pre_mpm, (apr_pool_t *p, ap_scoreboard_e sb_type)) */ APR_DECLARE_OPTIONAL_FN(int, ap_proxy_lb_workers, (void)); +/** + * proxy load balancer + * @return the size of lb_workers. + */ +APR_DECLARE_OPTIONAL_FN(int, ap_proxy_lb_worker_size, + (void)); /* for time_process_request() in http_main.c */ #define START_PREQUEST 1 diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 93921b8761..c0e14adb28 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -37,6 +37,17 @@ APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, #define MAX(x,y) ((x) >= (y) ? (x) : (y)) #endif +/* Global balancer counter */ +static int lb_workers_limit = 0; + +/* return the sizeof of one lb_worker in scoreboard. */ +static int ap_proxy_lb_worker_size(void) +{ + return sizeof(proxy_worker_stat); +} + + + /* * A Web proxy module. Stages: * @@ -2216,6 +2227,7 @@ static void register_hooks(apr_pool_t *p) static const char *const aszPred[] = { "mpm_winnt.c", NULL}; APR_REGISTER_OPTIONAL_FN(ap_proxy_lb_workers); + APR_REGISTER_OPTIONAL_FN(ap_proxy_lb_worker_size); /* handler */ ap_hook_handler(proxy_handler, NULL, NULL, APR_HOOK_FIRST); /* filename-to-URI translation */ diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c index c66232d21d..138173e8d0 100644 --- a/modules/proxy/proxy_util.c +++ b/modules/proxy/proxy_util.c @@ -1670,7 +1670,7 @@ PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, proxy_worker *worker, server_rec *s) { - lb_score *score = NULL; + proxy_worker_stat *score = NULL; if (PROXY_WORKER_IS_INITIALIZED(worker)) { /* The worker share is already initialized */ @@ -1681,7 +1681,7 @@ PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, } /* Get scoreboard slot */ if (ap_scoreboard_image) { - score = ap_get_scoreboard_lb(worker->id); + score = (proxy_worker_stat *) ap_get_scoreboard_lb(worker->id); 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", @@ -1694,12 +1694,12 @@ PROXY_DECLARE(void) ap_proxy_initialize_worker_share(proxy_server_conf *conf, } } if (!score) { - score = apr_pcalloc(conf->pool, sizeof(proxy_worker_stat)); + score = (proxy_worker_stat *) apr_pcalloc(conf->pool, sizeof(proxy_worker_stat)); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "proxy: initialized plain memory in child %" APR_PID_T_FMT " for worker %s", getpid(), worker->name); } - worker->s = (proxy_worker_stat *)score; + worker->s = score; /* * recheck to see if we've already been here. Possible * if proxy is using scoreboard to hold shared stats diff --git a/server/scoreboard.c b/server/scoreboard.c index ab91d1292d..2bce8ac696 100644 --- a/server/scoreboard.c +++ b/server/scoreboard.c @@ -62,13 +62,15 @@ AP_IMPLEMENT_HOOK_RUN_ALL(int,pre_mpm, static APR_OPTIONAL_FN_TYPE(ap_proxy_lb_workers) *pfn_proxy_lb_workers; +static APR_OPTIONAL_FN_TYPE(ap_proxy_lb_worker_size) + *pfn_proxy_lb_worker_size; struct ap_sb_handle_t { int child_num; int thread_num; }; -static int server_limit, thread_limit, lb_limit; +static int server_limit, thread_limit, lb_limit, worker_size; static apr_size_t scoreboard_size; /* @@ -101,11 +103,18 @@ AP_DECLARE(int) ap_calc_scoreboard_size(void) else lb_limit = 0; + if (!pfn_proxy_lb_worker_size) + pfn_proxy_lb_worker_size = APR_RETRIEVE_OPTIONAL_FN(ap_proxy_lb_worker_size); + if (pfn_proxy_lb_worker_size) + worker_size = pfn_proxy_lb_worker_size(); + else + worker_size = sizeof(lb_score); + scoreboard_size = sizeof(global_score); scoreboard_size += sizeof(process_score) * server_limit; scoreboard_size += sizeof(worker_score) * server_limit * thread_limit; - if (lb_limit) - scoreboard_size += sizeof(lb_score) * lb_limit; + if (lb_limit && worker_size) + scoreboard_size += worker_size * lb_limit; return scoreboard_size; } @@ -129,9 +138,9 @@ void ap_init_scoreboard(void *shared_score) ap_scoreboard_image->servers[i] = (worker_score *)more_storage; more_storage += thread_limit * sizeof(worker_score); } - if (lb_limit) { - ap_scoreboard_image->balancers = (lb_score *)more_storage; - more_storage += lb_limit * sizeof(lb_score); + if (lb_limit && worker_size) { + ap_scoreboard_image->balancers = (void *)more_storage; + more_storage += lb_limit * worker_size; } ap_assert(more_storage == (char*)shared_score + scoreboard_size); ap_scoreboard_image->global->server_limit = server_limit; @@ -281,9 +290,9 @@ int ap_create_scoreboard(apr_pool_t *p, ap_scoreboard_e sb_type) sizeof(worker_score) * thread_limit); } /* Clean up the lb workers data */ - if (lb_limit) { + if (lb_limit && worker_size) { memset(ap_scoreboard_image->balancers, 0, - sizeof(lb_score) * lb_limit); + worker_size * lb_limit); } return OK; } @@ -490,8 +499,10 @@ AP_DECLARE(global_score *) ap_get_scoreboard_global() AP_DECLARE(lb_score *) ap_get_scoreboard_lb(int lb_num) { - if (((lb_num < 0) || (lb_limit < lb_num))) { + char *ptr; + if (((lb_num < 0) || (lb_limit < lb_num)) || (worker_size==0)) { return(NULL); /* Out of range */ } - return &ap_scoreboard_image->balancers[lb_num]; + ptr = (char *) ap_scoreboard_image->balancers + lb_num*worker_size; + return (lb_score *) ptr; }