summaryrefslogtreecommitdiff
path: root/server/mpm/winnt/child.c
diff options
context:
space:
mode:
Diffstat (limited to 'server/mpm/winnt/child.c')
-rw-r--r--server/mpm/winnt/child.c43
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)