Skip to content

Commit 092a87c

Browse files
committed
implement FCGI children automatic restart and cleanup
1 parent 5b91658 commit 092a87c

File tree

1 file changed

+80
-47
lines changed

1 file changed

+80
-47
lines changed

sapi/cgi/cgi_main.c

Lines changed: 80 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,12 @@ static php_cgi_globals_struct php_cgi_globals;
222222
#define TRANSLATE_SLASHES(path)
223223
#endif
224224

225+
#ifdef PHP_WIN32
226+
#define WIN32_MAX_SPAWN_CHILDREN 64
227+
HANDLE win32_kid_cgi_ps[WIN32_MAX_SPAWN_CHILDREN];
228+
int win32_kids;
229+
#endif
230+
225231
#ifndef HAVE_ATTRIBUTE_WEAK
226232
static void fcgi_log(int type, const char *format, ...) {
227233
va_list ap;
@@ -1427,6 +1433,25 @@ void fastcgi_cleanup(int signal)
14271433
exit(0);
14281434
}
14291435
}
1436+
#else
1437+
BOOL fastcgi_cleanup(DWORD sig)
1438+
{
1439+
int i = win32_kids;
1440+
1441+
while (0 < i--) {
1442+
if (NULL == win32_kid_cgi_ps[i]) {
1443+
continue;
1444+
}
1445+
1446+
TerminateProcess(win32_kid_cgi_ps[i], 0);
1447+
CloseHandle(win32_kid_cgi_ps[i]);
1448+
win32_kid_cgi_ps[i] = NULL;
1449+
}
1450+
1451+
parent = 0;
1452+
1453+
return TRUE;
1454+
}
14301455
#endif
14311456

14321457
PHP_INI_BEGIN()
@@ -2080,70 +2105,78 @@ consult the installation file that came with this distribution, or visit \n\
20802105
#else
20812106
if (children) {
20822107
char *cmd_line;
2083-
HANDLE kid_cgi_ps[64];
2084-
int kids = children < 64 ? children : 64;
20852108
char kid_buf[16];
20862109
char my_name[MAX_PATH] = {0};
2110+
int i;
2111+
2112+
ZeroMemory(&win32_kid_cgi_ps, sizeof(win32_kid_cgi_ps));
2113+
win32_kids = children < WIN32_MAX_SPAWN_CHILDREN ? children : WIN32_MAX_SPAWN_CHILDREN;
2114+
2115+
SetConsoleCtrlHandler(fastcgi_cleanup, TRUE);
20872116

20882117
SetEnvironmentVariable("PHP_FCGI_CHILDREN", NULL); /* kids will inherit the env, don't let them spawn */
20892118

20902119
GetModuleFileName(NULL, my_name, MAX_PATH);
20912120
cmd_line = my_name;
20922121

2093-
while (0 < kids--) {
2094-
PROCESS_INFORMATION pi;
2095-
STARTUPINFO si;
2096-
2097-
ZeroMemory(&si, sizeof(si));
2098-
si.cb = sizeof(si);
2099-
ZeroMemory(&pi, sizeof(pi));
2100-
2101-
si.dwFlags = STARTF_USESTDHANDLES;
2102-
si.hStdOutput = INVALID_HANDLE_VALUE;
2103-
si.hStdInput = (HANDLE)_get_osfhandle(fcgi_fd);
2104-
si.hStdError = INVALID_HANDLE_VALUE;
2105-
2106-
if (CreateProcess(NULL, cmd_line, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
2107-
kid_cgi_ps[kids] = pi.hProcess;
2108-
CloseHandle(pi.hThread);
2109-
} else {
2110-
DWORD err = GetLastError();
2111-
char *err_text;
2112-
2113-
kid_cgi_ps[kids] = INVALID_HANDLE_VALUE;
2114-
2115-
(void)FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
2116-
NULL,
2117-
err,
2118-
LANG_NEUTRAL,
2119-
(LPTSTR)&err_text,
2120-
0,
2121-
NULL);
2122-
2123-
fprintf(stderr, "unable to spawn: [0x%08lx]: %s\n", err, err_text);
2122+
while (parent) {
2123+
i = win32_kids;
2124+
while (0 < i--) {
2125+
DWORD status;
2126+
2127+
if (NULL != win32_kid_cgi_ps[i]) {
2128+
if(!GetExitCodeProcess(win32_kid_cgi_ps[i], &status) || status != STILL_ACTIVE) {
2129+
CloseHandle(win32_kid_cgi_ps[i]);
2130+
win32_kid_cgi_ps[i] = NULL;
2131+
}
2132+
}
21242133
}
2125-
}
2126-
2127-
snprintf(kid_buf, 16, "%d", children);
2128-
SetEnvironmentVariable("PHP_FCGI_CHILDREN", kid_buf); /* restore my env */
21292134

2130-
kids = children < 64 ? children : 64;
2131-
WaitForMultipleObjects(kids, kid_cgi_ps, FALSE, INFINITE);
2135+
i = win32_kids;
2136+
while (0 < i--) {
2137+
PROCESS_INFORMATION pi;
2138+
STARTUPINFO si;
21322139

2133-
while (0 < kids--) {
2134-
DWORD status;
2135-
2136-
if (INVALID_HANDLE_VALUE == kid_cgi_ps[kids]) {
2137-
if(!GetExitCodeProcess(kid_cgi_ps[kids], &status)) {
2140+
if (NULL != win32_kid_cgi_ps[i]) {
21382141
continue;
21392142
}
21402143

2141-
if(status != STILL_ACTIVE){
2142-
CloseHandle(kid_cgi_ps[kids]);
2143-
kid_cgi_ps[kids] = INVALID_HANDLE_VALUE;
2144+
ZeroMemory(&si, sizeof(si));
2145+
si.cb = sizeof(si);
2146+
ZeroMemory(&pi, sizeof(pi));
2147+
2148+
si.dwFlags = STARTF_USESTDHANDLES;
2149+
si.hStdOutput = INVALID_HANDLE_VALUE;
2150+
si.hStdInput = (HANDLE)_get_osfhandle(fcgi_fd);
2151+
si.hStdError = INVALID_HANDLE_VALUE;
2152+
2153+
if (CreateProcess(NULL, cmd_line, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
2154+
win32_kid_cgi_ps[i] = pi.hProcess;
2155+
CloseHandle(pi.hThread);
2156+
} else {
2157+
DWORD err = GetLastError();
2158+
char *err_text;
2159+
2160+
win32_kid_cgi_ps[i] = NULL;
2161+
2162+
(void)FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
2163+
NULL,
2164+
err,
2165+
LANG_NEUTRAL,
2166+
(LPTSTR)&err_text,
2167+
0,
2168+
NULL);
2169+
2170+
fprintf(stderr, "unable to spawn: [0x%08lx]: %s\n", err, err_text);
21442171
}
21452172
}
2173+
2174+
WaitForMultipleObjects(win32_kids, win32_kid_cgi_ps, FALSE, INFINITE);
21462175
}
2176+
2177+
snprintf(kid_buf, 16, "%d", children);
2178+
SetEnvironmentVariable("PHP_FCGI_CHILDREN", kid_buf); /* restore my env */
2179+
21472180
goto parent_out;
21482181
} else {
21492182
parent = 0;

0 commit comments

Comments
 (0)