summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorColm MacCarthaigh <colm@apache.org>2005-08-29 10:20:25 +0000
committerColm MacCarthaigh <colm@apache.org>2005-08-29 10:20:25 +0000
commit146fd39a5a6583e4f2f4298a04e3b892eb628936 (patch)
treed27eaa69f7d6d995237bd55c0d53e0fdf5ddab23
parent36b3643d82d34ea2278b64970f9de68e5a761f3f (diff)
downloadhttpd-146fd39a5a6583e4f2f4298a04e3b892eb628936.tar.gz
Implement graceful stop in the event MPM. Implementation is identical to
the worker MPM implementation. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@264105 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--CHANGES6
-rw-r--r--docs/manual/mod/mpm_common.html.en2
-rw-r--r--docs/manual/mod/mpm_common.xml3
-rw-r--r--docs/manual/new_features_2_2.html.en5
-rw-r--r--docs/manual/new_features_2_2.xml5
-rw-r--r--docs/manual/new_features_2_2.xml.ko2
-rw-r--r--docs/manual/new_features_2_2.xml.pt-br2
-rw-r--r--server/mpm/experimental/event/event.c80
-rw-r--r--server/mpm/experimental/event/mpm.h1
9 files changed, 88 insertions, 18 deletions
diff --git a/CHANGES b/CHANGES
index aab1a3bb2f..8f83c3359c 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,7 +4,7 @@ Changes with Apache 2.3.0
*) Doxygen fixup [Neale Ranns neale ranns.org, Ian Holsman]
- *) prefork and worker MPMs: Support a graceful-stop procedure:
+ *) prefork, worker and event MPMs: Support a graceful-stop procedure:
Server will wait until existing requests are finished or until
"GracefulShutdownTimeout" number of seconds before exiting.
[Colm MacCarthaigh, Ken Coar, Bill Stoddard]
@@ -12,8 +12,8 @@ Changes with Apache 2.3.0
*) mod_cgid: Append .PID to the script socket filename and remove the
script socket on exit. [Colm MacCarthaigh]
- *) prefork and worker MPMs: Prevent children from holding open listening
- ports upon graceful restart or stop. PR28167.
+ *) prefork, worker and event MPMs: Prevent children from holding open
+ listening ports upon graceful restart or stop. PR28167.
[Colm MacCarthaigh, Brian Pinkerton <bp thinkpink.com>]
*) Linux 2.0: remove support for threaded MPM's due to linuxthreads use
diff --git a/docs/manual/mod/mpm_common.html.en b/docs/manual/mod/mpm_common.html.en
index c8e0bb0052..d34e1fab9c 100644
--- a/docs/manual/mod/mpm_common.html.en
+++ b/docs/manual/mod/mpm_common.html.en
@@ -181,7 +181,7 @@ will exit.</td></tr>
<tr><th><a href="directive-dict.html#Default">Default:</a></th><td><code>GracefulShutDownTimeout 0</code></td></tr>
<tr><th><a href="directive-dict.html#Context">Context:</a></th><td>server config</td></tr>
<tr><th><a href="directive-dict.html#Status">Status:</a></th><td>MPM</td></tr>
-<tr><th><a href="directive-dict.html#Module">Module:</a></th><td><code class="module"><a href="../mod/prefork.html">prefork</a></code>, <code class="module"><a href="../mod/worker.html">worker</a></code></td></tr>
+<tr><th><a href="directive-dict.html#Module">Module:</a></th><td><code class="module"><a href="../mod/prefork.html">prefork</a></code>, <code class="module"><a href="../mod/worker.html">worker</a></code>, <code class="module"><a href="../mod/event.html">event</a></code></td></tr>
<tr><th><a href="directive-dict.html#Compatibility">Compatibility:</a></th><td>Available in version 2.2 and later</td></tr>
</table>
<p>The <code class="directive">GracefulShutdownTimeout</code> specifies
diff --git a/docs/manual/mod/mpm_common.xml b/docs/manual/mod/mpm_common.xml
index d631d32d13..347f4cb6e3 100644
--- a/docs/manual/mod/mpm_common.xml
+++ b/docs/manual/mod/mpm_common.xml
@@ -163,7 +163,8 @@ will exit.</description>
<syntax>GracefulShutDownTimeout <var>seconds</var></syntax>
<default>GracefulShutDownTimeout 0</default>
<contextlist><context>server config</context></contextlist>
-<modulelist><module>prefork</module><module>worker</module></modulelist>
+<modulelist><module>prefork</module><module>worker</module>
+<module>event</module></modulelist>
<compatibility>Available in version 2.2 and later</compatibility>
<usage>
diff --git a/docs/manual/new_features_2_2.html.en b/docs/manual/new_features_2_2.html.en
index 7ebf1b2751..e30b4e9b5b 100644
--- a/docs/manual/new_features_2_2.html.en
+++ b/docs/manual/new_features_2_2.html.en
@@ -53,8 +53,9 @@
setups.</dd>
<dt>Graceful stop</dt>
- <dd>The <code class="module"><a href="./mod/prefork.html">prefork</a></code> and <code class="module"><a href="./mod/worker.html">worker</a></code> MPMs now
- allow <code class="program"><a href="./programs/httpd.html">httpd</a></code> to be shutdown gracefully via the
+ <dd>The <code class="module"><a href="./mod/prefork.html">prefork</a></code>, <code class="module"><a href="./mod/worker.html">worker</a></code> and
+ <code class="module"><a href="./mod/event.html">event</a></code> MPMs now allow <code class="program"><a href="./programs/httpd.html">httpd</a></code>
+ to be shutdown gracefully via the
<a href="stopping.html#gracefulstop"><code>graceful-stop</code></a>
signal. The <code class="directive"><a href="./mod/mpm_common.html#gracefulshutdowntimeout">GracefulShutdownTimeout</a></code> directive
has been added to specify an optional timeout, after which
diff --git a/docs/manual/new_features_2_2.xml b/docs/manual/new_features_2_2.xml
index 7a88617948..510e66b2de 100644
--- a/docs/manual/new_features_2_2.xml
+++ b/docs/manual/new_features_2_2.xml
@@ -49,8 +49,9 @@
setups.</dd>
<dt>Graceful stop</dt>
- <dd>The <module>prefork</module> and <module>worker</module> MPMs now
- allow <program>httpd</program> to be shutdown gracefully via the
+ <dd>The <module>prefork</module>, <module>worker</module> and
+ <module>event</module> MPMs now allow <program>httpd</program>
+ to be shutdown gracefully via the
<a href="stopping.html#gracefulstop"><code>graceful-stop</code></a>
signal. The <directive
module="mpm_common">GracefulShutdownTimeout</directive> directive
diff --git a/docs/manual/new_features_2_2.xml.ko b/docs/manual/new_features_2_2.xml.ko
index 0e8d3ab010..733323c50c 100644
--- a/docs/manual/new_features_2_2.xml.ko
+++ b/docs/manual/new_features_2_2.xml.ko
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='EUC-KR' ?>
<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="./style/manual.ko.xsl"?>
-<!-- English Revision: 105989:193026 (outdated) -->
+<!-- English Revision: 105989:263906 (outdated) -->
<!--
Copyright 2004-2005 The Apache Software Foundation or its licensors,
diff --git a/docs/manual/new_features_2_2.xml.pt-br b/docs/manual/new_features_2_2.xml.pt-br
index a97474c4d3..10a13818a8 100644
--- a/docs/manual/new_features_2_2.xml.pt-br
+++ b/docs/manual/new_features_2_2.xml.pt-br
@@ -1,7 +1,7 @@
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE manualpage SYSTEM "./style/manualpage.dtd">
<?xml-stylesheet type="text/xsl" href="./style/manual.pt-br.xsl"?>
-<!-- English Revision: 151408:193026 (outdated) -->
+<!-- English Revision: 151408:263906 (outdated) -->
<!--
Copyright 2005 The Apache Software Foundation or its licensors,
diff --git a/server/mpm/experimental/event/event.c b/server/mpm/experimental/event/event.c
index 45d8458290..3dc48e1cf1 100644
--- a/server/mpm/experimental/event/event.c
+++ b/server/mpm/experimental/event/event.c
@@ -416,7 +416,7 @@ ap_generation_t volatile ap_my_generation;
* 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) {
@@ -427,6 +427,7 @@ static void ap_start_shutdown(void)
return;
}
shutdown_pending = 1;
+ is_graceful = graceful;
}
/* do a graceful restart if graceful == 1 */
@@ -443,7 +444,7 @@ static void ap_start_restart(int graceful)
static void sig_term(int sig)
{
- ap_start_shutdown();
+ ap_start_shutdown(sig == AP_SIG_GRACEFUL_STOP);
}
static void restart(int sig)
@@ -469,6 +470,11 @@ static void set_signals(void)
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,
@@ -521,6 +527,9 @@ static void set_signals(void)
#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 */
@@ -1036,6 +1045,7 @@ static void *listener_thread(apr_thread_t * thd, void *dummy)
} /* listener main loop */
+ ap_close_listeners();
ap_queue_term(worker_queue);
dying = 1;
ap_scoreboard_image->parent[process_slot].quiescing = 1;
@@ -1924,11 +1934,9 @@ int ap_mpm_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
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 */
@@ -1947,7 +1955,64 @@ int ap_mpm_run(apr_pool_t * _pconf, apr_pool_t * plog, server_rec * s)
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=%ld)",
+ pidfile, (long)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;
+ }
/* we've been told to restart */
apr_signal(SIGHUP, SIG_IGN);
@@ -2370,6 +2435,7 @@ static const command_rec event_cmds[] = {
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}
};
diff --git a/server/mpm/experimental/event/mpm.h b/server/mpm/experimental/event/mpm.h
index 31733690dc..05f3c7cb98 100644
--- a/server/mpm/experimental/event/mpm.h
+++ b/server/mpm/experimental/event/mpm.h
@@ -45,6 +45,7 @@
#define AP_MPM_WANT_SIGNAL_SERVER
#define AP_MPM_WANT_SET_MAX_MEM_FREE
#define AP_MPM_WANT_SET_STACKSIZE
+#define AP_MPM_WANT_SET_GRACEFUL_SHUTDOWN
#define AP_MPM_WANT_FATAL_SIGNAL_HANDLER
#define AP_MPM_DISABLE_NAGLE_ACCEPTED_SOCK