static void (*php_php_import_environment_variables)(zval *array_ptr);
-#ifndef PHP_WIN32
/* these globals used for forking children on unix systems */
/**
* Number of child processes that will get created to service requests
*/
static int parent = 1;
+#ifndef PHP_WIN32
/* Did parent received exit signals SIG_TERM/SIG_INT/SIG_QUIT */
static int exit_signal = 0;
fcgi_request *request = (fcgi_request*) server_context;
if (
-#ifndef PHP_WIN32
!parent &&
-#endif
request && !fcgi_flush(request, 0)) {
php_handle_aborted_connection();
if (SG(sapi_started)) {
if (fcgi_is_fastcgi()) {
if (
-#ifndef PHP_WIN32
!parent &&
-#endif
!fcgi_finish_request((fcgi_request*)SG(server_context), 0)) {
php_handle_aborted_connection();
}
/* library is already initialized, now init our request */
request = fcgi_init_request(fcgi_fd, NULL, NULL, NULL);
-#ifndef PHP_WIN32
- /* Pre-fork, if required */
+ /* Pre-fork or spawn, if required */
if (getenv("PHP_FCGI_CHILDREN")) {
char * children_str = getenv("PHP_FCGI_CHILDREN");
children = atoi(children_str);
fcgi_set_mgmt_var("FCGI_MAX_REQS", sizeof("FCGI_MAX_REQS")-1, "1", sizeof("1")-1);
}
+#ifndef PHP_WIN32
if (children) {
int running = 0;
pid_t pid;
parent = 0;
}
+#else
+ if (children) {
+ char *cmd_line;
+ HANDLE kid_cgi_ps[64];
+ int kids = children < 64 ? children : 64;
+ char kid_buf[16];
+ char my_name[MAX_PATH] = {0};
+
+ SetEnvironmentVariable("PHP_FCGI_CHILDREN", NULL); /* kids will inherit the env, don't let them spawn */
+
+ GetModuleFileName(NULL, my_name, MAX_PATH);
+ cmd_line = my_name;
+
+ while (0 < kids--) {
+ PROCESS_INFORMATION pi;
+ STARTUPINFO si;
+
+ ZeroMemory(&si, sizeof(si));
+ si.cb = sizeof(si);
+ ZeroMemory(&pi, sizeof(pi));
+
+ si.dwFlags = STARTF_USESTDHANDLES;
+ si.hStdOutput = INVALID_HANDLE_VALUE;
+ si.hStdInput = (HANDLE)_get_osfhandle(fcgi_fd);
+ si.hStdError = INVALID_HANDLE_VALUE;
+
+ if (CreateProcess(NULL, cmd_line, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
+ kid_cgi_ps[kids] = pi.hProcess;
+ CloseHandle(pi.hThread);
+ } else {
+ DWORD err = GetLastError();
+ char *err_text;
+
+ kid_cgi_ps[kids] = INVALID_HANDLE_VALUE;
+
+ (void)FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ARGUMENT_ARRAY,
+ NULL,
+ err,
+ LANG_NEUTRAL,
+ (LPTSTR)&err_text,
+ 0,
+ NULL);
+
+ fprintf(stderr, "unable to spawn: [0x%08lx]: %s\n", err, err_text);
+ }
+ }
+
+ snprintf(kid_buf, 16, "%d", children);
+ SetEnvironmentVariable("PHP_FCGI_CHILDREN", kid_buf); /* restore my env */
+
+ kids = children < 64 ? children : 64;
+ WaitForMultipleObjects(kids, kid_cgi_ps, FALSE, INFINITE);
+
+ while (0 < kids--) {
+ DWORD status;
+
+ if (INVALID_HANDLE_VALUE == kid_cgi_ps[kids]) {
+ if(!GetExitCodeProcess(kid_cgi_ps[kids], &status)) {
+ continue;
+ }
+
+ if(status != STILL_ACTIVE){
+ CloseHandle(kid_cgi_ps[kids]);
+ kid_cgi_ps[kids] = INVALID_HANDLE_VALUE;
+ }
+ }
+ }
+ goto parent_out;
+ } else {
+ parent = 0;
+ }
#endif /* WIN32 */
}
#endif
}
-#ifndef PHP_WIN32
parent_out:
-#endif
SG(server_context) = NULL;
php_module_shutdown();