From 83a4a4886e0508eaa6e457c5247e87dcb42e12a2 Mon Sep 17 00:00:00 2001 From: Graham Leggett Date: Mon, 13 Jun 2016 23:40:00 +0000 Subject: [PATCH] mpm_event, mpm_worker: Fix computation of MinSpareThreads' lower bound according the number of listeners buckets. Submitted by: ylavic Reviewed by: jim, minfrin git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1748336 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ STATUS | 7 ------- server/mpm/event/event.c | 14 +++++++------- server/mpm/worker/worker.c | 16 +++++++++------- 4 files changed, 19 insertions(+), 21 deletions(-) diff --git a/CHANGES b/CHANGES index b032de44de..7173c827a1 100644 --- a/CHANGES +++ b/CHANGES @@ -2,6 +2,9 @@ Changes with Apache 2.4.21 + *) mpm_event, mpm_worker: Fix computation of MinSpareThreads' lower bound + according the number of listeners buckets. [Yann Ylavic] + *) Add ap_cstr_casecmp[n]() - placeholder of apr_cstr_casecmp[n] functions for case-insensitive C/POSIX-locale token comparison. [Jim Jagielski, William Rowe, Yann Ylavic, Branko Čibej] diff --git a/STATUS b/STATUS index 0108746d21..01ef2508df 100644 --- a/STATUS +++ b/STATUS @@ -114,13 +114,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - *) mpm_event, mpm_worker: Fix computation of MinSpareThreads' lower bound - according the number of listeners buckets. - trunk patch: http://svn.apache.org/r1737447 - http://svn.apache.org/r1737449 - http://svn.apache.org/r1737451 - 2.4.x patch: trunk works (modulo CHANGES) - +1: ylavic, jim, minfrin PATCHES PROPOSED TO BACKPORT FROM TRUNK: diff --git a/server/mpm/event/event.c b/server/mpm/event/event.c index 9dd91cde2e..89ee47671d 100644 --- a/server/mpm/event/event.c +++ b/server/mpm/event/event.c @@ -2017,8 +2017,7 @@ static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy) thread_starter *ts = dummy; apr_thread_t **threads = ts->threads; apr_threadattr_t *thread_attr = ts->threadattr; - int child_num_arg = ts->child_num_arg; - int my_child_num = child_num_arg; + int my_child_num = ts->child_num_arg; proc_info *my_info; apr_status_t rv; int i; @@ -2102,7 +2101,7 @@ static void *APR_THREAD_FUNC start_threads(apr_thread_t * thd, void *dummy) /* threads_per_child does not include the listener thread */ for (i = 0; i < threads_per_child; i++) { int status = - ap_scoreboard_image->servers[child_num_arg][i].status; + ap_scoreboard_image->servers[my_child_num][i].status; if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { continue; @@ -2524,13 +2523,14 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) int all_dead_threads = 1; int child_threads_active = 0; - if (i >= retained->max_daemons_limit - && totally_free_length == retained->idle_spawn_rate[child_bucket]) + if (i >= retained->max_daemons_limit && + totally_free_length == retained->idle_spawn_rate[child_bucket]) { /* short cut if all active processes have been examined and * enough empty scoreboard slots have been found */ break; + } ps = &ap_scoreboard_image->parent[i]; for (j = 0; j < threads_per_child; j++) { ws = &ap_scoreboard_image->servers[i][j]; @@ -2829,8 +2829,8 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s) 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 (min_spare_threads < threads_per_child * (num_buckets - 1) + num_buckets) + min_spare_threads = threads_per_child * (num_buckets - 1) + num_buckets; if (max_spare_threads < min_spare_threads + threads_per_child * num_buckets) max_spare_threads = min_spare_threads + threads_per_child * num_buckets; diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index 01a86cb3a5..d15ffa207c 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -1046,8 +1046,7 @@ static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) thread_starter *ts = dummy; apr_thread_t **threads = ts->threads; apr_threadattr_t *thread_attr = ts->threadattr; - int child_num_arg = ts->child_num_arg; - int my_child_num = child_num_arg; + int my_child_num = ts->child_num_arg; proc_info *my_info; apr_status_t rv; int i; @@ -1081,7 +1080,7 @@ static void * APR_THREAD_FUNC start_threads(apr_thread_t *thd, void *dummy) while (1) { /* threads_per_child does not include the listener thread */ for (i = 0; i < threads_per_child; i++) { - int status = ap_scoreboard_image->servers[child_num_arg][i].status; + int status = ap_scoreboard_image->servers[my_child_num][i].status; if (status != SERVER_GRACEFUL && status != SERVER_DEAD) { continue; @@ -1518,11 +1517,13 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) int all_dead_threads = 1; int child_threads_active = 0; - if (i >= retained->max_daemons_limit && totally_free_length == retained->idle_spawn_rate[child_bucket]) + if (i >= retained->max_daemons_limit && + totally_free_length == retained->idle_spawn_rate[child_bucket]) { /* short cut if all active processes have been examined and * enough empty scoreboard slots have been found */ break; + } ps = &ap_scoreboard_image->parent[i]; for (j = 0; j < threads_per_child; j++) { ws = &ap_scoreboard_image->servers[i][j]; @@ -1556,7 +1557,8 @@ static void perform_idle_server_maintenance(int child_bucket, int num_buckets) } } active_thread_count += child_threads_active; - if (any_dead_threads && totally_free_length < retained->idle_spawn_rate[child_bucket] + if (any_dead_threads + && totally_free_length < retained->idle_spawn_rate[child_bucket] && free_length < MAX_SPAWN_RATE / num_buckets && (!ps->pid /* no process in the slot */ || ps->quiescing)) { /* or at least one is going away */ @@ -1834,8 +1836,8 @@ static int worker_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s) 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 (min_spare_threads < threads_per_child * (num_buckets - 1) + num_buckets) + min_spare_threads = threads_per_child * (num_buckets - 1) + num_buckets; if (max_spare_threads < min_spare_threads + threads_per_child * num_buckets) max_spare_threads = min_spare_threads + threads_per_child * num_buckets; -- 2.50.0