From: Dmitry Stogov Date: Tue, 15 Jul 2008 13:10:42 +0000 (+0000) Subject: Fixed bug #45423 (fastcgi parent process doesn't invoke php_module_shutdown before... X-Git-Tag: BEFORE_HEAD_NS_CHANGE~1253 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6cf169b16ca9f7ebd819b3ff50dc92a0c0ef1473;p=php Fixed bug #45423 (fastcgi parent process doesn't invoke php_module_shutdown before shutdown) (basant dot kukreja at sun dot com) --- diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 8ea189e277..57d8bf8567 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -101,6 +101,12 @@ static int children = 0; */ static int parent = 1; +/* Did parent received exit signals SIG_TERM/SIG_INT/SIG_QUIT */ +static int exit_signal = 0; + +/* Is Parent waiting for children to exit */ +static int parent_waiting = 0; + /** * Process group */ @@ -1235,6 +1241,7 @@ static void init_request_info(TSRMLS_D) } /* }}} */ +#ifndef PHP_WIN32 /** * Clean up child processes upon exit */ @@ -1244,16 +1251,18 @@ void fastcgi_cleanup(int signal) fprintf(stderr, "FastCGI shutdown, pid %d\n", getpid()); #endif -#ifndef PHP_WIN32 sigaction(SIGTERM, &old_term, 0); /* Kill all the processes in our process group */ kill(-pgroup, SIGTERM); -#endif - /* We should exit at this point, but MacOSX doesn't seem to */ - exit(0); + if (parent && parent_waiting) { + exit_signal = 1; + } else { + exit(0); + } } +#endif PHP_INI_BEGIN() STD_PHP_INI_ENTRY("cgi.rfc2616_headers", "0", PHP_INI_ALL, OnUpdateBool, rfc2616_headers, php_cgi_globals_struct, php_cgi_globals) @@ -1596,7 +1605,7 @@ consult the installation file that came with this distribution, or visit \n\ } if (fcgi_in_shutdown()) { - exit(0); + goto parent_out; } while (parent) { @@ -1633,9 +1642,25 @@ consult the installation file that came with this distribution, or visit \n\ #ifdef DEBUG_FASTCGI fprintf(stderr, "Wait for kids, pid %d\n", getpid()); #endif - while (wait(&status) < 0) { + parent_waiting = 1; + while (1) { + if (wait(&status) >= 0) { + running--; + break; + } else if (exit_signal) { + break; + } + } + if (exit_signal) { +#if 0 + while (running > 0) { + while (wait(&status) < 0) { + } + running--; + } +#endif + goto parent_out; } - running--; } } } else { @@ -2098,6 +2123,10 @@ out: #endif } +#ifndef PHP_WIN32 +parent_out: +#endif + SG(server_context) = NULL; php_module_shutdown(TSRMLS_C); sapi_shutdown(); diff --git a/sapi/cgi/fastcgi.c b/sapi/cgi/fastcgi.c index e0ff6f111b..c480abed36 100644 --- a/sapi/cgi/fastcgi.c +++ b/sapi/cgi/fastcgi.c @@ -170,6 +170,20 @@ static void fcgi_signal_handler(int signo) } } +static void fcgi_setup_signals(void) +{ + struct sigaction new_sa, old_sa; + + sigemptyset(&new_sa.sa_mask); + new_sa.sa_flags = 0; + new_sa.sa_handler = fcgi_signal_handler; + sigaction(SIGUSR1, &new_sa, NULL); + sigaction(SIGTERM, &new_sa, NULL); + sigaction(SIGPIPE, NULL, &old_sa); + if (old_sa.sa_handler == SIG_DFL) { + sigaction(SIGPIPE, &new_sa, NULL); + } +} #endif int fcgi_in_shutdown(void) @@ -229,18 +243,7 @@ int fcgi_init(void) is_initialized = 1; errno = 0; if (getpeername(0, (struct sockaddr *)&sa, &len) != 0 && errno == ENOTCONN) { - struct sigaction new_sa, old_sa; - - sigemptyset(&new_sa.sa_mask); - new_sa.sa_flags = 0; - new_sa.sa_handler = fcgi_signal_handler; - sigaction(SIGUSR1, &new_sa, NULL); - sigaction(SIGTERM, &new_sa, NULL); - sigaction(SIGPIPE, NULL, &old_sa); - if (old_sa.sa_handler == SIG_DFL) { - sigaction(SIGPIPE, &new_sa, NULL); - } - + fcgi_setup_signals(); return is_fastcgi = 1; } else { return is_fastcgi = 0; @@ -501,6 +504,8 @@ int fcgi_listen(const char *path, int backlog) if (tcp) { listen_socket = _open_osfhandle((long)listen_socket, 0); } +#else + fcgi_setup_signals(); #endif return listen_socket; }