One Level Up
Top Level
src/os/win32/ngx_process.c - nginx source code
Global variables defined
Functions defined
Source code
- #include <ngx_config.h>
- #include <ngx_core.h>
- int ngx_argc;
- char **ngx_argv;
- char **ngx_os_argv;
- ngx_int_t ngx_last_process;
- ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
- ngx_pid_t
- ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn)
- {
- u_long rc, n, code;
- ngx_int_t s;
- ngx_pid_t pid;
- ngx_exec_ctx_t ctx;
- HANDLE events[2];
- char file[MAX_PATH + 1];
- if (respawn >= 0) {
- s = respawn;
- } else {
- for (s = 0; s < ngx_last_process; s++) {
- if (ngx_processes[s].handle == NULL) {
- break;
- }
- }
- if (s == NGX_MAX_PROCESSES) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "no more than %d processes can be spawned",
- NGX_MAX_PROCESSES);
- return NGX_INVALID_PID;
- }
- }
- n = GetModuleFileName(NULL, file, MAX_PATH);
- if (n == 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "GetModuleFileName() failed");
- return NGX_INVALID_PID;
- }
- file[n] = '\0';
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "GetModuleFileName: \"%s\"", file);
- ctx.path = file;
- ctx.name = name;
- ctx.args = GetCommandLine();
- ctx.argv = NULL;
- ctx.envp = NULL;
- pid = ngx_execute(cycle, &ctx);
- if (pid == NGX_INVALID_PID) {
- return pid;
- }
- ngx_memzero(&ngx_processes[s], sizeof(ngx_process_t));
- ngx_processes[s].handle = ctx.child;
- ngx_processes[s].pid = pid;
- ngx_processes[s].name = name;
- ngx_sprintf(ngx_processes[s].term_event, "ngx_%s_term_%P%Z", name, pid);
- ngx_sprintf(ngx_processes[s].quit_event, "ngx_%s_quit_%P%Z", name, pid);
- ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%P%Z",
- name, pid);
- events[0] = ngx_master_process_event;
- events[1] = ctx.child;
- rc = WaitForMultipleObjects(2, events, 0, 5000);
- ngx_time_update();
- ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
- "WaitForMultipleObjects: %ul", rc);
- switch (rc) {
- case WAIT_OBJECT_0:
- ngx_processes[s].term = OpenEvent(EVENT_MODIFY_STATE, 0,
- (char *) ngx_processes[s].term_event);
- if (ngx_processes[s].term == NULL) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "OpenEvent(\"%s\") failed",
- ngx_processes[s].term_event);
- goto failed;
- }
- ngx_processes[s].quit = OpenEvent(EVENT_MODIFY_STATE, 0,
- (char *) ngx_processes[s].quit_event);
- if (ngx_processes[s].quit == NULL) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "OpenEvent(\"%s\") failed",
- ngx_processes[s].quit_event);
- goto failed;
- }
- ngx_processes[s].reopen = OpenEvent(EVENT_MODIFY_STATE, 0,
- (char *) ngx_processes[s].reopen_event);
- if (ngx_processes[s].reopen == NULL) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "OpenEvent(\"%s\") failed",
- ngx_processes[s].reopen_event);
- goto failed;
- }
- if (ResetEvent(ngx_master_process_event) == 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "ResetEvent(\"%s\") failed",
- ngx_master_process_event_name);
- goto failed;
- }
- break;
- case WAIT_OBJECT_0 + 1:
- if (GetExitCodeProcess(ctx.child, &code) == 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "GetExitCodeProcess(%P) failed", pid);
- }
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "%s process %P exited with code %Xl",
- name, pid, code);
- goto failed;
- case WAIT_TIMEOUT:
- ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
- "the event \"%s\" was not signaled for 5s",
- ngx_master_process_event_name);
- goto failed;
- case WAIT_FAILED:
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "WaitForSingleObject(\"%s\") failed",
- ngx_master_process_event_name);
- goto failed;
- }
- if (respawn >= 0) {
- return pid;
- }
- switch (respawn) {
- case NGX_PROCESS_RESPAWN:
- ngx_processes[s].just_spawn = 0;
- break;
- case NGX_PROCESS_JUST_RESPAWN:
- ngx_processes[s].just_spawn = 1;
- break;
- }
- if (s == ngx_last_process) {
- ngx_last_process++;
- }
- return pid;
- failed:
- if (ngx_processes[s].reopen) {
- ngx_close_handle(ngx_processes[s].reopen);
- }
- if (ngx_processes[s].quit) {
- ngx_close_handle(ngx_processes[s].quit);
- }
- if (ngx_processes[s].term) {
- ngx_close_handle(ngx_processes[s].term);
- }
- TerminateProcess(ngx_processes[s].handle, 2);
- if (ngx_processes[s].handle) {
- ngx_close_handle(ngx_processes[s].handle);
- ngx_processes[s].handle = NULL;
- }
- return NGX_INVALID_PID;
- }
- ngx_pid_t
- ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
- {
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ngx_memzero(&si, sizeof(STARTUPINFO));
- si.cb = sizeof(STARTUPINFO);
- ngx_memzero(&pi, sizeof(PROCESS_INFORMATION));
- if (CreateProcess(ctx->path, ctx->args,
- NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)
- == 0)
- {
- ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
- "CreateProcess(\"%s\") failed", ngx_argv[0]);
- return 0;
- }
- ctx->child = pi.hProcess;
- if (CloseHandle(pi.hThread) == 0) {
- ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
- "CloseHandle(pi.hThread) failed");
- }
- ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
- "start %s process %P", ctx->name, pi.dwProcessId);
- return pi.dwProcessId;
- }
One Level Up
Top Level