I have some questions about this patch (just now looking at porting it to 2.0):

[EMAIL PROTECTED] wrote:
ake         2004/05/03 15:22:50

Modified: . CHANGES
server/mpm/winnt child.c
Log:
Prevent Win32 pool corruption at startup
1.36 +17 -2 httpd-2.0/server/mpm/winnt/child.c
Index: child.c
===================================================================
RCS file: /home/cvs/httpd-2.0/server/mpm/winnt/child.c,v
retrieving revision 1.35
retrieving revision 1.36
diff -u -r1.35 -r1.36
--- child.c 15 Mar 2004 23:08:41 -0000 1.35
+++ child.c 3 May 2004 22:22:50 -0000 1.36
@@ -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 {

Here is the actual code from this section of the patch with my comments:

                /* Allocate another context.
                 * Note:
                 * Multiple failures in the next two steps will cause the pchild pool
                 * to 'leak' storage. I don't think this is worth fixing...
                 */
                apr_allocator_t *allocator;

===> lock here  apr_thread_mutex_lock(child_lock);
===> this presumes the calls to apr_pcalloc, createevent, et need protection. I think
===> they don't need protection

                context = (PCOMP_CONTEXT) apr_pcalloc(pchild, sizeof(COMP_CONTEXT));

                context->Overlapped.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
                if (context->Overlapped.hEvent == 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;
                }

                /* Create the tranaction pool */
==> needs protection?   apr_allocator_create(&allocator);
==> needs protection?   apr_allocator_max_free_set(allocator, ap_max_mem_free);
==> can we move the lock call here???
                rv = apr_pool_create_ex(&context->ptrans, pchild, NULL, allocator);
==> and add unlock call here?
                if (rv != APR_SUCCESS) {
                    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);
==> and delete this?
                    apr_thread_mutex_unlock(child_lock);
                    return NULL;
                }
                apr_allocator_owner_set(allocator, context->ptrans);
                apr_pool_tag(context->ptrans, "transaction");

                context->accept_socket = INVALID_SOCKET;
                context->ba = apr_bucket_alloc_create(pchild);
                apr_atomic_inc32(&num_completion_contexts);
==> and delete this?
                apr_thread_mutex_unlock(child_lock);
                break;
            }


<snip>
  +            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);
           }
This looks okay as child_handles and ht can be access my multiple threads at once, 
thus needs protection.

Comments?

Bill

Reply via email to