From c95ea675e62b14483f683a7b7a7858e950333842 Mon Sep 17 00:00:00 2001 From: Jim Jagielski Date: Thu, 10 Oct 2013 14:34:19 +0000 Subject: [PATCH] Merge r1526666, r1527220 from trunk: WinNT MPM: Exit the child if the parent process crashes or is terminated. Submitted by: Oracle, via trawick The original modification was made some years ago for Oracle HTTP Server by an Oracle employee. trawick made additional changes for style and for trunk/2.4.x changes. Follow up to r1526666: Use SYNCHRONIZE instead of PROCESS_ALL_ACCESS because a. it is sufficient b. it avoids an issue where PROCESS_ALL_ACCESS is larger on newer SDKs, resulting in a run-time error when running on older Windows Close the handle. Submitted by: Ivan Zhakov Submitted by: trawick Reviewed/backported by: jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1531000 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ STATUS | 7 ------- server/mpm/winnt/child.c | 29 +++++++++++++++++++++++++---- server/mpm/winnt/mpm_winnt.c | 2 +- server/mpm/winnt/mpm_winnt.h | 2 +- 5 files changed, 30 insertions(+), 13 deletions(-) diff --git a/CHANGES b/CHANGES index fe60b5d0aa..91d3fb5553 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,9 @@ Changes with Apache 2.4.7 *) core: Don't truncate output when sending is interrupted by a signal, such as from an exiting CGI process. PR 55643. [Jeff Trawick] + *) WinNT MPM: Exit the child if the parent process crashes or is terminated. + [Oracle Corporation] + *) Windows: Correct failure to discard stderr in some error log configurations. (Error message AH00093) [Jeff Trawick] diff --git a/STATUS b/STATUS index 4b86d979ce..0255e7f3a4 100644 --- a/STATUS +++ b/STATUS @@ -98,13 +98,6 @@ PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * WinNT MPM: Exit the child if the parent process crashes or is terminated. - trunk: https://svn.apache.org/r1526666 and r1527220 - 2.4.x: trunk patches work if CHANGES are massaged and log-message-tag change - is ignored; alternately: - http://people.apache.org/~trawick/winnt-child-exits-if-no-parent.txt - +1: trawick, covener, jim - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/server/mpm/winnt/child.c b/server/mpm/winnt/child.c index d350dd79e4..c9168b08ef 100644 --- a/server/mpm/winnt/child.c +++ b/server/mpm/winnt/child.c @@ -950,12 +950,12 @@ static void create_listener_thread(void) } -void child_main(apr_pool_t *pconf) +void child_main(apr_pool_t *pconf, DWORD parent_pid) { apr_status_t status; apr_hash_t *ht; ap_listen_rec *lr; - HANDLE child_events[2]; + HANDLE child_events[3]; HANDLE *child_handles; int listener_started = 0; int threads_created = 0; @@ -965,6 +965,7 @@ void child_main(apr_pool_t *pconf) DWORD tid; int rv; int i; + int num_events; apr_pool_create(&pchild, pconf); apr_pool_tag(pchild, "pchild"); @@ -982,6 +983,16 @@ void child_main(apr_pool_t *pconf) child_events[0] = exit_event; child_events[1] = max_requests_per_child_event; + if (parent_pid != my_pid) { + child_events[2] = OpenProcess(SYNCHRONIZE, FALSE, parent_pid); + num_events = 3; + } + else { + /* presumably -DONE_PROCESS */ + child_events[2] = NULL; + num_events = 2; + } + /* * Wait until we have permission to start accepting connections. * start_mutex is used to ensure that only one child ever @@ -1098,10 +1109,10 @@ void child_main(apr_pool_t *pconf) */ while (1) { #if !APR_HAS_OTHER_CHILD - rv = WaitForMultipleObjects(2, (HANDLE *)child_events, FALSE, INFINITE); + rv = WaitForMultipleObjects(num_events, (HANDLE *)child_events, FALSE, INFINITE); cld = rv - WAIT_OBJECT_0; #else - rv = WaitForMultipleObjects(2, (HANDLE *)child_events, FALSE, 1000); + rv = WaitForMultipleObjects(num_events, (HANDLE *)child_events, FALSE, 1000); cld = rv - WAIT_OBJECT_0; if (rv == WAIT_TIMEOUT) { apr_proc_other_child_refresh_all(APR_OC_REASON_RUNNING); @@ -1122,6 +1133,13 @@ void child_main(apr_pool_t *pconf) "ending."); break; } + else if (cld == 2) { + /* The parent is dead. Shutdown the child process. */ + ap_log_error(APLOG_MARK, APLOG_CRIT, 0, ap_server_conf, APLOGNO(02538) + "Child: Parent process exited abruptly. Child process " + "is ending"); + break; + } else { /* MaxConnectionsPerChild event set by the worker threads. * Signal the parent to restart @@ -1287,6 +1305,9 @@ void child_main(apr_pool_t *pconf) apr_pool_destroy(pchild); CloseHandle(exit_event); + if (child_events[2] != NULL) { + CloseHandle(child_events[2]); + } } #endif /* def WIN32 */ diff --git a/server/mpm/winnt/mpm_winnt.c b/server/mpm/winnt/mpm_winnt.c index 4e3b23ceb0..957af63983 100644 --- a/server/mpm/winnt/mpm_winnt.c +++ b/server/mpm/winnt/mpm_winnt.c @@ -1708,7 +1708,7 @@ static int winnt_run(apr_pool_t *_pconf, apr_pool_t *plog, server_rec *s ) ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00453) "Child process is running"); - child_main(pconf); + child_main(pconf, parent_pid); ap_log_error(APLOG_MARK, APLOG_DEBUG, APR_SUCCESS, ap_server_conf, APLOGNO(00454) "Child process is exiting"); diff --git a/server/mpm/winnt/mpm_winnt.h b/server/mpm/winnt/mpm_winnt.h index 7452f9fb78..8fb595b423 100644 --- a/server/mpm/winnt/mpm_winnt.h +++ b/server/mpm/winnt/mpm_winnt.h @@ -90,7 +90,7 @@ AP_DECLARE(void) ap_signal_parent(ap_signal_parent_e type); void hold_console_open_on_error(void); /* From child.c: */ -void child_main(apr_pool_t *pconf); +void child_main(apr_pool_t *pconf, DWORD parent_pid); apr_status_t winnt_insert_network_bucket(conn_rec *c, apr_bucket_brigade *bb, apr_socket_t *socket); -- 2.40.0