summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--os/unix/unixd.c4
-rw-r--r--server/listen.c4
-rw-r--r--server/mpm/event/event.c249
-rw-r--r--server/mpm/prefork/prefork.c257
-rw-r--r--server/mpm/worker/worker.c270
5 files changed, 404 insertions, 380 deletions
diff --git a/os/unix/unixd.c b/os/unix/unixd.c
index 3b0e695727..eed76f683b 100644
--- a/os/unix/unixd.c
+++ b/os/unix/unixd.c
@@ -469,7 +469,6 @@ static void sig_term(int sig)
/* Main process (ap_pglobal) is dying */
return;
}
- retained_data->mpm_state = AP_MPMQ_STOPPING;
if (retained_data->shutdown_pending
&& (retained_data->is_ungraceful
|| sig == AP_SIG_GRACEFUL_STOP)) {
@@ -477,6 +476,7 @@ static void sig_term(int sig)
return;
}
+ retained_data->mpm_state = AP_MPMQ_STOPPING;
retained_data->shutdown_pending = 1;
if (sig != AP_SIG_GRACEFUL_STOP) {
retained_data->is_ungraceful = 1;
@@ -489,7 +489,6 @@ static void sig_restart(int sig)
/* Main process (ap_pglobal) is dying */
return;
}
- retained_data->mpm_state = AP_MPMQ_STOPPING;
if (retained_data->restart_pending
&& (retained_data->is_ungraceful
|| sig == AP_SIG_GRACEFUL)) {
@@ -497,6 +496,7 @@ static void sig_restart(int sig)
return;
}
+ retained_data->mpm_state = AP_MPMQ_STOPPING;
retained_data->restart_pending = 1;
if (sig != AP_SIG_GRACEFUL) {
retained_data->is_ungraceful = 1;
diff --git a/server/listen.c b/server/listen.c
index 445d1202c9..812bdd8bb3 100644
--- a/server/listen.c
+++ b/server/listen.c
@@ -853,7 +853,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
if (val > 1) {
*num_buckets = val;
}
- ap_log_perror(APLOG_MARK, APLOG_INFO, 0, p, APLOGNO(02819)
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02819)
"Using %i listeners bucket(s) based on %i "
"online CPU cores and a ratio of %i",
*num_buckets, num_online_cores,
@@ -862,7 +862,7 @@ AP_DECLARE(apr_status_t) ap_duplicate_listeners(apr_pool_t *p, server_rec *s,
else
#endif
if (!warn_once) {
- ap_log_perror(APLOG_MARK, APLOG_WARNING, 0, p, APLOGNO(02820)
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02820)
"ListenCoresBucketsRatio ignored without "
"SO_REUSEPORT and _SC_NPROCESSORS_ONLN "
"support: using a single listeners bucket");
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
index 1a27a8fc57..dca98d4c3d 100644
--- a/server/mpm/event/event.c
+++ b/server/mpm/event/event.c
@@ -392,6 +392,12 @@ typedef struct socket_callback_baton
unsigned int signaled :1;
} socket_callback_baton_t;
+typedef struct event_child_bucket {
+ ap_pod_t *pod;
+ ap_listen_rec *listeners;
+} event_child_bucket;
+static event_child_bucket *my_bucket; /* Current child bucket */
+
/* data retained by event across load/unload of the module
* allocated on first call to pre-config hook; located on
* subsequent calls to pre-config hook
@@ -399,6 +405,9 @@ typedef struct socket_callback_baton
typedef struct event_retained_data {
ap_unixd_mpm_retained_data *mpm;
+ apr_pool_t *gen_pool; /* generation pool (children start->stop lifetime) */
+ event_child_bucket *buckets; /* children buckets (reset per generation) */
+
int first_server_limit;
int first_thread_limit;
int sick_child_detected;
@@ -433,13 +442,6 @@ typedef struct event_retained_data {
} event_retained_data;
static event_retained_data *retained;
-typedef struct event_child_bucket {
- ap_pod_t *pod;
- ap_listen_rec *listeners;
-} event_child_bucket;
-static event_child_bucket *all_buckets, /* All listeners buckets */
- *my_bucket; /* Current child bucket */
-
struct event_srv_cfg_s {
struct timeout_queue *wc_q,
*ka_q;
@@ -2833,8 +2835,8 @@ static void child_main(int child_num_arg, int child_bucket)
/* close unused listeners and pods */
for (i = 0; i < retained->mpm->num_buckets; i++) {
if (i != child_bucket) {
- ap_close_listeners_ex(all_buckets[i].listeners);
- ap_mpm_podx_close(all_buckets[i].pod);
+ ap_close_listeners_ex(retained->buckets[i].listeners);
+ ap_mpm_podx_close(retained->buckets[i].pod);
}
}
@@ -2859,6 +2861,9 @@ static void child_main(int child_num_arg, int child_bucket)
clean_child_exit(APEXIT_CHILDFATAL);
}
+ /* For rand() users (e.g. skiplist). */
+ srand((unsigned int)apr_time_now());
+
ap_run_child_init(pchild, ap_server_conf);
if (ap_max_requests_per_child) {
@@ -3009,7 +3014,7 @@ static int make_child(server_rec * s, int slot, int bucket)
}
if (one_process) {
- my_bucket = &all_buckets[0];
+ my_bucket = &retained->buckets[0];
event_note_child_started(slot, getpid());
child_main(slot, 0);
@@ -3038,7 +3043,7 @@ static int make_child(server_rec * s, int slot, int bucket)
}
if (!pid) {
- my_bucket = &all_buckets[bucket];
+ my_bucket = &retained->buckets[bucket];
#ifdef HAVE_BINDPROCESSOR
/* By default, AIX binds to a single processor. This bit unbinds
@@ -3188,7 +3193,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
if (retained->total_daemons <= active_daemons_limit &&
retained->total_daemons < server_limit) {
/* Kill off one child */
- ap_mpm_podx_signal(all_buckets[child_bucket].pod,
+ ap_mpm_podx_signal(retained->buckets[child_bucket].pod,
AP_MPM_PODX_GRACEFUL);
retained->idle_spawn_rate[child_bucket] = 1;
active_daemons--;
@@ -3385,25 +3390,122 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets)
static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
{
+ ap_listen_rec **listen_buckets = NULL;
int num_buckets = retained->mpm->num_buckets;
int remaining_children_to_start;
+ apr_status_t rv;
int i;
ap_log_pid(pconf, ap_pid_fname);
+ /* On first startup create gen_pool to satisfy the lifetime of the
+ * parent's PODs and listeners; on restart stop the children from the
+ * previous generation and clear gen_pool for the next one.
+ */
+ if (!retained->gen_pool) {
+ apr_pool_create(&retained->gen_pool, ap_pglobal);
+ }
+ else {
+ if (retained->mpm->was_graceful) {
+ /* wake up the children...time to die. But we'll have more soon */
+ for (i = 0; i < num_buckets; i++) {
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ active_daemons_limit, AP_MPM_PODX_GRACEFUL);
+ }
+ }
+ else {
+ /* Kill 'em all. Since the child acts the same on the parents SIGTERM
+ * and a SIGHUP, we may as well use the same signal, because some user
+ * pthreads are stealing signals from us left and right.
+ */
+ for (i = 0; i < num_buckets; i++) {
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ active_daemons_limit, AP_MPM_PODX_RESTART);
+ }
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+ event_note_child_killed);
+ }
+ apr_pool_clear(retained->gen_pool);
+ retained->buckets = NULL;
+
+ /* advance to the next generation */
+ /* XXX: we really need to make sure this new generation number isn't in
+ * use by any of the previous children.
+ */
+ ++retained->mpm->my_generation;
+ }
+
+ /* On graceful restart, preserve the scoreboard and the listeners buckets.
+ * When ungraceful, clear the scoreboard and set num_buckets to zero to let
+ * ap_duplicate_listeners() below determine how many are needed/configured.
+ */
if (!retained->mpm->was_graceful) {
if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
retained->mpm->mpm_state = AP_MPMQ_STOPPING;
return !OK;
}
- /* fix the generation number in the global score; we just got a new,
- * cleared scoreboard
- */
- ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
+ num_buckets = (one_process) ? 1 : 0; /* one_process => one bucket */
+ retained->mpm->num_buckets = 0; /* reset idle_spawn_rate below */
}
+ /* Now on for the new generation. */
+ ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
ap_unixd_mpm_set_signals(pconf, one_process);
+ if ((rv = ap_duplicate_listeners(retained->gen_pool, ap_server_conf,
+ &listen_buckets, &num_buckets))) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
+ ap_server_conf, APLOGNO(03273)
+ "could not duplicate listeners");
+ return !OK;
+ }
+
+ retained->buckets = apr_pcalloc(retained->gen_pool,
+ num_buckets * sizeof(event_child_bucket));
+ for (i = 0; i < num_buckets; i++) {
+ if (!one_process /* no POD in one_process mode */
+ && (rv = ap_mpm_podx_open(retained->gen_pool,
+ &retained->buckets[i].pod))) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
+ ap_server_conf, APLOGNO(03274)
+ "could not open pipe-of-death");
+ return !OK;
+ }
+ retained->buckets[i].listeners = listen_buckets[i];
+ }
+
+ if (retained->mpm->max_buckets < num_buckets) {
+ int new_max, *new_ptr;
+ new_max = retained->mpm->max_buckets * 2;
+ if (new_max < num_buckets) {
+ new_max = num_buckets;
+ }
+ new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
+ if (retained->mpm->num_buckets) /* idle_spawn_rate NULL at startup */
+ memcpy(new_ptr, retained->idle_spawn_rate,
+ retained->mpm->num_buckets * sizeof(int));
+ retained->idle_spawn_rate = new_ptr;
+ retained->mpm->max_buckets = new_max;
+ }
+ if (retained->mpm->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->mpm->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->mpm->num_buckets = num_buckets;
+
+ active_daemons = 0;
+
/* Don't thrash since num_buckets depends on the
* system and the number of online CPU cores...
*/
@@ -3463,8 +3565,8 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
* Kill child processes, tell them to call child_exit, etc...
*/
for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
- AP_MPM_PODX_RESTART);
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ active_daemons_limit, AP_MPM_PODX_RESTART);
}
ap_reclaim_child_processes(1, /* Start with SIGTERM */
event_note_child_killed);
@@ -3490,8 +3592,8 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
/* Close our listeners, and then ask our children to do same */
ap_close_listeners();
for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
- AP_MPM_PODX_GRACEFUL);
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ active_daemons_limit, AP_MPM_PODX_GRACEFUL);
}
ap_relieve_child_processes(event_note_child_killed);
@@ -3533,8 +3635,8 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
* really dead.
*/
for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
- AP_MPM_PODX_RESTART);
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ active_daemons_limit, AP_MPM_PODX_RESTART);
}
ap_reclaim_child_processes(1, event_note_child_killed);
@@ -3547,46 +3649,15 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
return DONE;
}
- /* advance to the next generation */
- /* XXX: we really need to make sure this new generation number isn't in
- * use by any of the children.
- */
- ++retained->mpm->my_generation;
- ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
-
if (!retained->mpm->is_ungraceful) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00493)
- AP_SIG_GRACEFUL_STRING
- " received. Doing graceful restart");
- /* wake up the children...time to die. But we'll have more soon */
- for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
- AP_MPM_PODX_GRACEFUL);
- }
-
- /* This is mostly for debugging... so that we know what is still
- * gracefully dealing with existing request.
- */
-
+ "%s received. Doing graceful restart",
+ AP_SIG_GRACEFUL_STRING);
}
else {
- /* Kill 'em all. Since the child acts the same on the parents SIGTERM
- * and a SIGHUP, we may as well use the same signal, because some user
- * pthreads are stealing signals from us left and right.
- */
- for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, active_daemons_limit,
- AP_MPM_PODX_RESTART);
- }
-
- ap_reclaim_child_processes(1, /* Start with SIGTERM */
- event_note_child_killed);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00494)
"SIGHUP received. Attempting to restart");
}
-
- active_daemons = 0;
-
return OK;
}
@@ -3647,10 +3718,6 @@ 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;
pconf = p;
@@ -3667,65 +3734,6 @@ static int event_open_logs(apr_pool_t * p, apr_pool_t * plog,
return !OK;
}
- if (one_process) {
- num_buckets = 1;
- }
- else if (retained->mpm->was_graceful) {
- /* Preserve the number of buckets on graceful restarts. */
- num_buckets = retained->mpm->num_buckets;
- }
- if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
- &listen_buckets, &num_buckets))) {
- ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
- (startup ? NULL : s), APLOGNO(03273)
- "could not duplicate listeners");
- return !OK;
- }
-
- 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))) {
- ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
- (startup ? NULL : s), APLOGNO(03274)
- "could not open pipe-of-death");
- return !OK;
- }
- all_buckets[i].listeners = listen_buckets[i];
- }
-
- if (retained->mpm->max_buckets < num_buckets) {
- int new_max, *new_ptr;
- new_max = retained->mpm->max_buckets * 2;
- if (new_max < num_buckets) {
- new_max = num_buckets;
- }
- new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
- if (retained->idle_spawn_rate) /* NULL at startup */
- memcpy(new_ptr, retained->idle_spawn_rate,
- retained->mpm->num_buckets * sizeof(int));
- retained->idle_spawn_rate = new_ptr;
- retained->mpm->max_buckets = new_max;
- }
- if (retained->mpm->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->mpm->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->mpm->num_buckets = num_buckets;
-
- /* for skiplist */
- srand((unsigned int)apr_time_now());
return OK;
}
@@ -3753,16 +3761,13 @@ static int event_pre_config(apr_pool_t * pconf, apr_pool_t * plog,
if (!retained) {
retained = ap_retained_data_create(userdata_key, sizeof(*retained));
retained->mpm = ap_unixd_mpm_get_retained_data();
+ retained->mpm->baton = retained;
retained->max_daemons_limit = -1;
if (retained->mpm->module_loads) {
test_atomics = 1;
}
}
retained->mpm->mpm_state = AP_MPMQ_STARTING;
- if (retained->mpm->baton != retained) {
- retained->mpm->was_graceful = 0;
- retained->mpm->baton = retained;
- }
++retained->mpm->module_loads;
/* test once for correct operation of fdqueue */
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
index 447b901ed8..5b33b7fb82 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -95,6 +95,13 @@ static int ap_daemons_max_free=0;
static int ap_daemons_limit=0; /* MaxRequestWorkers */
static int server_limit = 0;
+typedef struct prefork_child_bucket {
+ ap_pod_t *pod;
+ ap_listen_rec *listeners;
+ apr_proc_mutex_t *mutex;
+} prefork_child_bucket;
+static prefork_child_bucket *my_bucket; /* Current child bucket */
+
/* data retained by prefork across load/unload of the module
* allocated on first call to pre-config hook; located on
* subsequent calls to pre-config hook
@@ -102,6 +109,9 @@ static int server_limit = 0;
typedef struct prefork_retained_data {
ap_unixd_mpm_retained_data *mpm;
+ apr_pool_t *gen_pool; /* generation pool (children start->stop lifetime) */
+ prefork_child_bucket *buckets; /* children buckets (reset per generation) */
+
int first_server_limit;
int maxclients_reported;
/*
@@ -124,14 +134,6 @@ typedef struct prefork_retained_data {
} prefork_retained_data;
static prefork_retained_data *retained;
-typedef struct prefork_child_bucket {
- ap_pod_t *pod;
- ap_listen_rec *listeners;
- apr_proc_mutex_t *mutex;
-} prefork_child_bucket;
-static prefork_child_bucket *all_buckets, /* All listeners buckets */
- *my_bucket; /* Current child bucket */
-
#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
/* one_process --- debugging mode variable; can be set from the command line
@@ -443,8 +445,8 @@ static void child_main(int child_num_arg, int child_bucket)
/* close unused listeners and pods */
for (i = 0; i < retained->mpm->num_buckets; i++) {
if (i != child_bucket) {
- ap_close_listeners_ex(all_buckets[i].listeners);
- ap_mpm_pod_close(all_buckets[i].pod);
+ ap_close_listeners_ex(retained->buckets[i].listeners);
+ ap_mpm_pod_close(retained->buckets[i].pod);
}
}
@@ -696,7 +698,7 @@ static int make_child(server_rec *s, int slot)
}
if (one_process) {
- my_bucket = &all_buckets[0];
+ my_bucket = &retained->buckets[0];
prefork_note_child_started(slot, getpid());
child_main(slot, 0);
@@ -732,7 +734,7 @@ static int make_child(server_rec *s, int slot)
}
if (!pid) {
- my_bucket = &all_buckets[bucket];
+ my_bucket = &retained->buckets[bucket];
#ifdef HAVE_BINDPROCESSOR
/* by default AIX binds to a single processor
@@ -842,7 +844,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p)
* while we were counting
*/
bucket_kill_child_record = (bucket_kill_child_record + 1) % retained->mpm->num_buckets;
- ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod);
+ ap_mpm_pod_signal(retained->buckets[bucket_kill_child_record].pod);
retained->idle_spawn_rate = 1;
}
else if (idle_count < ap_daemons_min_free) {
@@ -891,44 +893,127 @@ static void perform_idle_server_maintenance(apr_pool_t *p)
static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
{
- int index;
+ ap_listen_rec **listen_buckets = NULL;
+ int num_buckets = retained->mpm->num_buckets;
int remaining_children_to_start;
+ apr_status_t rv;
+ char id[16];
int i;
ap_log_pid(pconf, ap_pid_fname);
+ /* On first startup create gen_pool to satisfy the lifetime of the
+ * parent's PODs and listeners; on restart stop the children from the
+ * previous generation and clear gen_pool for the next one.
+ */
+ if (!retained->gen_pool) {
+ apr_pool_create(&retained->gen_pool, ap_pglobal);
+ }
+ else {
+ if (retained->mpm->was_graceful) {
+ /* kill off the idle ones */
+ for (i = 0; i < num_buckets; i++) {
+ ap_mpm_pod_killpg(retained->buckets[i].pod,
+ retained->max_daemons_limit);
+ }
+
+ /* This is mostly for debugging... so that we know what is still
+ * gracefully dealing with existing request. This will break
+ * in a very nasty way if we ever have the scoreboard totally
+ * file-based (no shared memory)
+ */
+ for (i = 0; i < ap_daemons_limit; ++i) {
+ if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
+ ap_scoreboard_image->servers[i][0].status = SERVER_GRACEFUL;
+ /* Ask each child to close its listeners.
+ *
+ * NOTE: we use the scoreboard, because if we send SIGUSR1
+ * to every process in the group, this may include CGI's,
+ * piped loggers, etc. They almost certainly won't handle
+ * it gracefully.
+ */
+ ap_mpm_safe_kill(ap_scoreboard_image->parent[i].pid,
+ AP_SIG_GRACEFUL);
+ }
+ }
+ }
+ else {
+ /* Kill 'em off */
+ if (ap_unixd_killpg(getpgrp(), SIGHUP) < 0) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno,
+ ap_server_conf, APLOGNO(00172) "killpg SIGHUP");
+ }
+ ap_reclaim_child_processes(0, /* Not when just starting up */
+ prefork_note_child_killed);
+ }
+ apr_pool_clear(retained->gen_pool);
+ retained->buckets = NULL;
+
+ /* advance to the next generation */
+ /* XXX: we really need to make sure this new generation number isn't in
+ * use by any of the children.
+ */
+ ++retained->mpm->my_generation;
+ }
+
if (!retained->mpm->was_graceful) {
if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
retained->mpm->mpm_state = AP_MPMQ_STOPPING;
return !OK;
}
- /* fix the generation number in the global score; we just got a new,
- * cleared scoreboard
- */
- ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
+ num_buckets = (one_process) ? 1 : 0; /* one_process => one bucket */
+ retained->idle_spawn_rate = 1; /* reset idle_spawn_rate */
}
+ /* Now on for the new generation. */
+ ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
ap_unixd_mpm_set_signals(pconf, one_process);
- if (one_process) {
- AP_MONCONTROL(1);
- make_child(ap_server_conf, 0);
- /* NOTREACHED */
- ap_assert(0);
+ if ((rv = ap_duplicate_listeners(retained->gen_pool, ap_server_conf,
+ &listen_buckets, &num_buckets))) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
+ ap_server_conf, APLOGNO(03280)
+ "could not duplicate listeners");
return !OK;
}
+ retained->buckets = apr_pcalloc(retained->gen_pool,
+ num_buckets * sizeof(*retained->buckets));
+ for (i = 0; i < num_buckets; i++) {
+ if (!one_process /* no POD in one_process mode */
+ && (rv = ap_mpm_pod_open(retained->gen_pool,
+ &retained->buckets[i].pod))) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
+ ap_server_conf, APLOGNO(03281)
+ "could not open pipe-of-death");
+ return !OK;
+ }
+ /* Initialize cross-process accept lock (safe accept needed only) */
+ if ((rv = SAFE_ACCEPT((apr_snprintf(id, sizeof id, "%i", i),
+ ap_proc_mutex_create(&retained->buckets[i].mutex,
+ NULL, AP_ACCEPT_MUTEX_TYPE,
+ id, s, retained->gen_pool,
+ 0))))) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
+ ap_server_conf, APLOGNO(03282)
+ "could not create accept mutex");
+ return !OK;
+ }
+ retained->buckets[i].listeners = listen_buckets[i];
+ }
+ retained->mpm->num_buckets = num_buckets;
+
/* Don't thrash since num_buckets depends on the
* system and the number of online CPU cores...
*/
- if (ap_daemons_limit < retained->mpm->num_buckets)
- ap_daemons_limit = retained->mpm->num_buckets;
- if (ap_daemons_to_start < retained->mpm->num_buckets)
- ap_daemons_to_start = retained->mpm->num_buckets;
- if (ap_daemons_min_free < retained->mpm->num_buckets)
- ap_daemons_min_free = retained->mpm->num_buckets;
- if (ap_daemons_max_free < ap_daemons_min_free + retained->mpm->num_buckets)
- ap_daemons_max_free = ap_daemons_min_free + retained->mpm->num_buckets;
+ 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;
/* If we're doing a graceful_restart then we're going to see a lot
* of children exiting immediately when we get into the main loop
@@ -962,13 +1047,21 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
ap_log_mpm_common(s);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00165)
"Accept mutex: %s (default: %s)",
- (all_buckets[0].mutex)
- ? apr_proc_mutex_name(all_buckets[0].mutex)
+ (retained->buckets[0].mutex)
+ ? apr_proc_mutex_name(retained->buckets[0].mutex)
: "none",
apr_proc_mutex_defname());
retained->mpm->mpm_state = AP_MPMQ_RUNNING;
+ if (one_process) {
+ AP_MONCONTROL(1);
+ make_child(ap_server_conf, 0);
+ /* NOTREACHED */
+ ap_assert(0);
+ return !OK;
+ }
+
while (!retained->mpm->restart_pending && !retained->mpm->shutdown_pending) {
int child_slot;
apr_exit_why_e exitwhy;
@@ -1096,16 +1189,17 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
ap_close_listeners();
/* kill off the idle ones */
- for (i = 0; i < retained->mpm->num_buckets; i++) {
- ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit);
+ for (i = 0; i < num_buckets; i++) {
+ ap_mpm_pod_killpg(retained->buckets[i].pod,
+ retained->max_daemons_limit);
}
/* Send SIGUSR1 to the active children */
active_children = 0;
- for (index = 0; index < ap_daemons_limit; ++index) {
- if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) {
+ for (i = 0; i < ap_daemons_limit; ++i) {
+ if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
/* Ask each child to close its listeners. */
- ap_mpm_safe_kill(MPM_CHILD_PID(index), AP_SIG_GRACEFUL);
+ ap_mpm_safe_kill(MPM_CHILD_PID(i), AP_SIG_GRACEFUL);
active_children++;
}
}
@@ -1133,8 +1227,8 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
ap_relieve_child_processes(prefork_note_child_killed);
active_children = 0;
- for (index = 0; index < ap_daemons_limit; ++index) {
- if (ap_mpm_safe_kill(MPM_CHILD_PID(index), 0) == APR_SUCCESS) {
+ for (i = 0; i < ap_daemons_limit; ++i) {
+ if (ap_mpm_safe_kill(MPM_CHILD_PID(i), 0) == APR_SUCCESS) {
active_children = 1;
/* Having just one child is enough to stay around */
break;
@@ -1158,52 +1252,14 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
return DONE;
}
- /* advance to the next generation */
- /* XXX: we really need to make sure this new generation number isn't in
- * use by any of the children.
- */
- ++retained->mpm->my_generation;
- ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
-
if (!retained->mpm->is_ungraceful) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00171)
"Graceful restart requested, doing restart");
-
- /* kill off the idle ones */
- for (i = 0; i < retained->mpm->num_buckets; i++) {
- ap_mpm_pod_killpg(all_buckets[i].pod, retained->max_daemons_limit);
- }
-
- /* This is mostly for debugging... so that we know what is still
- * gracefully dealing with existing request. This will break
- * in a very nasty way if we ever have the scoreboard totally
- * file-based (no shared memory)
- */
- for (index = 0; index < ap_daemons_limit; ++index) {
- if (ap_scoreboard_image->servers[index][0].status != SERVER_DEAD) {
- ap_scoreboard_image->servers[index][0].status = SERVER_GRACEFUL;
- /* Ask each child to close its listeners.
- *
- * NOTE: we use the scoreboard, because if we send SIGUSR1
- * to every process in the group, this may include CGI's,
- * piped loggers, etc. They almost certainly won't handle
- * it gracefully.
- */
- ap_mpm_safe_kill(ap_scoreboard_image->parent[index].pid, AP_SIG_GRACEFUL);
- }
- }
}
else {
- /* Kill 'em off */
- if (ap_unixd_killpg(getpgrp(), SIGHUP) < 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf, APLOGNO(00172) "killpg SIGHUP");
- }
- ap_reclaim_child_processes(0, /* Not when just starting up */
- prefork_note_child_killed);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00173)
"SIGHUP received. Attempting to restart");
}
-
return OK;
}
@@ -1214,10 +1270,6 @@ static int prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
{
int startup = 0;
int level_flags = 0;
- ap_listen_rec **listen_buckets;
- apr_status_t rv;
- char id[16];
- int i;
pconf = p;
@@ -1234,42 +1286,6 @@ static int prefork_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
return !OK;
}
- if (one_process) {
- retained->mpm->num_buckets = 1;
- }
- else if (!retained->mpm->was_graceful) {
- /* Preserve the number of buckets on graceful restarts. */
- retained->mpm->num_buckets = 0;
- }
- if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
- &listen_buckets, &retained->mpm->num_buckets))) {
- ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
- (startup ? NULL : s), APLOGNO(03280)
- "could not duplicate listeners");
- return !OK;
- }
- all_buckets = apr_pcalloc(pconf, retained->mpm->num_buckets *
- sizeof(prefork_child_bucket));
- for (i = 0; i < retained->mpm->num_buckets; i++) {
- if ((rv = ap_mpm_pod_open(pconf, &all_buckets[i].pod))) {
- ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
- (startup ? NULL : s), APLOGNO(03281)
- "could not open pipe-of-death");
- return !OK;
- }
- /* 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,
- id, s, pconf, 0))))) {
- ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
- (startup ? NULL : s), APLOGNO(03282)
- "could not create accept mutex");
- return !OK;
- }
- all_buckets[i].listeners = listen_buckets[i];
- }
-
return OK;
}
@@ -1298,14 +1314,11 @@ static int prefork_pre_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp
if (!retained) {
retained = ap_retained_data_create(userdata_key, sizeof(*retained));
retained->mpm = ap_unixd_mpm_get_retained_data();
+ retained->mpm->baton = retained;
retained->max_daemons_limit = -1;
retained->idle_spawn_rate = 1;
}
retained->mpm->mpm_state = AP_MPMQ_STARTING;
- if (retained->mpm->baton != retained) {
- retained->mpm->was_graceful = 0;
- retained->mpm->baton = retained;
- }
++retained->mpm->module_loads;
/* sigh, want this only the second time around */
diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c
index cf1837239e..1f370b2a3b 100644
--- a/server/mpm/worker/worker.c
+++ b/server/mpm/worker/worker.c
@@ -137,6 +137,12 @@ static fd_queue_t *worker_queue;
static fd_queue_info_t *worker_queue_info;
static apr_pollset_t *worker_pollset;
+typedef struct worker_child_bucket {
+ ap_pod_t *pod;
+ ap_listen_rec *listeners;
+ apr_proc_mutex_t *mutex;
+} worker_child_bucket;
+static worker_child_bucket *my_bucket; /* Current child bucket */
/* data retained by worker across load/unload of the module
* allocated on first call to pre-config hook; located on
@@ -145,6 +151,9 @@ static apr_pollset_t *worker_pollset;
typedef struct worker_retained_data {
ap_unixd_mpm_retained_data *mpm;
+ apr_pool_t *gen_pool; /* generation pool (children start->stop lifetime) */
+ worker_child_bucket *buckets; /* children buckets (reset per generation) */
+
int first_server_limit;
int first_thread_limit;
int sick_child_detected;
@@ -171,14 +180,6 @@ typedef struct worker_retained_data {
} worker_retained_data;
static worker_retained_data *retained;
-typedef struct worker_child_bucket {
- ap_pod_t *pod;
- ap_listen_rec *listeners;
- apr_proc_mutex_t *mutex;
-} worker_child_bucket;
-static worker_child_bucket *all_buckets, /* All listeners buckets */
- *my_bucket; /* Current child bucket */
-
#define MPM_CHILD_PID(i) (ap_scoreboard_image->parent[i].pid)
/* The structure used to pass unique initialization info to each thread */
@@ -1123,8 +1124,8 @@ static void child_main(int child_num_arg, int child_bucket)
/* close unused listeners and pods */
for (i = 0; i < retained->mpm->num_buckets; i++) {
if (i != child_bucket) {
- ap_close_listeners_ex(all_buckets[i].listeners);
- ap_mpm_podx_close(all_buckets[i].pod);
+ ap_close_listeners_ex(retained->buckets[i].listeners);
+ ap_mpm_podx_close(retained->buckets[i].pod);
}
}
@@ -1292,7 +1293,7 @@ static int make_child(server_rec *s, int slot, int bucket)
}
if (one_process) {
- my_bucket = &all_buckets[0];
+ my_bucket = &retained->buckets[0];
worker_note_child_started(slot, getpid());
child_main(slot, 0);
@@ -1320,7 +1321,7 @@ static int make_child(server_rec *s, int slot, int bucket)
}
if (!pid) {
- my_bucket = &all_buckets[bucket];
+ my_bucket = &retained->buckets[bucket];
#ifdef HAVE_BINDPROCESSOR
/* By default, AIX binds to a single processor. This bit unbinds
@@ -1501,7 +1502,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
if (idle_thread_count > max_spare_threads / num_buckets) {
/* Kill off one child */
- ap_mpm_podx_signal(all_buckets[child_bucket].pod,
+ ap_mpm_podx_signal(retained->buckets[child_bucket].pod,
AP_MPM_PODX_GRACEFUL);
retained->idle_spawn_rate[child_bucket] = 1;
}
@@ -1694,25 +1695,133 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets)
static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
{
+ ap_listen_rec **listen_buckets = NULL;
int num_buckets = retained->mpm->num_buckets;
int remaining_children_to_start;
+ apr_status_t rv;
+ char id[16];
int i;
ap_log_pid(pconf, ap_pid_fname);
+ /* On first startup create gen_pool to satisfy the lifetime of the
+ * parent's PODs, accept mutexes and listeners; on restart stop the
+ * children from the previous generation and clear gen_pool for the
+ * next one.
+ */
+ if (!retained->gen_pool) {
+ apr_pool_create(&retained->gen_pool, ap_pglobal);
+ }
+ else {
+ if (retained->mpm->was_graceful) {
+ /* wake up the children...time to die. But we'll have more soon */
+ for (i = 0; i < num_buckets; i++) {
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ ap_daemons_limit, AP_MPM_PODX_GRACEFUL);
+ }
+ }
+ else {
+ /* Kill 'em all. Since the child acts the same on the parents SIGTERM
+ * and a SIGHUP, we may as well use the same signal, because some user
+ * pthreads are stealing signals from us left and right.
+ */
+ for (i = 0; i < num_buckets; i++) {
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ ap_daemons_limit, AP_MPM_PODX_RESTART);
+ }
+ ap_reclaim_child_processes(1, /* Start with SIGTERM */
+ worker_note_child_killed);
+ }
+ apr_pool_clear(retained->gen_pool);
+ retained->buckets = NULL;
+
+ /* advance to the next generation */
+ /* XXX: we really need to make sure this new generation number isn't in
+ * use by any of the previous children.
+ */
+ ++retained->mpm->my_generation;
+ }
+
+ /* On graceful restart, preserve the scoreboard and the listeners buckets.
+ * When ungraceful, clear the scoreboard and set num_buckets to zero to let
+ * ap_duplicate_listeners() below determine how many are needed/configured.
+ */
if (!retained->mpm->was_graceful) {
if (ap_run_pre_mpm(s->process->pool, SB_SHARED) != OK) {
retained->mpm->mpm_state = AP_MPMQ_STOPPING;
return !OK;
}
- /* fix the generation number in the global score; we just got a new,
- * cleared scoreboard
- */
- ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
+ num_buckets = (one_process) ? 1 : 0; /* one_process => one bucket */
+ retained->mpm->num_buckets = 0; /* reset idle_spawn_rate below */
}
+ /* Now on for the new generation. */
+ ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
ap_unixd_mpm_set_signals(pconf, one_process);
+ if ((rv = ap_duplicate_listeners(retained->gen_pool, ap_server_conf,
+ &listen_buckets, &num_buckets))) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
+ ap_server_conf, APLOGNO(03291)
+ "could not duplicate listeners");
+ return !OK;
+ }
+
+ retained->buckets = apr_pcalloc(retained->gen_pool,
+ num_buckets * sizeof(*retained->buckets));
+ for (i = 0; i < num_buckets; i++) {
+ if (!one_process /* no POD in one_process mode */
+ && (rv = ap_mpm_podx_open(retained->gen_pool,
+ &retained->buckets[i].pod))) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
+ ap_server_conf, APLOGNO(03292)
+ "could not open pipe-of-death");
+ return !OK;
+ }
+ /* Initialize cross-process accept lock (safe accept needed only) */
+ if ((rv = SAFE_ACCEPT((apr_snprintf(id, sizeof id, "%i", i),
+ ap_proc_mutex_create(&retained->buckets[i].mutex,
+ NULL, AP_ACCEPT_MUTEX_TYPE,
+ id, s, retained->gen_pool,
+ 0))))) {
+ ap_log_error(APLOG_MARK, APLOG_CRIT, rv,
+ ap_server_conf, APLOGNO(03293)
+ "could not create accept mutex");
+ return !OK;
+ }
+ retained->buckets[i].listeners = listen_buckets[i];
+ }
+
+ if (retained->mpm->max_buckets < num_buckets) {
+ int new_max, *new_ptr;
+ new_max = retained->mpm->max_buckets * 2;
+ if (new_max < num_buckets) {
+ new_max = num_buckets;
+ }
+ new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
+ if (retained->mpm->num_buckets) /* idle_spawn_rate NULL at startup */
+ memcpy(new_ptr, retained->idle_spawn_rate,
+ retained->mpm->num_buckets * sizeof(int));
+ retained->idle_spawn_rate = new_ptr;
+ retained->mpm->max_buckets = new_max;
+ }
+ if (retained->mpm->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->mpm->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->mpm->num_buckets = num_buckets;
+
/* Don't thrash since num_buckets depends on the
* system and the number of online CPU cores...
*/
@@ -1763,8 +1872,8 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
ap_log_mpm_common(s);
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(00294)
"Accept mutex: %s (default: %s)",
- (all_buckets[0].mutex)
- ? apr_proc_mutex_name(all_buckets[0].mutex)
+ (retained->buckets[0].mutex)
+ ? apr_proc_mutex_name(retained->buckets[0].mutex)
: "none",
apr_proc_mutex_defname());
retained->mpm->mpm_state = AP_MPMQ_RUNNING;
@@ -1777,8 +1886,8 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
* Kill child processes, tell them to call child_exit, etc...
*/
for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
- AP_MPM_PODX_RESTART);
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ ap_daemons_limit, AP_MPM_PODX_RESTART);
}
ap_reclaim_child_processes(1, /* Start with SIGTERM */
worker_note_child_killed);
@@ -1804,8 +1913,8 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
ap_close_listeners();
for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
- AP_MPM_PODX_GRACEFUL);
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ ap_daemons_limit, AP_MPM_PODX_GRACEFUL);
}
ap_relieve_child_processes(worker_note_child_killed);
@@ -1847,8 +1956,8 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
* really dead.
*/
for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
- AP_MPM_PODX_RESTART);
+ ap_mpm_podx_killpg(retained->buckets[i].pod,
+ ap_daemons_limit, AP_MPM_PODX_RESTART);
}
ap_reclaim_child_processes(1, worker_note_child_killed);
@@ -1861,43 +1970,15 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
return DONE;
}
- /* advance to the next generation */
- /* XXX: we really need to make sure this new generation number isn't in
- * use by any of the children.
- */
- ++retained->mpm->my_generation;
- ap_scoreboard_image->global->running_generation = retained->mpm->my_generation;
-
if (!retained->mpm->is_ungraceful) {
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00297)
- AP_SIG_GRACEFUL_STRING " received. Doing graceful restart");
- /* wake up the children...time to die. But we'll have more soon */
- for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
- AP_MPM_PODX_GRACEFUL);
- }
-
- /* This is mostly for debugging... so that we know what is still
- * gracefully dealing with existing request.
- */
-
+ "%s received. Doing graceful restart",
+ AP_SIG_GRACEFUL_STRING);
}
else {
- /* Kill 'em all. Since the child acts the same on the parents SIGTERM
- * and a SIGHUP, we may as well use the same signal, because some user
- * pthreads are stealing signals from us left and right.
- */
- for (i = 0; i < num_buckets; i++) {
- ap_mpm_podx_killpg(all_buckets[i].pod, ap_daemons_limit,
- AP_MPM_PODX_RESTART);
- }
-
- ap_reclaim_child_processes(1, /* Start with SIGTERM */
- worker_note_child_killed);
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00298)
- "SIGHUP received. Attempting to restart");
+ "SIGHUP received. Attempting to restart");
}
-
return OK;
}
@@ -1908,11 +1989,6 @@ 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];
- int i;
pconf = p;
@@ -1929,73 +2005,6 @@ static int worker_open_logs(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp,
return !OK;
}
- if (one_process) {
- num_buckets = 1;
- }
- else if (retained->mpm->was_graceful) {
- /* Preserve the number of buckets on graceful restarts. */
- num_buckets = retained->mpm->num_buckets;
- }
- if ((rv = ap_duplicate_listeners(pconf, ap_server_conf,
- &listen_buckets, &num_buckets))) {
- ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
- (startup ? NULL : s), APLOGNO(03291)
- "could not duplicate listeners");
- return !OK;
- }
-
- 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))) {
- ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
- (startup ? NULL : s), APLOGNO(03292)
- "could not open pipe-of-death");
- return !OK;
- }
- /* 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,
- id, s, pconf, 0))))) {
- ap_log_error(APLOG_MARK, APLOG_CRIT | level_flags, rv,
- (startup ? NULL : s), APLOGNO(03293)
- "could not create accept mutex");
- return !OK;
- }
- all_buckets[i].listeners = listen_buckets[i];
- }
-
- if (retained->mpm->max_buckets < num_buckets) {
- int new_max, *new_ptr;
- new_max = retained->mpm->max_buckets * 2;
- if (new_max < num_buckets) {
- new_max = num_buckets;
- }
- new_ptr = (int *)apr_palloc(ap_pglobal, new_max * sizeof(int));
- if (retained->idle_spawn_rate) /* NULL at startup */
- memcpy(new_ptr, retained->idle_spawn_rate,
- retained->mpm->num_buckets * sizeof(int));
- retained->idle_spawn_rate = new_ptr;
- retained->mpm->max_buckets = new_max;
- }
- if (retained->mpm->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->mpm->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->mpm->num_buckets = num_buckets;
-
return OK;
}
@@ -2024,13 +2033,10 @@ static int worker_pre_config(apr_pool_t *pconf, apr_pool_t *plog,
if (!retained) {
retained = ap_retained_data_create(userdata_key, sizeof(*retained));
retained->mpm = ap_unixd_mpm_get_retained_data();
+ retained->mpm->baton = retained;
retained->max_daemons_limit = -1;
}
retained->mpm->mpm_state = AP_MPMQ_STARTING;
- if (retained->mpm->baton != retained) {
- retained->mpm->was_graceful = 0;
- retained->mpm->baton = retained;
- }
++retained->mpm->module_loads;
/* sigh, want this only the second time around */