]> granicus.if.org Git - apache/commitdiff
Fix for the worker deadlock problem
authorBrian Pane <brianp@apache.org>
Fri, 24 May 2002 19:50:58 +0000 (19:50 +0000)
committerBrian Pane <brianp@apache.org>
Fri, 24 May 2002 19:50:58 +0000 (19:50 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@95270 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
server/mpm/worker/worker.c

diff --git a/CHANGES b/CHANGES
index 033cc9f6ea20ad7aee37498fe7a71bc6c8f6a3f4..ff11dc268e9b5ee561ad7985bca394e7428f3f1b 100644 (file)
--- 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]
 
index f9c23ca270913badff80fce98fd804e7d5f73120..93bc30f2df0fb5033690914c7534ae8a790f7efa 100644 (file)
@@ -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;