This is a simpler approach to fixing what I think is the
root cause of the worker deadlocks.

Index: server/mpm/worker/worker.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v
retrieving revision 1.125
diff -u -r1.125 worker.c
--- server/mpm/worker/worker.c  23 May 2002 12:58:37 -0000      1.125
+++ server/mpm/worker/worker.c  23 May 2002 21:19:38 -0000
@@ -689,6 +689,7 @@
     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 @@
         }
         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 @@
                     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 @@
     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 @@
     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 @@
             }
             continue;
         }
+        is_idle = 0;
         worker_sockets[thread_slot] = csd;
         process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc);
         worker_sockets[thread_slot] = NULL;

Reply via email to