Parent Directory
|
Revision Log
|
Patch
--- httpd/httpd/branches/2.2.x/server/mpm/worker/worker.c 2005/09/19 14:57:07 290179
+++ httpd/httpd/branches/2.2.x/server/mpm/worker/worker.c 2005/09/19 15:51:22 290189
@@ -374,7 +374,7 @@
* child to force an exit) and so do an exit anyway.
*/
-static void ap_start_shutdown(void)
+static void ap_start_shutdown(int graceful)
{
mpm_state = AP_MPMQ_STOPPING;
if (shutdown_pending == 1) {
@@ -385,6 +385,7 @@
return;
}
shutdown_pending = 1;
+ is_graceful = graceful;
}
/* do a graceful restart if graceful == 1 */
@@ -401,7 +402,7 @@
static void sig_term(int sig)
{
- ap_start_shutdown();
+ ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
}
static void restart(int sig)
@@ -427,6 +428,11 @@
if (sigaction(SIGTERM, &sa, NULL) < 0)
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
"sigaction(SIGTERM)");
+#ifdef AP_SIG_GRACEFUL_STOP
+ if (sigaction(AP_SIG_GRACEFUL_STOP, &sa, NULL) < 0)
+ ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
+ "sigaction(" AP_SIG_GRACEFUL_STOP_STRING ")");
+#endif
#ifdef SIGINT
if (sigaction(SIGINT, &sa, NULL) < 0)
ap_log_error(APLOG_MARK, APLOG_WARNING, errno, ap_server_conf,
@@ -479,6 +485,9 @@
#ifdef AP_SIG_GRACEFUL
apr_signal(AP_SIG_GRACEFUL, restart);
#endif /* AP_SIG_GRACEFUL */
+#ifdef AP_SIG_GRACEFUL_STOP
+ apr_signal(AP_SIG_GRACEFUL_STOP, sig_term);
+#endif /* AP_SIG_GRACEFUL_STOP */
#ifdef SIGPIPE
apr_signal(SIGPIPE, SIG_IGN);
#endif /* SIGPIPE */
@@ -1714,11 +1723,9 @@
server_main_loop(remaining_children_to_start);
mpm_state = AP_MPMQ_STOPPING;
- if (shutdown_pending) {
- /* Time to gracefully shut down:
+ if (shutdown_pending && !is_graceful) {
+ /* Time to shut down:
* Kill child processes, tell them to call child_exit, etc...
- * (By "gracefully" we don't mean graceful in the same sense as
- * "apachectl graceful" where we allow old connections to finish.)
*/
ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE);
ap_reclaim_child_processes(1); /* Start with SIGTERM */
@@ -1730,12 +1737,69 @@
if ( pidfile != NULL && unlink(pidfile) == 0)
ap_log_error(APLOG_MARK, APLOG_INFO, 0,
ap_server_conf,
- "removed PID file %s (pid=%ld)",
- pidfile, (long)getpid());
+ "removed PID file %s (pid=%" APR_PID_T_FMT ")",
+ pidfile, getpid());
+
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
+ ap_server_conf, "caught SIGTERM, shutting down");
+ }
+ return 1;
+ } else if (shutdown_pending) {
+ /* Time to gracefully shut down:
+ * Kill child processes, tell them to call child_exit, etc...
+ */
+ int active_children;
+ int index;
+ apr_time_t cutoff = 0;
+
+ /* Close our listeners, and then ask our children to do same */
+ ap_close_listeners();
+ ap_mpm_pod_killpg(pod, ap_daemons_limit, TRUE);
+ ap_relieve_child_processes();
+
+ if (!child_fatal) {
+ /* cleanup pid file on normal shutdown */
+ const char *pidfile = NULL;
+ pidfile = ap_server_root_relative (pconf, ap_pid_fname);
+ if ( pidfile != NULL && unlink(pidfile) == 0)
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0,
+ ap_server_conf,
+ "removed PID file %s (pid=%" APR_PID_T_FMT ")",
+ pidfile, getpid());
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0,
ap_server_conf, "caught SIGTERM, shutting down");
}
+
+ /* Don't really exit until each child has finished */
+ shutdown_pending = 0;
+ do {
+ /* Pause for a second */
+ apr_sleep(apr_time_from_sec(1));
+
+ /* Relieve any children which have now exited */
+ ap_relieve_child_processes();
+
+ active_children = 0;
+ for (index = 0; index < ap_daemons_limit; ++index) {
+ if (MPM_CHILD_PID(index) != 0) {
+ if (kill(MPM_CHILD_PID(index), 0) == 0) {
+ active_children = 1;
+ /* Having just one child is enough to stay around */
+ break;
+ }
+ }
+ }
+ } while (!shutdown_pending && active_children &&
+ (!ap_graceful_shutdown_timeout || apr_time_now() < cutoff));
+
+ /* We might be here because we received SIGTERM, either
+ * way, try and make sure that all of our processes are
+ * really dead.
+ */
+ ap_mpm_pod_killpg(pod, ap_daemons_limit, FALSE);
+ ap_reclaim_child_processes(1);
+
return 1;
}
@@ -2150,6 +2214,7 @@
"Maximum number of child processes for this run of Apache"),
AP_INIT_TAKE1("ThreadLimit", set_thread_limit, NULL, RSRC_CONF,
"Maximum number of worker threads per child process for this run of Apache - Upper limit for ThreadsPerChild"),
+AP_GRACEFUL_SHUTDOWN_TIMEOUT_COMMAND,
{ NULL }
};
| apache@apache.org | ViewVC Help |
| Powered by ViewVC 1.1.2 |