static unsigned int g_blocked_threads = 0;
static HANDLE max_requests_per_child_event;
-
+static apr_thread_mutex_t *child_lock;
static apr_thread_mutex_t *qlock;
static PCOMP_CONTEXT qhead = NULL;
static PCOMP_CONTEXT qtail = NULL;
*/
apr_allocator_t *allocator;
+ apr_thread_mutex_lock(child_lock);
context = (PCOMP_CONTEXT) apr_pcalloc(pchild, sizeof(COMP_CONTEXT));
context->Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
/* Hopefully this is a temporary condition ... */
ap_log_error(APLOG_MARK,APLOG_WARNING, apr_get_os_error(), ap_server_conf,
"mpm_get_completion_context: CreateEvent failed.");
+
+ apr_thread_mutex_unlock(child_lock);
return NULL;
}
ap_log_error(APLOG_MARK,APLOG_WARNING, rv, ap_server_conf,
"mpm_get_completion_context: Failed to create the transaction pool.");
CloseHandle(context->Overlapped.hEvent);
+
+ apr_thread_mutex_unlock(child_lock);
return NULL;
}
apr_allocator_owner_set(allocator, context->ptrans);
context->accept_socket = INVALID_SOCKET;
context->ba = apr_bucket_alloc_create(pchild);
apr_atomic_inc(&num_completion_contexts);
+
+ apr_thread_mutex_unlock(child_lock);
break;
}
} else {
if (context == NULL) {
/* allocate the completion context and the transaction pool */
apr_allocator_t *allocator;
+ apr_thread_mutex_lock(child_lock);
context = apr_pcalloc(pchild, sizeof(COMP_CONTEXT));
apr_allocator_create(&allocator);
apr_allocator_max_free_set(allocator, ap_max_mem_free);
apr_allocator_owner_set(allocator, context->ptrans);
apr_pool_tag(context->ptrans, "transaction");
context->ba = apr_bucket_alloc_create(pchild);
+ apr_thread_mutex_unlock(child_lock);
}
while (1) {
ap_log_error(APLOG_MARK,APLOG_NOTICE, APR_SUCCESS, ap_server_conf,
"Child %d: Starting %d worker threads.", my_pid, ap_threads_per_child);
child_handles = (HANDLE) apr_pcalloc(pchild, ap_threads_per_child * sizeof(int));
+ apr_thread_mutex_create(&child_lock, APR_THREAD_MUTEX_DEFAULT, pchild);
+
while (1) {
for (i = 0; i < ap_threads_per_child; i++) {
int *score_idx;
/* Save the score board index in ht keyed to the thread handle. We need this
* when cleaning up threads down below...
*/
+ apr_thread_mutex_lock(child_lock);
score_idx = apr_pcalloc(pchild, sizeof(int));
*score_idx = i;
apr_hash_set(ht, &child_handles[i], sizeof(HANDLE), score_idx);
+ apr_thread_mutex_unlock(child_lock);
}
/* Start the listener only when workers are available */
if (!listener_started && threads_created) {
CloseHandle(allowed_globals.jobsemaphore);
apr_thread_mutex_destroy(allowed_globals.jobmutex);
+ apr_thread_mutex_destroy(child_lock);
+
if (use_acceptex) {
apr_thread_mutex_destroy(qlock);
CloseHandle(qwait_event);