akosut 97/08/25 17:00:57
Modified: src CHANGES src/main http_config.c http_main.c Log: Update sig_term to shutdown gracefully when a SIGTERM is received. Reviewed by: Dean Gaudet, Randy Terbush Revision Changes Path 1.421 +4 -0 apachen/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apachen/src/CHANGES,v retrieving revision 1.420 retrieving revision 1.421 diff -u -u -r1.420 -r1.421 --- CHANGES 1997/08/25 16:02:21 1.420 +++ CHANGES 1997/08/26 00:00:50 1.421 @@ -1,5 +1,9 @@ Changes with Apache 1.3a2 + *) Apache now gracefully shuts down when it receives a SIGTERM, instead + of forcibly killing off all its processes and exiting without + cleaning up. [Alexei Kosut] + *) API: A new field in the request_rec, r->mtime, has been added to avoid gratuitous parsing of date strings. It is intended to hold the last-modified date of the resource (if applicable). An 1.76 +0 -1 apachen/src/main/http_config.c Index: http_config.c =================================================================== RCS file: /export/home/cvs/apachen/src/main/http_config.c,v retrieving revision 1.75 retrieving revision 1.76 diff -u -u -r1.75 -r1.76 --- http_config.c 1997/08/25 02:26:57 1.75 +++ http_config.c 1997/08/26 00:00:54 1.76 @@ -1293,7 +1293,6 @@ if (m->child_exit) (*m->child_exit) (s, p); - exit(0); } /******************************************************************** 1.210 +48 -18 apachen/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /export/home/cvs/apachen/src/main/http_main.c,v retrieving revision 1.209 retrieving revision 1.210 diff -u -u -r1.209 -r1.210 --- http_main.c 1997/08/24 18:41:29 1.209 +++ http_main.c 1997/08/26 00:00:55 1.210 @@ -746,6 +746,8 @@ if (alarms_blocked == 0) { if (exit_after_unblock) { child_exit_modules(pconf, server_conf); + destroy_pool(pconf); + exit(0); } if (alarm_pending) { alarm_pending = 0; @@ -1591,7 +1593,7 @@ return -1; } -static void reclaim_child_processes (void) +static void reclaim_child_processes (int start_tries) { #ifndef MULTITHREAD int i, status; @@ -1602,7 +1604,7 @@ if (pid != my_pid && pid != 0) { int waitret = 0, - tries = 1; + tries = start_tries; while (waitret == 0 && tries <= 4) { long int waittime = 4096; /* in usecs */ @@ -1745,17 +1747,6 @@ } -void sig_term(int sig) { - log_error("httpd: caught SIGTERM, shutting down", server_conf); - cleanup_scoreboard(); - accept_mutex_cleanup(); -#ifdef SIGKILL - ap_killpg (pgrp, SIGKILL); -#endif /* SIGKILL */ - close(sd); - exit(1); -} - void bus_error(int sig) { char emsg[256]; @@ -1790,6 +1781,8 @@ exit_after_unblock = 1; } else { child_exit_modules(pconf, server_conf); + destroy_pool(pconf); + exit(0); } } @@ -1805,10 +1798,15 @@ } /* volatile just in case */ +static int volatile shutdown_pending; static int volatile restart_pending; static int volatile is_graceful; static int volatile generation; +static void sig_term(int sig) { + shutdown_pending = 1; +} + static void restart (int sig) { #ifdef WIN32 @@ -2642,13 +2640,18 @@ clear_pool (ptrans); sync_scoreboard_image(); - if (scoreboard_image->global.exit_generation >= generation) + if (scoreboard_image->global.exit_generation >= generation) { child_exit_modules(pconf, server_conf); + destroy_pool(pconf); + exit(0); + } if ((max_requests_per_child > 0 && ++requests_this_child >= max_requests_per_child)) { child_exit_modules(pconf, server_conf); + destroy_pool(pconf); + exit(0); } (void)update_child_status(my_child_num, SERVER_READY, (request_rec*)NULL); @@ -2692,6 +2695,8 @@ if (deferred_die) { /* we didn't get a socket, and we were told to die */ child_exit_modules(pconf, server_conf); + destroy_pool(pconf); + exit(0); } } @@ -2714,13 +2719,18 @@ if (deferred_die) { /* ok maybe not, see ya later */ child_exit_modules(pconf, server_conf); + destroy_pool(pconf); + exit(0); } /* or maybe we missed a signal, you never know on systems * without reliable signals */ sync_scoreboard_image(); - if (scoreboard_image->global.exit_generation >= generation) + if (scoreboard_image->global.exit_generation >= generation) { child_exit_modules(pconf, server_conf); + destroy_pool(pconf); + exit(0); + } } SAFE_ACCEPT(accept_mutex_off()); /* unlock after "accept" */ @@ -2805,6 +2815,8 @@ if (scoreboard_image->global.exit_generation >= generation) { bclose(conn_io); child_exit_modules(pconf, server_conf); + destroy_pool(pconf); + exit(0); } /* In case we get a graceful restart while we're blocked @@ -3129,9 +3141,9 @@ log_printf (server_conf, "Server built: %s", SERVER_BUILT); log_error ("Server configured -- resuming normal operations", server_conf); - restart_pending = 0; + restart_pending = shutdown_pending = 0; - while (!restart_pending) { + while (!restart_pending && !shutdown_pending) { int child_slot; int pid = wait_or_timeout (); @@ -3182,6 +3194,24 @@ perform_idle_server_maintenance(); } + if (shutdown_pending) { + /* Time to gracefully shut down: + * Kill child processes, tell them to call child_exit, etc... + */ + if (ap_killpg (pgrp, SIGTERM) < 0) { + log_unixerr ("killpg SIGTERM", NULL, NULL, server_conf); + } + reclaim_child_processes(2); /* Start with SIGTERM */ + log_error("httpd: caught SIGTERM, shutting down", server_conf); + + /* Clear the pool - including any registered cleanups */ + destroy_pool(pconf); + cleanup_scoreboard(); + accept_mutex_cleanup(); + + exit(0); + } + /* we've been told to restart */ signal (SIGHUP, SIG_IGN); signal (SIGUSR1, SIG_IGN); @@ -3225,7 +3255,7 @@ if (ap_killpg (pgrp, SIGHUP) < 0) { log_unixerr ("killpg SIGHUP", NULL, NULL, server_conf); } - reclaim_child_processes(); /* Not when just starting up */ + reclaim_child_processes(1); /* Not when just starting up */ log_error ("SIGHUP received. Attempting to restart", server_conf); } ++generation;