From 9a00245469c10ebe0a804cd07a33e04dedc54ecb Mon Sep 17 00:00:00 2001 From: Jeff Trawick Date: Wed, 7 Jan 2009 20:00:56 +0000 Subject: [PATCH] prefork: Fix child process hang during graceful restart/stop in 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 | 4 ++++ server/mpm/prefork/prefork.c | 33 ++++++++++++++++++++------------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index 047c0ccd86..2186c26a7a 100644 --- 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] diff --git a/server/mpm/prefork/prefork.c b/server/mpm/prefork/prefork.c index 7fb366a7fa..2bbf7c3a95 100644 --- a/server/mpm/prefork/prefork.c +++ b/server/mpm/prefork/prefork.c @@ -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 -- 2.40.0