From: Brian Pane Date: Fri, 24 May 2002 19:50:58 +0000 (+0000) Subject: Fix for the worker deadlock problem X-Git-Tag: 2.0.37~274 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=cc62268db9dacfe28152e81e9b73edfe708081f5;p=apache Fix for the worker deadlock problem git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95270 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 033cc9f6ea..ff11dc268e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,5 +1,7 @@ Changes with Apache 2.0.37 + *) Fix the worker MPM deadlock problem [Brian Pane] + *) Modify the module documentation to allow for translations. [Yoshiki Hayashi, Joshua Slive] diff --git a/server/mpm/worker/worker.c b/server/mpm/worker/worker.c index f9c23ca270..93bc30f2df 100644 --- a/server/mpm/worker/worker.c +++ b/server/mpm/worker/worker.c @@ -689,6 +689,7 @@ static void *listener_thread(apr_thread_t *thd, void * dummy) apr_pollfd_t *pollset; apr_status_t rv; ap_listen_rec *lr, *last_lr = ap_listeners; + int have_idle_worker = 0; free(ti); @@ -711,18 +712,22 @@ static void *listener_thread(apr_thread_t *thd, void * dummy) } if (listener_may_exit) break; - rv = ap_queue_info_wait_for_idler(worker_queue_info, - &recycled_pool); - if (APR_STATUS_IS_EOF(rv)) { - break; /* we've been signaled to die now */ - } - else if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "apr_queue_info_wait failed. Attempting to shutdown " - "process gracefully."); - signal_threads(ST_GRACEFUL); - break; + if (!have_idle_worker) { + rv = ap_queue_info_wait_for_idler(worker_queue_info, + &recycled_pool); + if (APR_STATUS_IS_EOF(rv)) { + break; /* we've been signaled to die now */ + } + else if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "apr_queue_info_wait failed. Attempting to " + " shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + break; + } + have_idle_worker = 1; } + /* We've already decremented the idle worker count inside * ap_queue_info_wait_for_idler. */ @@ -833,6 +838,9 @@ static void *listener_thread(apr_thread_t *thd, void * dummy) ap_log_error(APLOG_MARK, APLOG_CRIT, rv, ap_server_conf, "ap_queue_push failed"); } + else { + have_idle_worker = 0; + } } } else { @@ -875,6 +883,7 @@ static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy) apr_pool_t *last_ptrans = NULL; apr_pool_t *ptrans; /* Pool for per-transaction stuff */ apr_status_t rv; + int is_idle = 0; free(ti); @@ -883,14 +892,17 @@ static void * APR_THREAD_FUNC worker_thread(apr_thread_t *thd, void * dummy) bucket_alloc = apr_bucket_alloc_create(apr_thread_pool_get(thd)); while (!workers_may_exit) { - rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans); - last_ptrans = NULL; - if (rv != APR_SUCCESS) { - ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, - "ap_queue_info_set_idle failed. Attempting to " - "shutdown process gracefully."); - signal_threads(ST_GRACEFUL); - break; + if (!is_idle) { + rv = ap_queue_info_set_idle(worker_queue_info, last_ptrans); + last_ptrans = NULL; + if (rv != APR_SUCCESS) { + ap_log_error(APLOG_MARK, APLOG_EMERG, rv, ap_server_conf, + "ap_queue_info_set_idle failed. Attempting to " + "shutdown process gracefully."); + signal_threads(ST_GRACEFUL); + break; + } + is_idle = 1; } ap_update_child_status_from_indexes(process_slot, thread_slot, SERVER_READY, NULL); @@ -928,6 +940,7 @@ worker_pop: } continue; } + is_idle = 0; worker_sockets[thread_slot] = csd; process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc); worker_sockets[thread_slot] = NULL;