diff options
author | Colm MacCarthaigh <colm@apache.org> | 2005-08-29 10:20:25 +0000 |
---|---|---|
committer | Colm MacCarthaigh <colm@apache.org> | 2005-08-29 10:20:25 +0000 |
commit | 146fd39a5a6583e4f2f4298a04e3b892eb628936 (patch) | |
tree | d27eaa69f7d6d995237bd55c0d53e0fdf5ddab23 | |
parent | 36b3643d82d34ea2278b64970f9de68e5a761f3f (diff) | |
download | httpd-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-- | CHANGES | 6 | ||||
-rw-r--r-- | docs/manual/mod/mpm_common.html.en | 2 | ||||
-rw-r--r-- | docs/manual/mod/mpm_common.xml | 3 | ||||
-rw-r--r-- | docs/manual/new_features_2_2.html.en | 5 | ||||
-rw-r--r-- | docs/manual/new_features_2_2.xml | 5 | ||||
-rw-r--r-- | docs/manual/new_features_2_2.xml.ko | 2 | ||||
-rw-r--r-- | docs/manual/new_features_2_2.xml.pt-br | 2 | ||||
-rw-r--r-- | server/mpm/experimental/event/event.c | 80 | ||||
-rw-r--r-- | server/mpm/experimental/event/mpm.h | 1 |
9 files changed, 88 insertions, 18 deletions
@@ -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 |