diff options
Diffstat (limited to 'server/mpm/winnt/child.c')
| -rw-r--r-- | server/mpm/winnt/child.c | 43 |
1 files changed, 34 insertions, 9 deletions
diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c index 6879179f..dee35df5 100644 --- a/server/mpm/winnt/child.c +++ b/server/mpm/winnt/child.c @@ -601,8 +601,12 @@ reinit: /* target of data or connect upon too many AcceptEx failures */ b->length = BytesRead; context->overlapped.Pointer = b; } - else + else { + if (accf == 2) { + apr_bucket_free(buf); + } context->overlapped.Pointer = NULL; + } } else /* (accf = 0) e.g. 'none' */ { @@ -890,8 +894,7 @@ static DWORD __stdcall worker_main(void *thread_num_val) } } - ap_update_child_status_from_indexes(0, thread_num, SERVER_DEAD, - (request_rec *) NULL); + ap_update_child_status_from_indexes(0, thread_num, SERVER_DEAD, NULL); return 0; } @@ -986,7 +989,15 @@ void child_main(apr_pool_t *pconf, DWORD parent_pid) if (parent_pid != my_pid) { child_events[2] = OpenProcess(SYNCHRONIZE, FALSE, parent_pid); - num_events = 3; + if (child_events[2] == NULL) { + num_events = 2; + ap_log_error(APLOG_MARK, APLOG_ERR, apr_get_os_error(), ap_server_conf, APLOGNO(02643) + "Child: Failed to open handle to parent process %ld; " + "will not react to abrupt parent termination", parent_pid); + } + else { + num_events = 3; + } } else { /* presumably -DONE_PROCESS */ @@ -1084,7 +1095,7 @@ void child_main(apr_pool_t *pconf, DWORD parent_pid) apr_sleep(1 * APR_USEC_PER_SEC); } - /* Wait for one of three events: + /* Wait for one of these events: * exit_event: * The exit_event is signaled by the parent process to notify * the child that it is time to exit. @@ -1093,6 +1104,8 @@ void child_main(apr_pool_t *pconf, DWORD parent_pid) * This event is signaled by the worker threads to indicate that * the process has handled MaxConnectionsPerChild connections. * + * parent process exiting + * * TIMEOUT: * To do periodic maintenance on the server (check for thread exits, * number of completion contexts, etc.) @@ -1113,6 +1126,7 @@ void child_main(apr_pool_t *pconf, DWORD parent_pid) rv = WaitForMultipleObjects(num_events, (HANDLE *)child_events, FALSE, INFINITE); cld = rv - WAIT_OBJECT_0; #else + /* THIS IS THE EXPECTED BUILD VARIATION -- APR_HAS_OTHER_CHILD */ rv = WaitForMultipleObjects(num_events, (HANDLE *)child_events, FALSE, 1000); cld = rv - WAIT_OBJECT_0; if (rv == WAIT_TIMEOUT) { @@ -1125,6 +1139,17 @@ void child_main(apr_pool_t *pconf, DWORD parent_pid) ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), ap_server_conf, APLOGNO(00356) "Child: WAIT_FAILED -- shutting down server"); + /* check handle validity to identify a possible culprit */ + for (i = 0; i < num_events; i++) { + DWORD out_flags; + + if (0 == GetHandleInformation(child_events[i], &out_flags)) { + ap_log_error(APLOG_MARK, APLOG_CRIT, apr_get_os_error(), + ap_server_conf, APLOGNO(02644) + "Child: Event handle #%d (%pp) is invalid", + i, child_events[i]); + } + } break; } else if (cld == 0) { @@ -1288,13 +1313,13 @@ void child_main(apr_pool_t *pconf, DWORD parent_pid) threads_created); } for (i = 0; i < threads_created; i++) { - int *score_idx; + int *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)); - if (score_idx) { - ap_update_child_status_from_indexes(0, *score_idx, SERVER_DEAD, NULL); + idx = apr_hash_get(ht, &child_handles[i], sizeof(HANDLE)); + if (idx) { + ap_update_child_status_from_indexes(0, *idx, SERVER_DEAD, NULL); } } ap_log_error(APLOG_MARK, APLOG_NOTICE, APR_SUCCESS, ap_server_conf, APLOGNO(00364) |
