--- httpd-2.0.63/server/mpm/winnt/child.c 2008-01-05 11:23:44.000000000 -0500 +++ httpd-2.0.63/server/mpm/winnt/child.c 2008-07-29 11:13:41.359375000 -0400 @@ -815,14 +815,16 @@ } } - void child_main(apr_pool_t *pconf) { + char pool_tag[32]; + static int child_count = 0; + apr_pool_t *private_pchild; apr_status_t status; - apr_hash_t *ht; ap_listen_rec *lr; HANDLE child_events[2]; HANDLE *child_handles; + HANDLE *sb_assignments; int listener_started = 0; int threads_created = 0; int watch_thread; @@ -832,11 +834,12 @@ int rv; int i; - apr_pool_create(&pchild, pconf); - apr_pool_tag(pchild, "pchild"); + apr_pool_create(&private_pchild, pconf); + sprintf(pool_tag, "pchild_%d", child_count++); + apr_pool_tag(private_pchild, pool_tag); + pchild = private_pchild; // Share into global context - ap_run_child_init(pchild, ap_server_conf); - ht = apr_hash_make(pchild); + ap_run_child_init(private_pchild, ap_server_conf); /* Initialize the child_events */ max_requests_per_child_event = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -850,7 +853,7 @@ allowed_globals.jobsemaphore = CreateSemaphore(NULL, 0, 1000000, NULL); apr_thread_mutex_create(&allowed_globals.jobmutex, - APR_THREAD_MUTEX_DEFAULT, pchild); + APR_THREAD_MUTEX_DEFAULT, private_pchild); /* * Wait until we have permission to start accepting connections. @@ -876,7 +879,7 @@ NULL, 0, 0); /* CONCURRENT ACTIVE THREADS */ - apr_thread_mutex_create(&qlock, APR_THREAD_MUTEX_DEFAULT, pchild); + apr_thread_mutex_create(&qlock, APR_THREAD_MUTEX_DEFAULT, private_pchild); qwait_event = CreateEvent(NULL, TRUE, FALSE, NULL); if (!qwait_event) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, @@ -890,8 +893,9 @@ */ 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); + child_handles = (HANDLE) apr_pcalloc(private_pchild, ap_threads_per_child * sizeof(int)); + sb_assignments = (HANDLE) apr_pcalloc(private_pchild, ap_threads_per_child * sizeof(int)); + apr_thread_mutex_create(&child_lock, APR_THREAD_MUTEX_DEFAULT, private_pchild); while (1) { for (i = 0; i < ap_threads_per_child; i++) { @@ -901,8 +905,15 @@ continue; } ap_update_child_status_from_indexes(0, i, SERVER_STARTING, NULL); - child_handles[i] = (HANDLE) _beginthreadex(NULL, 0, worker_main, - (void *) i, 0, &tid); + + child_handles[i] = (HANDLE) _beginthreadex(NULL, 0, worker_main, (void *) i, 0, &tid); + + /* + * Save the score board index in the sb_assignments array keyed to the thread handle. + * We need this when cleaning up threads down below... + */ + sb_assignments[i] = child_handles[i]; + if (child_handles[i] == 0) { ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, "Child %d: _beginthreadex failed. Unable to create all worker threads. " @@ -912,14 +923,6 @@ goto shutdown; } threads_created++; - /* 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) { @@ -1141,12 +1144,21 @@ my_pid, threads_created); } for (i = 0; i < threads_created; i++) { - int *score_idx; + int score_idx; + TerminateThread(child_handles[i], 1); CloseHandle(child_handles[i]); + /* Reset the scoreboard entry for the thread we just whacked */ - score_idx = apr_hash_get(ht, &child_handles[i], sizeof(HANDLE)); - ap_update_child_status_from_indexes(0, *score_idx, SERVER_DEAD, NULL); + for (score_idx=0; score_idxfilehand, hproc, &newhand, 0, FALSE, DUPLICATE_SAME_ACCESS)) { @@ -130,7 +128,6 @@ /* For the process flow see the stderr case above */ fflush(stdin); setvbuf(stdin, NULL, _IONBF, 0); - _commit(0 /* stdin */); if (!DuplicateHandle(hproc, old_file->filehand, hproc, &newhand, 0, FALSE, DUPLICATE_SAME_ACCESS)) {