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) {