On Fri, 2009-10-23 at 07:58 +1100, Bojan Smojver wrote:
> Note that the attached _still_ has a race.

Slower, but safer attached (not even compiled, so could be utterly
bogus).

-- 
Bojan
Index: server/mpm/worker/worker.c
===================================================================
--- server/mpm/worker/worker.c	(revision 828847)
+++ server/mpm/worker/worker.c	(working copy)
@@ -236,16 +236,22 @@
 /* An array of socket descriptors in use by each thread used to
  * perform a non-graceful (forced) shutdown of the server. */
 static apr_socket_t **worker_sockets;
+static apr_thread_mutex_t *worker_socket_mutex;
 
 static void close_worker_sockets(void)
 {
     int i;
+
+    apr_mutex_lock(worker_socket_mutex); /* press ahead, even on error */
+
     for (i = 0; i < threads_per_child; i++) {
         if (worker_sockets[i]) {
-            apr_socket_close(worker_sockets[i]);
-            worker_sockets[i] = NULL;
+            apr_os_sock_get((apr_os_sock_t *)&csd, worker_sockets[i]);
+            shutdown(csd, SHUT_RDWR);
         }
     }
+
+    apr_mutex_unlock(worker_socket_mutex);
 }
 
 static void wakeup_listener(void)
@@ -915,10 +921,18 @@
             continue;
         }
         is_idle = 0;
+
+        apr_mutex_lock(worker_socket_mutex); /* press ahead, even on error */
         worker_sockets[thread_slot] = csd;
+        apr_mutex_unlock(worker_socket_mutex);
+
         bucket_alloc = apr_bucket_alloc_create(ptrans);
         process_socket(thd, ptrans, csd, process_slot, thread_slot, bucket_alloc);
+
+        apr_mutex_lock(worker_socket_mutex); /* press ahead, even on error */
         worker_sockets[thread_slot] = NULL;
+        apr_mutex_unlock(worker_socket_mutex);
+
         requests_this_child--; 
         apr_pool_clear(ptrans);
         last_ptrans = ptrans;
@@ -1003,6 +1017,13 @@
 
     worker_sockets = apr_pcalloc(pchild, threads_per_child
                                         * sizeof(apr_socket_t *));
+    rv = apr_thread_mutex_create(&worker_socket_mutex,
+                                 APR_THREAD_MUTEX_DEFAULT, pchild);
+    if (rv != APR_SUCCESS) {
+        ap_log_error(APLOG_MARK, APLOG_ALERT, rv, ap_server_conf,
+                     "Cannot create worker socket lock");
+        clean_child_exit(APEXIT_CHILDFATAL);
+    }
 
     loops = prev_threads_created = 0;
     while (1) {

Reply via email to