summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorYann Ylavic <ylavic@apache.org>2019-03-12 10:45:02 +0000
committerYann Ylavic <ylavic@apache.org>2019-03-12 10:45:02 +0000
commit0900b36b70df8ca3939df65a98f12c0c5f537d3b (patch)
tree04562ab737d3f24369d1dcec21a09ff3949704aa /server
parent93f20aaeba6aa071be8764bbbace1432e732738b (diff)
downloadhttpd-0900b36b70df8ca3939df65a98f12c0c5f537d3b.tar.gz
MPMs unix: bind the bucket number of each child to its slot number
We need not remember each child's bucket number in SHM for restarts, for the lifetime of the httpd main process the bucket number can be bound to the slot number such that: bucket = slot % num_buckets. This both simplifies the logic and helps children maintenance per bucket in threaded MPMs, where previously perform_idle_server_maintenance() could create or kill children processes for the buckets it was not in charge of. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1855306 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'server')
-rw-r--r--server/mpm/event/event.c13
-rw-r--r--server/mpm/motorz/motorz.c19
-rw-r--r--server/mpm/prefork/prefork.c19
-rw-r--r--server/mpm/worker/worker.c10
4 files changed, 28 insertions, 33 deletions
diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c
index 1458a8cc80..4bb2d5bd0f 100644
--- a/server/mpm/event/event.c
+++ b/server/mpm/event/event.c
@@ -2977,7 +2977,6 @@ static int make_child(server_rec * s, int slot, int bucket)
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);
active_daemons++;
retained->total_daemons++;
@@ -3016,6 +3015,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
* that threads_per_child is always > 0 */
int status = SERVER_DEAD;
int child_threads_active = 0;
+ int bucket = i % num_buckets;
if (i >= retained->max_daemons_limit &&
free_length == retained->idle_spawn_rate[child_bucket]) {
@@ -3039,7 +3039,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
*/
if (status <= SERVER_READY && !ps->quiescing && !ps->not_accepting
&& ps->generation == retained->mpm->my_generation
- && ps->bucket == child_bucket)
+ && bucket == child_bucket)
{
++idle_thread_count;
}
@@ -3050,7 +3050,9 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
last_non_dead = i;
}
active_thread_count += child_threads_active;
- if (!ps->pid && free_length < retained->idle_spawn_rate[child_bucket])
+ if (!ps->pid
+ && bucket == child_bucket
+ && free_length < retained->idle_spawn_rate[child_bucket])
free_slots[free_length++] = i;
else if (child_threads_active == threads_per_child)
had_healthy_child = 1;
@@ -3243,13 +3245,14 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets)
retained->total_daemons--;
if (processed_status == APEXIT_CHILDSICK) {
/* resource shortage, minimize the fork rate */
- retained->idle_spawn_rate[ps->bucket] = 1;
+ retained->idle_spawn_rate[child_slot % num_buckets] = 1;
}
else if (remaining_children_to_start) {
/* we're still doing a 1-for-1 replacement of dead
* children with new children
*/
- make_child(ap_server_conf, child_slot, ps->bucket);
+ make_child(ap_server_conf, child_slot,
+ child_slot % num_buckets);
--remaining_children_to_start;
}
}
diff --git a/server/mpm/motorz/motorz.c b/server/mpm/motorz/motorz.c
index fe31e147a9..7fd9430591 100644
--- a/server/mpm/motorz/motorz.c
+++ b/server/mpm/motorz/motorz.c
@@ -948,8 +948,9 @@ static void child_main(motorz_core_t *mz, int child_num_arg, int child_bucket)
clean_child_exit(0);
}
-static int make_child(motorz_core_t *mz, server_rec *s, int slot, int bucket)
+static int make_child(motorz_core_t *mz, server_rec *s, int slot)
{
+ int bucket = slot % mz->mpm->num_buckets;
int pid;
if (slot + 1 > mz->max_daemons_limit) {
@@ -1020,7 +1021,6 @@ static int make_child(motorz_core_t *mz, server_rec *s, int slot, int bucket)
child_main(mz, slot, bucket);
}
- ap_scoreboard_image->parent[slot].bucket = bucket;
motorz_note_child_started(mz, slot, pid);
return 0;
@@ -1036,7 +1036,7 @@ static void startup_children(motorz_core_t *mz, int number_to_start)
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
continue;
}
- if (make_child(mz, ap_server_conf, i, i % mz->mpm->num_buckets) < 0) {
+ if (make_child(mz, ap_server_conf, i) < 0) {
break;
}
--number_to_start;
@@ -1045,8 +1045,6 @@ static void startup_children(motorz_core_t *mz, int number_to_start)
static void perform_idle_server_maintenance(motorz_core_t *mz, apr_pool_t *p)
{
- static int bucket_make_child_record = -1;
- static int bucket_kill_child_record = -1;
int free_length;
int free_slots[1];
@@ -1070,6 +1068,7 @@ static void perform_idle_server_maintenance(motorz_core_t *mz, apr_pool_t *p)
}
}
if (active > ap_num_kids) {
+ static int bucket_kill_child_record = -1;
/* kill off one child... we use the pod because that'll cause it to
* shut down gracefully, in case it happened to pick up a request
* while we were counting
@@ -1078,10 +1077,7 @@ static void perform_idle_server_maintenance(motorz_core_t *mz, apr_pool_t *p)
ap_mpm_pod_signal(all_buckets[bucket_kill_child_record].pod);
}
else if (active < ap_num_kids) {
- bucket_make_child_record++;
- bucket_make_child_record %= mz->mpm->num_buckets;
- make_child(mz, ap_server_conf, free_slots[0],
- bucket_make_child_record);
+ make_child(mz, ap_server_conf, free_slots[0]);
}
}
@@ -1113,7 +1109,7 @@ static int motorz_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
if (one_process) {
AP_MONCONTROL(1);
- make_child(mz, ap_server_conf, 0, 0);
+ make_child(mz, ap_server_conf, 0);
/* NOTREACHED */
ap_assert(0);
return !OK;
@@ -1201,8 +1197,7 @@ static int motorz_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
/* we're still doing a 1-for-1 replacement of dead
* children with new children
*/
- make_child(mz, ap_server_conf, child_slot,
- ap_get_scoreboard_process(child_slot)->bucket);
+ make_child(mz, ap_server_conf, child_slot);
--remaining_children_to_start;
}
#if APR_HAS_OTHER_CHILD
diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c
index 78e64ab64d..36577fda78 100644
--- a/server/mpm/prefork/prefork.c
+++ b/server/mpm/prefork/prefork.c
@@ -643,8 +643,9 @@ static void child_main(int child_num_arg, int child_bucket)
}
-static int make_child(server_rec *s, int slot, int bucket)
+static int make_child(server_rec *s, int slot)
{
+ int bucket = slot % retained->mpm->num_buckets;
int pid;
if (slot + 1 > retained->max_daemons_limit) {
@@ -722,7 +723,6 @@ static int make_child(server_rec *s, int slot, int bucket)
child_main(slot, bucket);
}
- ap_scoreboard_image->parent[slot].bucket = bucket;
prefork_note_child_started(slot, pid);
return 0;
@@ -738,7 +738,7 @@ static void startup_children(int number_to_start)
if (ap_scoreboard_image->servers[i][0].status != SERVER_DEAD) {
continue;
}
- if (make_child(ap_server_conf, i, i % retained->mpm->num_buckets) < 0) {
+ if (make_child(ap_server_conf, i) < 0) {
break;
}
--number_to_start;
@@ -747,8 +747,6 @@ static void startup_children(int number_to_start)
static void perform_idle_server_maintenance(apr_pool_t *p)
{
- static int bucket_make_child_record = -1;
- static int bucket_kill_child_record = -1;
int i;
int idle_count;
worker_score *ws;
@@ -795,6 +793,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p)
}
retained->max_daemons_limit = last_non_dead + 1;
if (idle_count > ap_daemons_max_free) {
+ static int bucket_kill_child_record = -1;
/* kill off one child... we use the pod because that'll cause it to
* shut down gracefully, in case it happened to pick up a request
* while we were counting
@@ -825,10 +824,7 @@ static void perform_idle_server_maintenance(apr_pool_t *p)
idle_count, total_non_dead);
}
for (i = 0; i < free_length; ++i) {
- bucket_make_child_record++;
- bucket_make_child_record %= retained->mpm->num_buckets;
- make_child(ap_server_conf, free_slots[i],
- bucket_make_child_record);
+ make_child(ap_server_conf, free_slots[i]);
}
/* 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
@@ -873,7 +869,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
if (one_process) {
AP_MONCONTROL(1);
- make_child(ap_server_conf, 0, 0);
+ make_child(ap_server_conf, 0);
/* NOTREACHED */
ap_assert(0);
return !OK;
@@ -982,8 +978,7 @@ static int prefork_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s)
/* we're still doing a 1-for-1 replacement of dead
* children with new children
*/
- make_child(ap_server_conf, child_slot,
- ap_get_scoreboard_process(child_slot)->bucket);
+ make_child(ap_server_conf, child_slot);
--remaining_children_to_start;
}
#if APR_HAS_OTHER_CHILD
diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c
index 26fc324262..b977e5a23d 100644
--- a/server/mpm/worker/worker.c
+++ b/server/mpm/worker/worker.c
@@ -1344,7 +1344,6 @@ static int make_child(server_rec *s, int slot, int bucket)
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;
}
@@ -1393,6 +1392,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
int any_dead_threads = 0;
int all_dead_threads = 1;
int child_threads_active = 0;
+ int bucket = i % num_buckets;
if (i >= retained->max_daemons_limit &&
totally_free_length == retained->idle_spawn_rate[child_bucket]) {
@@ -1425,7 +1425,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
if (status <= SERVER_READY &&
!ps->quiescing &&
ps->generation == retained->mpm->my_generation &&
- ps->bucket == child_bucket) {
+ bucket == child_bucket) {
++idle_thread_count;
}
if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
@@ -1435,6 +1435,7 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets)
}
active_thread_count += child_threads_active;
if (any_dead_threads
+ && bucket == child_bucket
&& totally_free_length < retained->idle_spawn_rate[child_bucket]
&& free_length < MAX_SPAWN_RATE / num_buckets
&& (!ps->pid /* no process in the slot */
@@ -1620,14 +1621,15 @@ static void server_main_loop(int remaining_children_to_start, int num_buckets)
ps->quiescing = 0;
if (processed_status == APEXIT_CHILDSICK) {
/* resource shortage, minimize the fork rate */
- retained->idle_spawn_rate[ps->bucket] = 1;
+ retained->idle_spawn_rate[child_slot % num_buckets] = 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, ps->bucket);
+ make_child(ap_server_conf, child_slot,
+ child_slot % num_buckets);
--remaining_children_to_start;
}
}