* 20140627.5 (2.5.0-dev) Add r->trailers_{in,out}
* 20140627.6 (2.5.0-dev) Added ap_pcre_version_string(), AP_REG_PCRE_COMPILED
* and AP_REG_PCRE_LOADED to ap_regex.h.
+ * 20140627.7 (2.5.0-dev) Add listener bucket in scoreboard.h's process_score.
*/
#define MODULE_MAGIC_COOKIE 0x41503235UL /* "AP25" */
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20140627
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 6 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 7 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
apr_uint32_t lingering_close; /* async connections in lingering close */
apr_uint32_t keep_alive; /* async connections in keep alive */
apr_uint32_t suspended; /* connections suspended by some module */
+ int bucket; /* Listener bucket used by this child */
};
/* Scoreboard is now in 'local' memory, since it isn't updated once created,
static ap_pod_t **pod;
static ap_pod_t *child_pod;
static ap_listen_rec *child_listen;
-static int *bucket; /* bucket array for the httpd child processes */
/* The event MPM respects a couple of runtime flags that can aid
* in debugging. Setting the -DNO_DETACH flag will prevent the root process
}
}
-static void child_main(int child_num_arg)
+static void child_main(int child_num_arg, int child_bucket)
{
apr_thread_t **threads;
apr_status_t rv;
ap_fatal_signal_child_setup(ap_server_conf);
apr_pool_create(&pchild, pconf);
+ child_listen = mpm_listen[child_bucket];
+ child_pod = pod[child_bucket];
+
/* close unused listeners and pods */
for (i = 0; i < num_buckets; i++) {
- if (i != bucket[child_num_arg]) {
+ if (i != child_bucket) {
lr = mpm_listen[i];
while(lr) {
apr_socket_close(lr->sd);
clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
}
-static int make_child(server_rec * s, int slot)
+static int make_child(server_rec * s, int slot, int bucket)
{
int pid;
retained->max_daemons_limit = slot + 1;
}
- child_listen = mpm_listen[bucket[slot]];
- child_pod = pod[bucket[slot]];
-
if (one_process) {
set_signals();
event_note_child_started(slot, getpid());
- child_main(slot);
+ child_main(0, 0);
/* NOTREACHED */
}
RAISE_SIGSTOP(MAKE_CHILD);
apr_signal(SIGTERM, just_die);
- child_main(slot);
+ child_main(slot, bucket);
/* NOTREACHED */
}
/* else */
}
ap_scoreboard_image->parent[slot].quiescing = 0;
ap_scoreboard_image->parent[slot].not_accepting = 0;
+ ap_scoreboard_image->parent[slot].bucket = bucket;
event_note_child_started(slot, pid);
return 0;
}
if (ap_scoreboard_image->parent[i].pid != 0) {
continue;
}
- bucket[i] = i % num_buckets;
- if (make_child(ap_server_conf, i) < 0) {
+ if (make_child(ap_server_conf, i, i % num_buckets) < 0) {
break;
}
--number_to_start;
if (ps->pid != 0) { /* XXX just set all_dead_threads in outer
for loop if no pid? not much else matters */
if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
- && ps->generation == retained->my_generation &&
- bucket[i] == child_bucket)
+ && ps->generation == retained->my_generation
+ && ps->bucket == child_bucket)
{
++idle_thread_count;
}
active_thread_count += child_threads_active;
if (any_dead_threads
&& totally_free_length < retained->idle_spawn_rate[child_bucket]
- && free_length < MAX_SPAWN_RATE/num_buckets
+ && free_length < MAX_SPAWN_RATE / num_buckets
&& (!ps->pid /* no process in the slot */
|| ps->quiescing)) { /* or at least one is going away */
if (all_dead_threads) {
retained->max_daemons_limit = last_non_dead + 1;
- if (idle_thread_count > max_spare_threads/num_buckets) {
+ if (idle_thread_count > max_spare_threads / num_buckets) {
/* Kill off one child */
ap_mpm_podx_signal(pod[child_bucket], AP_MPM_PODX_GRACEFUL);
retained->idle_spawn_rate[child_bucket] = 1;
}
- else if (idle_thread_count < min_spare_threads/num_buckets) {
+ else if (idle_thread_count < min_spare_threads) {
/* terminate the free list */
if (free_length == 0) { /* scoreboard is full, can't fork */
idle_thread_count, total_non_dead);
}
for (i = 0; i < free_length; ++i) {
- bucket[free_slots[i]] = child_bucket;
- make_child(ap_server_conf, free_slots[i]);
+ make_child(ap_server_conf, free_slots[i], child_bucket);
}
/* the next time around we want to spawn twice as many if this
* wasn't good enough, but not if we've just done a graceful
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;
}
}
}
/* non-fatal death... note that it's gone in the scoreboard. */
if (child_slot >= 0) {
+ process_score *ps;
+
for (i = 0; i < threads_per_child; i++)
ap_update_child_status_from_indexes(child_slot, i,
SERVER_DEAD,
(request_rec *) NULL);
event_note_child_killed(child_slot, 0, 0);
- ap_scoreboard_image->parent[child_slot].quiescing = 0;
+ ps = &ap_scoreboard_image->parent[child_slot];
+ ps->quiescing = 0;
if (processed_status == APEXIT_CHILDSICK) {
/* resource shortage, minimize the fork rate */
- retained->idle_spawn_rate[bucket[child_slot]] = 1;
+ retained->idle_spawn_rate[ps->bucket] = 1;
}
else if (remaining_children_to_start
&& child_slot < ap_daemons_limit) {
/* we're still doing a 1-for-1 replacement of dead
* children with new children
*/
- make_child(ap_server_conf, child_slot);
+ make_child(ap_server_conf, child_slot, ps->bucket);
--remaining_children_to_start;
}
}
ap_scoreboard_image->global->running_generation = retained->my_generation;
}
- bucket = apr_palloc(_pconf, sizeof(int) * ap_daemons_limit);
-
restart_pending = shutdown_pending = 0;
set_signals();
/* Don't thrash... */
int level_flags = 0;
apr_status_t rv;
int i;
- int num_of_cores = 0;
pconf = p;
}
enable_default_listener = 0;
-
if ((num_listensocks = ap_setup_listeners(ap_server_conf)) < 1) {
ap_log_error(APLOG_MARK, APLOG_ALERT | level_flags, 0,
(startup ? NULL : s),
}
enable_default_listener = 1;
- if (have_so_reuseport) {
-#ifdef _SC_NPROCESSORS_ONLN
- num_of_cores = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- num_of_cores = 1;
-#endif
- if (num_of_cores > 8) {
- num_buckets = num_of_cores/8;
- }
- else {
- num_buckets = 1;
- }
- }
- else {
- num_buckets = 1;
- }
ap_duplicate_listeners(ap_server_conf, pconf, num_buckets);
retained = ap_retained_data_create(userdata_key, sizeof(*retained));
retained->max_daemons_limit = -1;
}
+ if (!retained->is_graceful) {
+ num_buckets = 1;
+#ifdef _SC_NPROCESSORS_ONLN
+ if (have_so_reuseport) {
+ int num_online_cores = sysconf(_SC_NPROCESSORS_ONLN);
+ if (num_online_cores > 8) {
+ num_buckets = num_online_cores / 8;
+ }
+ }
+#endif
+ }
++retained->module_loads;
if (retained->module_loads == 2) {
/* test for correct operation of fdqueue */
}
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 < 0) {
+ if (ap_daemons_to_start < 1) {
if (startup) {
ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00517)
"WARNING: StartServers of %d not allowed, "
}
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) {
}
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()
static ap_pod_t **pod;
static ap_pod_t *child_pod;
static ap_listen_rec *child_listen;
-static int *bucket; /* bucket array for the httpd child processes */
/* The eventopt MPM respects a couple of runtime flags that can aid
* in debugging. Setting the -DNO_DETACH flag will prevent the root process
}
}
-static void child_main(int child_num_arg)
+static void child_main(int child_num_arg, int child_bucket)
{
apr_thread_t **threads;
apr_status_t rv;
ap_fatal_signal_child_setup(ap_server_conf);
apr_pool_create(&pchild, pconf);
+ child_listen = mpm_listen[child_bucket];
+ child_pod = pod[child_bucket];
+
/* close unused listeners and pods */
for (i = 0; i < num_buckets; i++) {
- if (i != bucket[child_num_arg]) {
+ if (i != child_bucket) {
lr = mpm_listen[i];
while(lr) {
apr_socket_close(lr->sd);
clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
}
-static int make_child(server_rec * s, int slot)
+static int make_child(server_rec * s, int slot, int bucket)
{
int pid;
retained->max_daemons_limit = slot + 1;
}
- child_listen = mpm_listen[bucket[slot]];
- child_pod = pod[bucket[slot]];
-
if (one_process) {
set_signals();
event_note_child_started(slot, getpid());
- child_main(slot);
+ child_main(0, 0);
/* NOTREACHED */
}
RAISE_SIGSTOP(MAKE_CHILD);
apr_signal(SIGTERM, just_die);
- child_main(slot);
+ child_main(slot, bucket);
/* NOTREACHED */
}
/* else */
}
ap_scoreboard_image->parent[slot].quiescing = 0;
ap_scoreboard_image->parent[slot].not_accepting = 0;
+ ap_scoreboard_image->parent[slot].bucket = bucket;
event_note_child_started(slot, pid);
return 0;
}
if (ap_scoreboard_image->parent[i].pid != 0) {
continue;
}
- bucket[i] = i % num_buckets;
- if (make_child(ap_server_conf, i) < 0) {
+ if (make_child(ap_server_conf, i, i % num_buckets) < 0) {
break;
}
--number_to_start;
if (ps->pid != 0) { /* XXX just set all_dead_threads in outer
for loop if no pid? not much else matters */
if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
- && ps->generation == retained->my_generation &&
- bucket[i] == child_bucket)
+ && ps->generation == retained->my_generation
+ && ps->bucket == child_bucket)
{
++idle_thread_count;
}
active_thread_count += child_threads_active;
if (any_dead_threads
&& totally_free_length < retained->idle_spawn_rate[child_bucket]
- && free_length < MAX_SPAWN_RATE/num_buckets
+ && free_length < MAX_SPAWN_RATE / num_buckets
&& (!ps->pid /* no process in the slot */
|| ps->quiescing)) { /* or at least one is going away */
if (all_dead_threads) {
retained->max_daemons_limit = last_non_dead + 1;
- if (idle_thread_count > max_spare_threads/num_buckets) {
+ if (idle_thread_count > max_spare_threads / num_buckets) {
/* Kill off one child */
ap_mpm_podx_signal(pod[child_bucket], AP_MPM_PODX_GRACEFUL);
retained->idle_spawn_rate[child_bucket] = 1;
}
- else if (idle_thread_count < min_spare_threads/num_buckets) {
+ else if (idle_thread_count < min_spare_threads) {
/* terminate the free list */
if (free_length == 0) { /* scoreboard is full, can't fork */
idle_thread_count, total_non_dead);
}
for (i = 0; i < free_length; ++i) {
- bucket[free_slots[i]] = child_bucket;
- make_child(ap_server_conf, free_slots[i]);
+ make_child(ap_server_conf, free_slots[i], child_bucket);
}
/* the next time around we want to spawn twice as many if this
* wasn't good enough, but not if we've just done a graceful
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;
}
}
}
/* non-fatal death... note that it's gone in the scoreboard. */
if (child_slot >= 0) {
+ process_score *ps;
+
for (i = 0; i < threads_per_child; i++)
ap_update_child_status_from_indexes(child_slot, i,
SERVER_DEAD,
(request_rec *) NULL);
event_note_child_killed(child_slot, 0, 0);
- ap_scoreboard_image->parent[child_slot].quiescing = 0;
+ ps = &ap_scoreboard_image->parent[child_slot];
+ ps->quiescing = 0;
if (processed_status == APEXIT_CHILDSICK) {
/* resource shortage, minimize the fork rate */
- retained->idle_spawn_rate[bucket[child_slot]] = 1;
+ retained->idle_spawn_rate[ps->bucket] = 1;
}
else if (remaining_children_to_start
&& child_slot < ap_daemons_limit) {
/* we're still doing a 1-for-1 replacement of dead
* children with new children
*/
- make_child(ap_server_conf, child_slot);
+ make_child(ap_server_conf, child_slot, ps->bucket);
--remaining_children_to_start;
}
}
ap_scoreboard_image->global->running_generation = retained->my_generation;
}
- bucket = apr_palloc(_pconf, sizeof(int) * ap_daemons_limit);
-
restart_pending = shutdown_pending = 0;
set_signals();
/* Don't thrash... */
int level_flags = 0;
apr_status_t rv;
int i;
- int num_of_cores = 0;
pconf = p;
}
enable_default_listener = 1;
- if (have_so_reuseport) {
-#ifdef _SC_NPROCESSORS_ONLN
- num_of_cores = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- num_of_cores = 1;
-#endif
- if (num_of_cores > 8) {
- num_buckets = num_of_cores/8;
- }
- else {
- num_buckets = 1;
- }
- }
- else {
- num_buckets = 1;
- }
-
ap_duplicate_listeners(ap_server_conf, pconf, num_buckets);
pod = apr_palloc(pconf, sizeof(ap_pod_t *) * num_buckets);
retained = ap_retained_data_create(userdata_key, sizeof(*retained));
retained->max_daemons_limit = -1;
}
+ if (!retained->is_graceful) {
+ num_buckets = 1;
+#ifdef _SC_NPROCESSORS_ONLN
+ if (have_so_reuseport) {
+ int num_online_cores = sysconf(_SC_NPROCESSORS_ONLN);
+ if (num_online_cores > 8) {
+ num_buckets = num_online_cores / 8;
+ }
+ }
+#endif
+ }
++retained->module_loads;
if (retained->module_loads == 2) {
/* test for correct operation of fdqueue */
}
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 < 0) {
+ if (ap_daemons_to_start < 1) {
if (startup) {
ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00517)
"WARNING: StartServers of %d not allowed, "
}
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) {
}
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()
static ap_pod_t *child_pod;
static apr_proc_mutex_t *child_mutex;
static ap_listen_rec *child_listen;
-static int *bucket; /* bucket array for the httpd child processes */
/* data retained by prefork across load/unload of the module
static int requests_this_child;
static int num_listensocks = 0;
-static void child_main(int child_num_arg)
+static void child_main(int child_num_arg, int child_bucket)
{
#if APR_HAS_THREADS
apr_thread_t *thd = NULL;
ap_my_pid = getpid();
requests_this_child = 0;
+ child_listen = mpm_listen[child_bucket];
+ child_mutex = accept_mutex[child_bucket];
+ child_pod = pod[child_bucket];
+
ap_fatal_signal_child_setup(ap_server_conf);
/* Get a sub context for global allocations in this child, so that
/* close unused listeners and pods */
for (i = 0; i < num_buckets; i++) {
- if (i != bucket[my_child_num]) {
+ if (i != child_bucket) {
lr = mpm_listen[i];
while(lr) {
apr_socket_close(lr->sd);
}
-static int make_child(server_rec *s, int slot)
+static int make_child(server_rec *s, int slot, int bucket)
{
int pid;
retained->max_daemons_limit = slot + 1;
}
- child_listen = mpm_listen[bucket[slot]];
- child_mutex = accept_mutex[bucket[slot]];
- child_pod = pod[bucket[slot]];
-
if (one_process) {
apr_signal(SIGHUP, sig_term);
/* Don't catch AP_SIG_GRACEFUL in ONE_PROCESS mode :) */
#endif
apr_signal(SIGTERM, sig_term);
prefork_note_child_started(slot, getpid());
- child_main(slot);
+ child_main(slot, bucket);
/* NOTREACHED */
}
* The pod is used for signalling the graceful restart.
*/
apr_signal(AP_SIG_GRACEFUL, stop_listening);
- child_main(slot);
+ child_main(slot, bucket);
}
+ ap_scoreboard_image->parent[slot].bucket = bucket;
prefork_note_child_started(slot, pid);
return 0;
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
continue;
}
- bucket[i] = i % num_buckets;
- if (make_child(ap_server_conf, i) < 0) {
+ if (make_child(ap_server_conf, i, i % num_buckets) < 0) {
break;
}
--number_to_start;
idle_count, total_non_dead);
}
for (i = 0; i < free_length; ++i) {
- bucket[free_slots[i]]= (++bucket_make_child_record) % num_buckets;
- make_child(ap_server_conf, free_slots[i]);
+ bucket_make_child_record++;
+ make_child(ap_server_conf, free_slots[i],
+ bucket_make_child_record % num_buckets);
}
/* the next time around we want to spawn twice as many if this
* wasn't good enough, but not if we've just done a graceful
ap_log_pid(pconf, ap_pid_fname);
- bucket = apr_palloc(_pconf, sizeof(int) * ap_daemons_limit);
/* Initialize cross-process accept lock for each bucket*/
accept_mutex = apr_palloc(_pconf, sizeof(apr_proc_mutex_t *) * num_buckets);
for (i = 0; i < num_buckets; i++) {
if (one_process) {
AP_MONCONTROL(1);
- bucket[0] = 0;
- make_child(ap_server_conf, 0);
+ make_child(ap_server_conf, 0, 0);
/* NOTREACHED */
+ ap_assert(0);
+ return DONE;
}
- else {
- if (ap_daemons_max_free < ap_daemons_min_free + num_buckets) /* Don't thrash... */
+
+ /* Don't thrash... */
+ 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
/* we're still doing a 1-for-1 replacement of dead
* children with new children
*/
- make_child(ap_server_conf, child_slot);
+ make_child(ap_server_conf, child_slot,
+ ap_get_scoreboard_process(child_slot)->bucket);
--remaining_children_to_start;
}
#if APR_HAS_OTHER_CHILD
perform_idle_server_maintenance(pconf);
}
- } /* one_process */
mpm_state = AP_MPMQ_STOPPING;
int level_flags = 0;
apr_status_t rv;
int i;
- int num_of_cores = 0;
pconf = p;
}
enable_default_listener = 1;
- if (have_so_reuseport) {
-#ifdef _SC_NPROCESSORS_ONLN
- num_of_cores = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- num_of_cores = 1;
-#endif
- if (num_of_cores > 8) {
- num_buckets = num_of_cores/8;
- }
- else {
- num_buckets = 1;
- }
- }
- else {
- num_buckets = 1;
- }
-
ap_duplicate_listeners(ap_server_conf, pconf, num_buckets);
pod = apr_palloc(pconf, sizeof(ap_pod_t *) * num_buckets);
retained->max_daemons_limit = -1;
retained->idle_spawn_rate = 1;
}
+ if (!retained->is_graceful) {
+ num_buckets = 1;
+#ifdef _SC_NPROCESSORS_ONLN
+ if (have_so_reuseport) {
+ int num_online_cores = sysconf(_SC_NPROCESSORS_ONLN);
+ if (num_online_cores > 8) {
+ num_buckets = num_online_cores / 8;
+ }
+ }
+#endif
+ }
++retained->module_loads;
if (retained->module_loads == 2) {
if (!one_process && !foreground) {
}
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 < 0) {
}
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) {
}
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() */
static apr_proc_mutex_t **accept_mutex;
static apr_proc_mutex_t *child_mutex;
static ap_listen_rec *child_listen;
-static int *bucket; /* bucket array for the httpd child processes */
#ifdef SINGLE_LISTEN_UNSERIALIZED_ACCEPT
#define SAFE_ACCEPT(stmt) (child_listen->next ? (stmt) : APR_SUCCESS)
}
}
-static void child_main(int child_num_arg)
+static void child_main(int child_num_arg, int child_bucket)
{
apr_thread_t **threads;
apr_status_t rv;
ap_fatal_signal_child_setup(ap_server_conf);
apr_pool_create(&pchild, pconf);
+ child_listen = mpm_listen[child_bucket];
+ child_mutex = accept_mutex[child_bucket];
+ child_pod = pod[child_bucket];
+
/* close unused listeners and pods */
for (i = 0; i < num_buckets; i++) {
- if (i != bucket[child_num_arg]) {
+ if (i != child_bucket) {
lr = mpm_listen[i];
while(lr) {
apr_socket_close(lr->sd);
clean_child_exit(resource_shortage ? APEXIT_CHILDSICK : 0);
}
-static int make_child(server_rec *s, int slot)
+static int make_child(server_rec *s, int slot, int bucket)
{
int pid;
retained->max_daemons_limit = slot + 1;
}
- child_listen = mpm_listen[bucket[slot]];
- child_mutex = accept_mutex[bucket[slot]];
- child_pod = pod[bucket[slot]];
-
if (one_process) {
set_signals();
worker_note_child_started(slot, getpid());
- child_main(slot);
+ child_main(0, 0);
/* NOTREACHED */
}
RAISE_SIGSTOP(MAKE_CHILD);
apr_signal(SIGTERM, just_die);
- child_main(slot);
+ child_main(slot, bucket);
/* NOTREACHED */
}
/* else */
worker_note_child_lost_slot(slot, pid);
}
ap_scoreboard_image->parent[slot].quiescing = 0;
+ ap_scoreboard_image->parent[slot].bucket = bucket;
worker_note_child_started(slot, pid);
return 0;
}
if (ap_scoreboard_image->parent[i].pid != 0) {
continue;
}
- bucket[i] = i % num_buckets;
- if (make_child(ap_server_conf, i) < 0) {
+ if (make_child(ap_server_conf, i, i % num_buckets) < 0) {
break;
}
--number_to_start;
if (status <= SERVER_READY &&
!ps->quiescing &&
ps->generation == retained->my_generation &&
- bucket[i] == child_bucket) {
+ ps->bucket == child_bucket) {
++idle_thread_count;
}
if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
}
active_thread_count += child_threads_active;
if (any_dead_threads && totally_free_length < retained->idle_spawn_rate[child_bucket]
- && free_length < MAX_SPAWN_RATE/num_buckets
+ && free_length < MAX_SPAWN_RATE / num_buckets
&& (!ps->pid /* no process in the slot */
|| ps->quiescing)) { /* or at least one is going away */
if (all_dead_threads) {
retained->max_daemons_limit = last_non_dead + 1;
- if (idle_thread_count > max_spare_threads/num_buckets) {
+ if (idle_thread_count > max_spare_threads / num_buckets) {
/* Kill off one child */
ap_mpm_podx_signal(pod[child_bucket], AP_MPM_PODX_GRACEFUL);
retained->idle_spawn_rate[child_bucket] = 1;
}
- else if (idle_thread_count < min_spare_threads/num_buckets) {
+ else if (idle_thread_count < min_spare_threads) {
/* terminate the free list */
if (free_length == 0) { /* scoreboard is full, can't fork */
idle_thread_count, total_non_dead);
}
for (i = 0; i < free_length; ++i) {
- bucket[free_slots[i]] = child_bucket;
- make_child(ap_server_conf, free_slots[i]);
+ make_child(ap_server_conf, free_slots[i], child_bucket);
}
/* the next time around we want to spawn twice as many if this
* wasn't good enough, but not if we've just done a graceful
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;
}
}
}
else {
- retained->idle_spawn_rate[child_bucket] = 1;
+ retained->idle_spawn_rate[child_bucket] = 1;
}
}
}
/* non-fatal death... note that it's gone in the scoreboard. */
if (child_slot >= 0) {
+ process_score *ps;
+
for (i = 0; i < threads_per_child; i++)
ap_update_child_status_from_indexes(child_slot, i, SERVER_DEAD,
(request_rec *) NULL);
worker_note_child_killed(child_slot, 0, 0);
- ap_scoreboard_image->parent[child_slot].quiescing = 0;
+ ps = &ap_scoreboard_image->parent[child_slot];
+ ps->quiescing = 0;
if (processed_status == APEXIT_CHILDSICK) {
/* resource shortage, minimize the fork rate */
- retained->idle_spawn_rate[bucket[child_slot]] = 1;
+ retained->idle_spawn_rate[ps->bucket] = 1;
}
else if (remaining_children_to_start
&& child_slot < ap_daemons_limit) {
/* we're still doing a 1-for-1 replacement of dead
* children with new children
*/
- make_child(ap_server_conf, child_slot);
+ make_child(ap_server_conf, child_slot, ps->bucket);
--remaining_children_to_start;
}
}
ap_log_pid(pconf, ap_pid_fname);
- bucket = apr_palloc(_pconf, sizeof(int) * ap_daemons_limit);
/* Initialize cross-process accept lock */
accept_mutex = apr_palloc(_pconf, sizeof(apr_proc_mutex_t *) * num_buckets);
for (i = 0; i < num_buckets; i++) {
int level_flags = 0;
apr_status_t rv;
int i;
- int num_of_cores = 0;
pconf = p;
"no listening sockets available, shutting down");
return DONE;
}
- enable_default_listener = 1;
- if (have_so_reuseport) {
-#ifdef _SC_NPROCESSORS_ONLN
- num_of_cores = sysconf(_SC_NPROCESSORS_ONLN);
-#else
- num_of_cores = 1;
-#endif
- if (num_of_cores > 8) {
- num_buckets = num_of_cores/8;
- }
- else {
- num_buckets = 1;
- }
- }
- else {
- num_buckets = 1;
- }
+ enable_default_listener = 1;
ap_duplicate_listeners(ap_server_conf, pconf, num_buckets);
pod = apr_palloc(pconf, sizeof(ap_pod_t *) * num_buckets);
retained = ap_retained_data_create(userdata_key, sizeof(*retained));
retained->max_daemons_limit = -1;
}
+ if (!retained->is_graceful) {
+ num_buckets = 1;
+#ifdef _SC_NPROCESSORS_ONLN
+ if (have_so_reuseport) {
+ int num_online_cores = sysconf(_SC_NPROCESSORS_ONLN);
+ if (num_online_cores > 8) {
+ num_buckets = num_online_cores / 8;
+ }
+ }
+#endif
+ }
++retained->module_loads;
if (retained->module_loads == 2) {
if (!one_process && !foreground) {
}
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 < 0) {
+ if (ap_daemons_to_start < 1) {
if (startup) {
ap_log_error(APLOG_MARK, APLOG_WARNING | APLOG_STARTUP, 0, NULL, APLOGNO(00320)
"WARNING: StartServers of %d not allowed, "
}
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) {
}
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()