From: Anatol Belski Date: Wed, 13 Jan 2016 10:53:29 +0000 (+0100) Subject: Basic implementation for FCGI to respect PHP_FCGI_CHILDREN on Windows X-Git-Tag: php-7.1.0alpha1~617^2~62 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=5b91658365562da78cdb00c8d8f697ba340b3fba;p=php Basic implementation for FCGI to respect PHP_FCGI_CHILDREN on Windows PHP_FCGI_CHILDREN number of children processes will be spawned, sharing same TCP socket. To implement yet - children cleanup on exit - automatic children re-spawning --- diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index c1cca1e3d2..eec97fe686 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -102,7 +102,6 @@ struct sigaction act, old_term, old_quit, old_int; 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 @@ -115,6 +114,7 @@ static int children = 0; */ static int parent = 1; +#ifndef PHP_WIN32 /* Did parent received exit signals SIG_TERM/SIG_INT/SIG_QUIT */ static int exit_signal = 0; @@ -354,9 +354,7 @@ static void sapi_fcgi_flush(void *server_context) fcgi_request *request = (fcgi_request*) server_context; if ( -#ifndef PHP_WIN32 !parent && -#endif request && !fcgi_flush(request, 0)) { php_handle_aborted_connection(); @@ -900,9 +898,7 @@ static int sapi_cgi_deactivate(void) 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(); } @@ -1979,8 +1975,7 @@ consult the installation file that came with this distribution, or visit \n\ /* 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); @@ -1996,6 +1991,7 @@ consult the installation file that came with this distribution, or visit \n\ 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; @@ -2081,6 +2077,77 @@ consult the installation file that came with this distribution, or visit \n\ 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 */ } @@ -2584,9 +2651,7 @@ out: #endif } -#ifndef PHP_WIN32 parent_out: -#endif SG(server_context) = NULL; php_module_shutdown();