Skip to content

Commit 74b3a74

Browse files
authored
Add IdleTerminationTimeout to mpm_event
1 parent 38e7542 commit 74b3a74

1 file changed

Lines changed: 44 additions & 2 deletions

File tree

server/mpm/event/event.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,9 @@ static fd_queue_info_t *worker_queue_info;
199199

200200
static apr_thread_mutex_t *timeout_mutex;
201201

202+
static int idle_termination_timeout = -1; /* never terminate by default */
203+
static int idle_termination_remaining;
204+
202205
module AP_MODULE_DECLARE_DATA mpm_event_module;
203206

204207
/* forward declare */
@@ -444,6 +447,8 @@ typedef struct event_retained_data {
444447
*/
445448
int *idle_spawn_rate;
446449
int hold_off_on_exponential_spawning;
450+
451+
int idle_timeout; /* did we time out? */
447452
} event_retained_data;
448453
static event_retained_data *retained;
449454

@@ -3242,6 +3247,7 @@ static void perform_idle_server_maintenance(int child_bucket,
32423247
{
32433248
int num_buckets = retained->mpm->num_buckets;
32443249
int idle_thread_count = 0;
3250+
int total_thread_count = 0;
32453251
process_score *ps;
32463252
int free_length = 0;
32473253
int free_slots[MAX_SPAWN_RATE];
@@ -3292,6 +3298,7 @@ static void perform_idle_server_maintenance(int child_bucket,
32923298
if (status >= SERVER_READY && status < SERVER_GRACEFUL) {
32933299
++child_threads_active;
32943300
}
3301+
++total_thread_count;
32953302
}
32963303
active_thread_count += child_threads_active;
32973304
if (child_threads_active == threads_per_child) {
@@ -3338,6 +3345,21 @@ static void perform_idle_server_maintenance(int child_bucket,
33383345
&& retained->total_daemons <= retained->max_daemon_used
33393346
&& retained->max_daemon_used <= server_limit);
33403347

3348+
if (idle_termination_timeout >= 0) {
3349+
if (idle_thread_count == total_thread_count) {
3350+
/* we are completely idle, decrease and check the timer */
3351+
if (--idle_termination_remaining < 0) {
3352+
/* the termination timeout has expired, inform us we want to terminate immediately */
3353+
retained->mpm->shutdown_pending = 1;
3354+
retained->mpm->is_ungraceful = 1;
3355+
retained->idle_timeout = 1;
3356+
}
3357+
} else {
3358+
/* not idle, reset the timer */
3359+
idle_termination_remaining = idle_termination_timeout;
3360+
}
3361+
}
3362+
33413363
if (idle_thread_count > max_spare_threads / num_buckets) {
33423364
/*
33433365
* Child processes that we ask to shut down won't die immediately
@@ -3783,8 +3805,15 @@ static int event_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
37833805
if (!child_fatal) {
37843806
/* cleanup pid file on normal shutdown */
37853807
ap_remove_pid(pconf, ap_pid_fname);
3786-
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
3787-
ap_server_conf, APLOGNO(00491) "caught SIGTERM, shutting down");
3808+
3809+
/* log message depends on if we are terminating by signal or by idle timeout */
3810+
if (!retained->idle_timeout) {
3811+
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00491)
3812+
"caught SIGTERM, shutting down");
3813+
} else {
3814+
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, APLOGNO(00491)
3815+
"idle timeout reached, shutting down");
3816+
}
37883817
}
37893818

37903819
return DONE;
@@ -4481,6 +4510,17 @@ static const char *set_worker_factor(cmd_parms * cmd, void *dummy,
44814510
return NULL;
44824511
}
44834512

4513+
static const char *set_idle_termination_timeout (cmd_parms *cmd, void *dummy, const char *arg)
4514+
{
4515+
const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
4516+
if (err != NULL) {
4517+
return err;
4518+
}
4519+
4520+
idle_termination_timeout = atoi(arg);
4521+
idle_termination_remaining = idle_termination_timeout;
4522+
return NULL;
4523+
}
44844524

44854525
static const command_rec event_cmds[] = {
44864526
LISTEN_COMMANDS,
@@ -4504,6 +4544,8 @@ static const command_rec event_cmds[] = {
45044544
AP_INIT_TAKE1("AsyncRequestWorkerFactor", set_worker_factor, NULL, RSRC_CONF,
45054545
"How many additional connects will be accepted per idle "
45064546
"worker thread"),
4547+
AP_INIT_TAKE1("IdleTerminationTimeout", set_idle_termination_timeout, NULL, RSRC_CONF,
4548+
"Number of seconds to terminate in when the server is idle"),
45074549
AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
45084550
{NULL}
45094551
};

0 commit comments

Comments
 (0)