1
0
mirror of https://github.com/apache/httpd.git synced 2026-01-06 09:01:14 +03:00

mpm_event(opt), mpm_worker, mpm_prefork: follow up to r1635521, r1640161.

Retain num_buckets and max_buckets accross restarts so that we can determine
whether new buckets were allocated and set their idle_spawn_rate at the same
level as the existing ones (max).

Also, adjust ap_daemons_limit and ap_daemons_to_start lower bounds at mpm_run()
time, once num_buckets is available for the current generation (previously done
at check_config time, hence before num_buckets is computed, and then with the
previous generation's value).


git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1640763 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Yann Ylavic
2014-11-20 16:26:04 +00:00
parent a952fd276f
commit 4669bc745b
4 changed files with 172 additions and 163 deletions

View File

@@ -350,15 +350,20 @@ typedef struct event_retained_data {
/*
* idle_spawn_rate is the number of children that will be spawned on the
* next maintenance cycle if there aren't enough idle servers. It is
* doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
* without the need to spawn.
* maintained per listeners bucket, doubled up to MAX_SPAWN_RATE, and
* reset only when a cycle goes by without the need to spawn.
*/
int *idle_spawn_rate,
idle_spawn_rate_len;
int *idle_spawn_rate;
#ifndef MAX_SPAWN_RATE
#define MAX_SPAWN_RATE (32)
#endif
int hold_off_on_exponential_spawning;
/*
* Current number of listeners buckets and maximum reached accross
* restarts (to size retained data according to dynamic num_buckets,
* eg. idle_spawn_rate).
*/
int num_buckets, max_buckets;
} event_retained_data;
static event_retained_data *retained;
@@ -366,7 +371,6 @@ typedef struct event_child_bucket {
ap_pod_t *pod;
ap_listen_rec *listeners;
} event_child_bucket;
static int num_buckets; /* Number of listeners buckets */
static event_child_bucket *all_buckets, /* All listeners buckets */
*my_bucket; /* Current child bucket */
@@ -2425,7 +2429,7 @@ static void child_main(int child_num_arg, int child_bucket)
apr_pool_create(&pchild, pconf);
/* close unused listeners and pods */
for (i = 0; i < num_buckets; i++) {
for (i = 0; i < retained->num_buckets; i++) {
if (i != child_bucket) {
ap_close_listeners_ex(all_buckets[i].listeners);
ap_mpm_podx_close(all_buckets[i].pod);
@@ -2664,14 +2668,14 @@ static void startup_children(int number_to_start)
if (ap_scoreboard_image->parent[i].pid != 0) {
continue;
}
if (make_child(ap_server_conf, i, i % num_buckets) < 0) {
if (make_child(ap_server_conf, i, i % retained->num_buckets) < 0) {
break;
}
--number_to_start;
}
}
static void perform_idle_server_maintenance(int child_bucket)
static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
{
int i, j;
int idle_thread_count;
@@ -2845,8 +2849,8 @@ static void perform_idle_server_maintenance(int child_bucket)
if (retained->hold_off_on_exponential_spawning) {
--retained->hold_off_on_exponential_spawning;
}
else if (retained->idle_spawn_rate[child_bucket] <
MAX_SPAWN_RATE / num_buckets) {
else if (retained->idle_spawn_rate[child_bucket]
< MAX_SPAWN_RATE / num_buckets) {
retained->idle_spawn_rate[child_bucket] *= 2;
}
}
@@ -2856,7 +2860,7 @@ static void perform_idle_server_maintenance(int child_bucket)
}
}
static void server_main_loop(int remaining_children_to_start)
static void server_main_loop(int remaining_children_to_start, int num_buckets)
{
ap_generation_t old_gen;
int child_slot;
@@ -2972,15 +2976,15 @@ static void server_main_loop(int remaining_children_to_start)
}
for (i = 0; i < num_buckets; i++) {
perform_idle_server_maintenance(i);
perform_idle_server_maintenance(i, num_buckets);
}
}
}
static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
{
int num_buckets = retained->num_buckets;
int remaining_children_to_start;
int i;
ap_log_pid(pconf, ap_pid_fname);
@@ -2999,7 +3003,13 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
restart_pending = shutdown_pending = 0;
set_signals();
/* Don't thrash... */
/* Don't thrash since num_buckets depends on the
* system and the number of online CPU cores...
*/
if (ap_daemons_limit < num_buckets)
ap_daemons_limit = num_buckets;
if (ap_daemons_to_start < num_buckets)
ap_daemons_to_start = num_buckets;
if (min_spare_threads < threads_per_child * num_buckets)
min_spare_threads = threads_per_child * num_buckets;
if (max_spare_threads < min_spare_threads + threads_per_child * num_buckets)
@@ -3038,7 +3048,7 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
mpm_state = AP_MPMQ_RUNNING;
server_main_loop(remaining_children_to_start);
server_main_loop(remaining_children_to_start, num_buckets);
mpm_state = AP_MPMQ_STOPPING;
if (shutdown_pending && !retained->is_graceful) {
@@ -3178,6 +3188,7 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
{
int startup = 0;
int level_flags = 0;
int num_buckets = 0;
ap_listen_rec **listen_buckets;
apr_status_t rv;
int i;
@@ -3200,9 +3211,9 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
if (one_process) {
num_buckets = 1;
}
else if (!retained->is_graceful) { /* Preserve the number of buckets
on graceful restarts. */
num_buckets = 0;
else if (retained->is_graceful) {
/* Preserve the number of buckets on graceful restarts. */
num_buckets = retained->num_buckets;
}
if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
&listen_buckets, &num_buckets))) {
@@ -3211,8 +3222,8 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
"could not duplicate listeners");
return DONE;
}
all_buckets = apr_pcalloc(pconf, num_buckets *
sizeof(event_child_bucket));
all_buckets = apr_pcalloc(pconf, num_buckets * sizeof(*all_buckets));
for (i = 0; i < num_buckets; i++) {
if (!one_process && /* no POD in one_process mode */
(rv = ap_mpm_podx_open(pconf, &all_buckets[i].pod))) {
@@ -3224,21 +3235,34 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
all_buckets[i].listeners = listen_buckets[i];
}
if (retained->idle_spawn_rate_len < num_buckets) {
int *new_ptr, new_len;
new_len = retained->idle_spawn_rate_len * 2;
if (new_len < num_buckets) {
new_len = num_buckets;
if (retained->max_buckets < num_buckets) {
int new_max, *new_ptr;
new_max = retained->max_buckets * 2;
if (new_max < num_buckets) {
new_max = num_buckets;
}
new_ptr = (int *)apr_palloc(ap_pglobal, new_len * sizeof(int));
new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
memcpy(new_ptr, retained->idle_spawn_rate,
retained->idle_spawn_rate_len * sizeof(int));
for (i = retained->idle_spawn_rate_len; i < new_len; i++) {
new_ptr[i] = 1;
}
retained->idle_spawn_rate_len = new_len;
retained->num_buckets * sizeof(int));
retained->idle_spawn_rate = new_ptr;
retained->max_buckets = new_max;
}
if (retained->num_buckets < num_buckets) {
int rate_max = 1;
/* If new buckets are added, set their idle spawn rate to
* the highest so far, so that they get filled as quickly
* as the existing ones.
*/
for (i = 0; i < retained->num_buckets; i++) {
if (rate_max < retained->idle_spawn_rate[i]) {
rate_max = retained->idle_spawn_rate[i];
}
}
for (/* up to date i */; i < num_buckets; i++) {
retained->idle_spawn_rate[i] = rate_max;
}
}
retained->num_buckets = num_buckets;
/* for skiplist */
srand((unsigned int)apr_time_now());
@@ -3522,12 +3546,6 @@ static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_limit = server_limit;
}
else if (ap_daemons_limit < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_limit = num_buckets;
}
/* ap_daemons_to_start > ap_daemons_limit checked in ap_mpm_run() */
if (ap_daemons_to_start < 1) {
@@ -3542,12 +3560,6 @@ static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_to_start = 1;
}
if (ap_daemons_to_start < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_to_start = num_buckets;
}
if (min_spare_threads < 1) {
if (startup) {
@@ -3565,12 +3577,6 @@ static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
}
min_spare_threads = 1;
}
if (min_spare_threads < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
min_spare_threads = num_buckets;
}
/* max_spare_threads < min_spare_threads + threads_per_child
* checked in ap_mpm_run()

View File

@@ -335,15 +335,20 @@ typedef struct event_retained_data {
/*
* idle_spawn_rate is the number of children that will be spawned on the
* next maintenance cycle if there aren't enough idle servers. It is
* doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
* without the need to spawn.
* maintained per listeners bucket, doubled up to MAX_SPAWN_RATE, and
* reset only when a cycle goes by without the need to spawn.
*/
int *idle_spawn_rate,
idle_spawn_rate_len;
int *idle_spawn_rate;
#ifndef MAX_SPAWN_RATE
#define MAX_SPAWN_RATE (32)
#endif
int hold_off_on_exponential_spawning;
/*
* Current number of listeners buckets and maximum reached accross
* restarts (to size retained data according to dynamic num_buckets,
* eg. idle_spawn_rate).
*/
int num_buckets, max_buckets;
} event_retained_data;
static event_retained_data *retained;
@@ -351,7 +356,6 @@ typedef struct event_child_bucket {
ap_pod_t *pod;
ap_listen_rec *listeners;
} event_child_bucket;
static int num_buckets; /* Number of listeners buckets */
static event_child_bucket *all_buckets, /* All listeners buckets */
*my_bucket; /* Current child bucket */
@@ -2245,7 +2249,7 @@ static void child_main(int child_num_arg, int child_bucket)
apr_pool_create(&pchild, pconf);
/* close unused listeners and pods */
for (i = 0; i < num_buckets; i++) {
for (i = 0; i < retained->num_buckets; i++) {
if (i != child_bucket) {
ap_close_listeners_ex(all_buckets[i].listeners);
ap_mpm_podx_close(all_buckets[i].pod);
@@ -2484,14 +2488,14 @@ static void startup_children(int number_to_start)
if (ap_scoreboard_image->parent[i].pid != 0) {
continue;
}
if (make_child(ap_server_conf, i, i % num_buckets) < 0) {
if (make_child(ap_server_conf, i, i % retained->num_buckets) < 0) {
break;
}
--number_to_start;
}
}
static void perform_idle_server_maintenance(int child_bucket)
static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
{
int i, j;
int idle_thread_count;
@@ -2675,7 +2679,7 @@ static void perform_idle_server_maintenance(int child_bucket)
}
}
static void server_main_loop(int remaining_children_to_start)
static void server_main_loop(int remaining_children_to_start, int num_buckets)
{
ap_generation_t old_gen;
int child_slot;
@@ -2791,15 +2795,15 @@ static void server_main_loop(int remaining_children_to_start)
}
for (i = 0; i < num_buckets; i++) {
perform_idle_server_maintenance(i);
perform_idle_server_maintenance(i, num_buckets);
}
}
}
static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
{
int num_buckets = retained->num_buckets;
int remaining_children_to_start;
int i;
ap_log_pid(pconf, ap_pid_fname);
@@ -2818,7 +2822,13 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
restart_pending = shutdown_pending = 0;
set_signals();
/* Don't thrash... */
/* Don't thrash since num_buckets depends on the
* system and the number of online CPU cores...
*/
if (ap_daemons_limit < num_buckets)
ap_daemons_limit = num_buckets;
if (ap_daemons_to_start < num_buckets)
ap_daemons_to_start = num_buckets;
if (min_spare_threads < threads_per_child * num_buckets)
min_spare_threads = threads_per_child * num_buckets;
if (max_spare_threads < min_spare_threads + threads_per_child * num_buckets)
@@ -2857,7 +2867,7 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
mpm_state = AP_MPMQ_RUNNING;
server_main_loop(remaining_children_to_start);
server_main_loop(remaining_children_to_start, num_buckets);
mpm_state = AP_MPMQ_STOPPING;
if (shutdown_pending && !retained->is_graceful) {
@@ -2997,6 +3007,7 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
{
int startup = 0;
int level_flags = 0;
int num_buckets = 0;
ap_listen_rec **listen_buckets;
apr_status_t rv;
int i;
@@ -3019,9 +3030,9 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
if (one_process) {
num_buckets = 1;
}
else if (!retained->is_graceful) { /* Preserve the number of buckets
on graceful restarts. */
num_buckets = 0;
else if (retained->is_graceful) {
/* Preserve the number of buckets on graceful restarts. */
num_buckets = retained->num_buckets;
}
if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
&listen_buckets, &num_buckets))) {
@@ -3030,8 +3041,8 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
"could not duplicate listeners");
return DONE;
}
all_buckets = apr_pcalloc(pconf, num_buckets *
sizeof(event_child_bucket));
all_buckets = apr_pcalloc(pconf, num_buckets * sizeof(*all_buckets));
for (i = 0; i < num_buckets; i++) {
if (!one_process && /* no POD in one_process mode */
(rv = ap_mpm_podx_open(pconf, &all_buckets[i].pod))) {
@@ -3043,21 +3054,34 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
all_buckets[i].listeners = listen_buckets[i];
}
if (retained->idle_spawn_rate_len < num_buckets) {
int *new_ptr, new_len;
new_len = retained->idle_spawn_rate_len * 2;
if (new_len < num_buckets) {
new_len = num_buckets;
if (retained->max_buckets < num_buckets) {
int new_max, *new_ptr;
new_max = retained->max_buckets * 2;
if (new_max < num_buckets) {
new_max = num_buckets;
}
new_ptr = (int *)apr_palloc(ap_pglobal, new_len * sizeof(int));
new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
memcpy(new_ptr, retained->idle_spawn_rate,
retained->idle_spawn_rate_len * sizeof(int));
for (i = retained->idle_spawn_rate_len; i < new_len; i++) {
new_ptr[i] = 1;
}
retained->idle_spawn_rate_len = new_len;
retained->num_buckets * sizeof(int));
retained->idle_spawn_rate = new_ptr;
retained->max_buckets = new_max;
}
if (retained->num_buckets < num_buckets) {
int rate_max = 1;
/* If new buckets are added, set their idle spawn rate to
* the highest so far, so that they get filled as quickly
* as the existing ones.
*/
for (i = 0; i < retained->num_buckets; i++) {
if (rate_max < retained->idle_spawn_rate[i]) {
rate_max = retained->idle_spawn_rate[i];
}
}
for (/* up to date i */; i < num_buckets; i++) {
retained->idle_spawn_rate[i] = rate_max;
}
}
retained->num_buckets = num_buckets;
/* for skiplist */
srand((unsigned int)apr_time_now());
@@ -3339,12 +3363,6 @@ static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_limit = server_limit;
}
else if (ap_daemons_limit < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_limit = num_buckets;
}
/* ap_daemons_to_start > ap_daemons_limit checked in ap_mpm_run() */
if (ap_daemons_to_start < 1) {
@@ -3359,12 +3377,6 @@ static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_to_start = 1;
}
if (ap_daemons_to_start < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_to_start = num_buckets;
}
if (min_spare_threads < 1) {
if (startup) {
@@ -3382,12 +3394,6 @@ static int event_check_config(apr_pool_t *p, apr_pool_t *plog,
}
min_spare_threads = 1;
}
if (min_spare_threads < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
min_spare_threads = num_buckets;
}
/* max_spare_threads < min_spare_threads + threads_per_child
* checked in ap_mpm_run()

View File

@@ -993,7 +993,15 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
return !OK;
}
/* Don't thrash... */
/* Don't thrash since num_buckets depends on the
* system and the number of online CPU cores...
*/
if (ap_daemons_limit < num_buckets)
ap_daemons_limit = num_buckets;
if (ap_daemons_to_start < num_buckets)
ap_daemons_to_start = num_buckets;
if (ap_daemons_min_free < num_buckets)
ap_daemons_min_free = num_buckets;
if (ap_daemons_max_free < ap_daemons_min_free + num_buckets)
ap_daemons_max_free = ap_daemons_min_free + num_buckets;
@@ -1324,7 +1332,7 @@ static int prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
"could not open pipe-of-death");
return DONE;
}
/* Initialize cross-process accept lock (safe accept is needed only) */
/* Initialize cross-process accept lock (safe accept needed only) */
if ((rv = SAFE_ACCEPT((apr_snprintf(id, sizeof id, "%i", i),
ap_proc_mutex_create(&all_buckets[i].mutex,
NULL, AP_ACCEPT_MUTEX_TYPE,
@@ -1483,12 +1491,6 @@ static int prefork_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_limit = 1;
}
if (ap_daemons_limit < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_limit = num_buckets;
}
/* ap_daemons_to_start > ap_daemons_limit checked in prefork_run() */
if (ap_daemons_to_start < 1) {
@@ -1503,12 +1505,6 @@ static int prefork_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_to_start = 1;
}
if (ap_daemons_to_start < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_to_start = num_buckets;
}
if (ap_daemons_min_free < 1) {
if (startup) {
@@ -1526,12 +1522,6 @@ static int prefork_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_min_free = 1;
}
if (ap_daemons_min_free < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_min_free = num_buckets;
}
/* ap_daemons_max_free < ap_daemons_min_free + 1 checked in prefork_run() */

View File

@@ -160,15 +160,20 @@ typedef struct worker_retained_data {
/*
* idle_spawn_rate is the number of children that will be spawned on the
* next maintenance cycle if there aren't enough idle servers. It is
* doubled up to MAX_SPAWN_RATE, and reset only when a cycle goes by
* without the need to spawn.
* maintained per listeners bucket, doubled up to MAX_SPAWN_RATE, and
* reset only when a cycle goes by without the need to spawn.
*/
int *idle_spawn_rate,
idle_spawn_rate_len;
int *idle_spawn_rate;
#ifndef MAX_SPAWN_RATE
#define MAX_SPAWN_RATE (32)
#endif
int hold_off_on_exponential_spawning;
/*
* Current number of listeners buckets and maximum reached accross
* restarts (to size retained data according to dynamic num_buckets,
* eg. idle_spawn_rate).
*/
int num_buckets, max_buckets;
} worker_retained_data;
static worker_retained_data *retained;
@@ -177,7 +182,6 @@ typedef struct worker_child_bucket {
ap_listen_rec *listeners;
apr_proc_mutex_t *mutex;
} worker_child_bucket;
static int num_buckets; /* Number of listeners buckets */
static worker_child_bucket *all_buckets, /* All listeners buckets */
*my_bucket; /* Current child bucket */
@@ -1236,7 +1240,7 @@ static void child_main(int child_num_arg, int child_bucket)
apr_pool_create(&pchild, pconf);
/* close unused listeners and pods */
for (i = 0; i < num_buckets; i++) {
for (i = 0; i < retained->num_buckets; i++) {
if (i != child_bucket) {
ap_close_listeners_ex(all_buckets[i].listeners);
ap_mpm_podx_close(all_buckets[i].pod);
@@ -1476,14 +1480,14 @@ static void startup_children(int number_to_start)
if (ap_scoreboard_image->parent[i].pid != 0) {
continue;
}
if (make_child(ap_server_conf, i, i % num_buckets) < 0) {
if (make_child(ap_server_conf, i, i % retained->num_buckets) < 0) {
break;
}
--number_to_start;
}
}
static void perform_idle_server_maintenance(int child_bucket)
static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
{
int i, j;
int idle_thread_count;
@@ -1680,7 +1684,7 @@ static void perform_idle_server_maintenance(int child_bucket)
}
}
static void server_main_loop(int remaining_children_to_start)
static void server_main_loop(int remaining_children_to_start, int num_buckets)
{
ap_generation_t old_gen;
int child_slot;
@@ -1794,13 +1798,14 @@ static void server_main_loop(int remaining_children_to_start)
}
for (i = 0; i < num_buckets; i++) {
perform_idle_server_maintenance(i);
perform_idle_server_maintenance(i, num_buckets);
}
}
}
static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
{
int num_buckets = retained->num_buckets;
int remaining_children_to_start;
int i;
@@ -1820,7 +1825,13 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
restart_pending = shutdown_pending = 0;
set_signals();
/* Don't thrash... */
/* Don't thrash since num_buckets depends on the
* system and the number of online CPU cores...
*/
if (ap_daemons_limit < num_buckets)
ap_daemons_limit = num_buckets;
if (ap_daemons_to_start < num_buckets)
ap_daemons_to_start = num_buckets;
if (min_spare_threads < threads_per_child * num_buckets)
min_spare_threads = threads_per_child * num_buckets;
if (max_spare_threads < min_spare_threads + threads_per_child * num_buckets)
@@ -1862,7 +1873,7 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
apr_proc_mutex_defname());
mpm_state = AP_MPMQ_RUNNING;
server_main_loop(remaining_children_to_start);
server_main_loop(remaining_children_to_start, num_buckets);
mpm_state = AP_MPMQ_STOPPING;
if (shutdown_pending && !retained->is_graceful) {
@@ -2001,6 +2012,7 @@ static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
{
int startup = 0;
int level_flags = 0;
int num_buckets = 0;
ap_listen_rec **listen_buckets;
apr_status_t rv;
char id[16];
@@ -2024,9 +2036,9 @@ static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
if (one_process) {
num_buckets = 1;
}
else if (!retained->is_graceful) { /* Preserve the number of buckets
on graceful restarts. */
num_buckets = 0;
else if (retained->is_graceful) {
/* Preserve the number of buckets on graceful restarts. */
num_buckets = retained->num_buckets;
}
if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
&listen_buckets, &num_buckets))) {
@@ -2035,8 +2047,8 @@ static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
"could not duplicate listeners");
return DONE;
}
all_buckets = apr_pcalloc(pconf, num_buckets *
sizeof(worker_child_bucket));
all_buckets = apr_pcalloc(pconf, num_buckets * sizeof(*all_buckets));
for (i = 0; i < num_buckets; i++) {
if (!one_process && /* no POD in one_process mode */
(rv = ap_mpm_podx_open(pconf, &all_buckets[i].pod))) {
@@ -2045,7 +2057,7 @@ static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
"could not open pipe-of-death");
return DONE;
}
/* Initialize cross-process accept lock (safe accept is needed only) */
/* Initialize cross-process accept lock (safe accept needed only) */
if ((rv = SAFE_ACCEPT((apr_snprintf(id, sizeof id, "%i", i),
ap_proc_mutex_create(&all_buckets[i].mutex,
NULL, AP_ACCEPT_MUTEX_TYPE,
@@ -2058,21 +2070,34 @@ static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
all_buckets[i].listeners = listen_buckets[i];
}
if (retained->idle_spawn_rate_len < num_buckets) {
int *new_ptr, new_len;
new_len = retained->idle_spawn_rate_len * 2;
if (new_len < num_buckets) {
new_len = num_buckets;
if (retained->max_buckets < num_buckets) {
int new_max, *new_ptr;
new_max = retained->max_buckets * 2;
if (new_max < num_buckets) {
new_max = num_buckets;
}
new_ptr = (int *)apr_palloc(ap_pglobal, new_len * sizeof(int));
new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
memcpy(new_ptr, retained->idle_spawn_rate,
retained->idle_spawn_rate_len * sizeof(int));
for (i = retained->idle_spawn_rate_len; i < new_len; i++) {
new_ptr[i] = 1;
}
retained->idle_spawn_rate_len = new_len;
retained->num_buckets * sizeof(int));
retained->idle_spawn_rate = new_ptr;
retained->max_buckets = new_max;
}
if (retained->num_buckets < num_buckets) {
int rate_max = 1;
/* If new buckets are added, set their idle spawn rate to
* the highest so far, so that they get filled as quickly
* as the existing ones.
*/
for (i = 0; i < retained->num_buckets; i++) {
if (rate_max < retained->idle_spawn_rate[i]) {
rate_max = retained->idle_spawn_rate[i];
}
}
for (/* up to date i */; i < num_buckets; i++) {
retained->idle_spawn_rate[i] = rate_max;
}
}
retained->num_buckets = num_buckets;
return OK;
}
@@ -2334,12 +2359,6 @@ static int worker_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_limit = server_limit;
}
else if (ap_daemons_limit < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_limit = num_buckets;
}
/* ap_daemons_to_start > ap_daemons_limit checked in worker_run() */
if (ap_daemons_to_start < 1) {
@@ -2354,12 +2373,6 @@ static int worker_check_config(apr_pool_t *p, apr_pool_t *plog,
}
ap_daemons_to_start = 1;
}
if (ap_daemons_to_start < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
ap_daemons_to_start = num_buckets;
}
if (min_spare_threads < 1) {
if (startup) {
@@ -2377,12 +2390,6 @@ static int worker_check_config(apr_pool_t *p, apr_pool_t *plog,
}
min_spare_threads = 1;
}
if (min_spare_threads < num_buckets) {
/* Don't thrash since num_buckets depends on
* the system and the number of CPU cores.
*/
min_spare_threads = num_buckets;
}
/* max_spare_threads < min_spare_threads + threads_per_child
* checked in worker_run()