httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Allan Edwards <a...@us.ibm.com>
Subject Win32 pool corruption at startup
Date Mon, 03 May 2004 17:32:00 GMT
I see startup crashes when using Win32DisableAcceptEx.
Need to prevent the child main thread and multiple worker
threads simultaneously allocating from the pchild pool.
There are also exposures in the winnt path. The
attached patch closes these holes. I'll commit shortly.

Allan


Index: child.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/winnt/child.c,v
retrieving revision 1.35
diff -u -d -b -U3 -r1.35 child.c
--- child.c	15 Mar 2004 23:08:41 -0000	1.35
+++ child.c	3 May 2004 16:59:55 -0000
@@ -58,7 +58,7 @@
  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;
@@ -145,6 +145,7 @@
                   */
                  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);
@@ -152,6 +153,8 @@
                      /* 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;
                  }

@@ -163,6 +166,8 @@
                      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);
@@ -171,6 +176,8 @@
                  context->accept_socket = INVALID_SOCKET;
                  context->ba = apr_bucket_alloc_create(pchild);
                  apr_atomic_inc32(&num_completion_contexts);
+
+                apr_thread_mutex_unlock(child_lock);
                  break;
              }
          } else {
@@ -419,6 +426,7 @@
      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);
@@ -426,6 +434,7 @@
          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) {
@@ -920,6 +929,8 @@
      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;
@@ -943,9 +954,11 @@
              /* 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) {
@@ -1128,6 +1141,8 @@

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



Mime
View raw message