]> granicus.if.org Git - apache/commitdiff
prefork: Fix child process hang during graceful restart/stop in
authorJeff Trawick <trawick@apache.org>
Wed, 7 Jan 2009 20:00:56 +0000 (20:00 +0000)
committerJeff Trawick <trawick@apache.org>
Wed, 7 Jan 2009 20:00:56 +0000 (20:00 +0000)
configurations with multiple listening sockets.

PR: 42829
Submitted by: Joe Orton, with some tweaking and testing from me

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@732451 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/mpm/prefork/prefork.c

diff --git a/CHANGES b/CHANGES
index 047c0ccd860b4db0b4f65c28c68d33ef58a54611..2186c26a7ac40f23c40acd3068d642e659c22920 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@
 Changes with Apache 2.3.2
 [ When backported to 2.2.x, remove entry from this file ]
 
+ *) prefork: Fix child process hang during graceful restart/stop in
+    configurations with multiple listening sockets.  PR 42829.  [Joe Orton,
+    Jeff Trawick]
+
  *) prefork: Log an error instead of segfaulting when child startup fails
     due to pollset creation failures.  PR 46467.  [Jeff Trawick]
 
index 7fb366a7faa3f67b16191843b6707546115ade9e..2bbf7c3a9515f07ede53ff7d0e4fd6716c79c3e7 100644 (file)
@@ -544,20 +544,27 @@ static void child_main(int child_num_arg)
                 apr_int32_t numdesc;
                 const apr_pollfd_t *pdesc;
 
-                /* timeout == -1 == wait forever */
-                status = apr_pollset_poll(pollset, -1, &numdesc, &pdesc);
+                /* check for termination first so we don't sleep for a while in
+                 * poll if already signalled
+                 */
+                if (one_process && shutdown_pending) {
+                    SAFE_ACCEPT(accept_mutex_off());
+                    return;
+                }
+                else if (die_now) {
+                    /* In graceful stop/restart; drop the mutex
+                     * and terminate the child. */
+                    SAFE_ACCEPT(accept_mutex_off());
+                    clean_child_exit(0);
+                }
+                /* timeout == 10 seconds to avoid a hang at graceful restart/stop
+                 * caused by the closing of sockets by the signal handler
+                 */
+                status = apr_pollset_poll(pollset, apr_time_from_sec(10), 
+                                          &numdesc, &pdesc);
                 if (status != APR_SUCCESS) {
-                    if (APR_STATUS_IS_EINTR(status)) {
-                        if (one_process && shutdown_pending) {
-                            SAFE_ACCEPT(accept_mutex_off());
-                            return;
-                        }
-                        else if (die_now) {
-                            /* In graceful stop/restart; drop the mutex
-                             * and terminate the child. */
-                            SAFE_ACCEPT(accept_mutex_off());
-                            clean_child_exit(0);
-                        }
+                    if (APR_STATUS_IS_TIMEUP(status) ||
+                        APR_STATUS_IS_EINTR(status)) {
                         continue;
                     }
                     /* Single Unix documents select as returning errnos