diff -ru ./src/include/http_conf_globals.h /home/lonerr/tmp/apache13/apache_1.3.41/src/include/http_conf_globals.h --- ./src/include/http_conf_globals.h 2006-07-12 12:16:05.000000000 +0400 +++ /home/lonerr/tmp/apache13/apache_1.3.41/src/include/http_conf_globals.h 2008-03-06 14:34:45.000000000 +0300 @@ -45,6 +45,7 @@ extern API_VAR_EXPORT int ap_daemons_to_start; extern API_VAR_EXPORT int ap_daemons_min_free; extern API_VAR_EXPORT int ap_daemons_max_free; +extern API_VAR_EXPORT int ap_spare_reaper_delay; extern API_VAR_EXPORT int ap_daemons_limit; extern API_VAR_EXPORT int ap_suexec_enabled; extern API_VAR_EXPORT int ap_listenbacklog; diff -ru ./src/main/http_core.c /home/lonerr/tmp/apache13/apache_1.3.41/src/main/http_core.c --- ./src/main/http_core.c 2006-07-12 12:16:05.000000000 +0400 +++ /home/lonerr/tmp/apache13/apache_1.3.41/src/main/http_core.c 2008-03-06 14:34:53.000000000 +0300 @@ -2478,6 +2478,17 @@ return NULL; } +static const char *set_spare_reaper_delay(cmd_parms *cmd, void *dummy, char *arg) +{ + const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); + if (err != NULL) { + return err; + } + + ap_spare_reaper_delay = atoi(arg); + return NULL; +} + static const char *set_server_limit (cmd_parms *cmd, void *dummy, char *arg) { const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY); @@ -3616,6 +3627,8 @@ "Minimum number of idle children, to handle request spikes" }, { "MaxSpareServers", set_max_free_servers, NULL, RSRC_CONF, TAKE1, "Maximum number of idle children" }, +{ "SpareReaperDelay", set_spare_reaper_delay, NULL, RSRC_CONF, TAKE1, + "Delay to kill spare servers" }, { "MaxServers", set_max_free_servers, NULL, RSRC_CONF, TAKE1, "Deprecated equivalent to MaxSpareServers" }, { "ServersSafetyLimit", set_server_limit, NULL, RSRC_CONF, TAKE1, diff -ru ./src/main/http_main.c /home/lonerr/tmp/apache13/apache_1.3.41/src/main/http_main.c --- ./src/main/http_main.c 2007-11-16 00:31:15.000000000 +0300 +++ /home/lonerr/tmp/apache13/apache_1.3.41/src/main/http_main.c 2008-03-06 14:34:53.000000000 +0300 @@ -214,6 +214,7 @@ API_VAR_EXPORT int ap_daemons_to_start=0; API_VAR_EXPORT int ap_daemons_min_free=0; API_VAR_EXPORT int ap_daemons_max_free=0; +API_VAR_EXPORT int ap_spare_reaper_delay=0; API_VAR_EXPORT int ap_daemons_limit=0; API_VAR_EXPORT time_t ap_restart_time=0; API_VAR_EXPORT int ap_suexec_enabled = 0; @@ -5117,7 +5118,7 @@ #define SIG_TIMEOUT_KILL SIGALRM #endif -static void perform_idle_server_maintenance(void) +static void perform_idle_server_maintenance(int *rloop) { int i; int to_kill; @@ -5209,11 +5210,20 @@ */ pid = ap_scoreboard_image->parent[to_kill].pid; if (in_pid_table(pid)) { - kill(pid, SIG_IDLE_KILL); - idle_spawn_rate = 1; + if (*rloop >= ap_spare_reaper_delay) { + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf, + "reaping spare child (pid: %d, delay: %d/%d)", pid, *rloop, ap_spare_reaper_delay); + kill(pid, SIG_IDLE_KILL); + idle_spawn_rate = 1; + *rloop = 0; #ifdef TPF - ap_update_child_status(to_kill, SERVER_DEAD, (request_rec *)NULL); + ap_update_child_status(to_kill, SERVER_DEAD, (request_rec *)NULL); #endif + } else { + ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_DEBUG, server_conf, + "empty reaper cycle (delay: %d/%d)", *rloop, ap_spare_reaper_delay); + ++*rloop; + } } else { ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, server_conf, @@ -5221,6 +5231,7 @@ } } else if (idle_count < ap_daemons_min_free) { + *rloop = 0; /* terminate the free list */ if (free_length == 0) { /* only report this condition once */ @@ -5268,6 +5279,7 @@ } } else { + *rloop = 0; idle_spawn_rate = 1; } } @@ -5450,6 +5462,7 @@ amutex->name, ap_default_mutex_method()); restart_pending = shutdown_pending = 0; + int reaper_loop = 0; while (!restart_pending && !shutdown_pending) { int child_slot; ap_wait_t status; @@ -5517,7 +5530,7 @@ continue; } - perform_idle_server_maintenance(); + perform_idle_server_maintenance(&reaper_loop); } if (shutdown_pending) {