comparison src/os/win32/ngx_process.c @ 2725:d43d73277c5c

Win32 master/workers model
author Igor Sysoev <igor@sysoev.ru>
date Mon, 20 Apr 2009 06:08:47 +0000
parents 23fb87bddda1
children d52cf82d0d77
comparison
equal deleted inserted replaced
2724:9fd2f12fee0a 2725:d43d73277c5c
6 6
7 #include <ngx_config.h> 7 #include <ngx_config.h>
8 #include <ngx_core.h> 8 #include <ngx_core.h>
9 9
10 10
11 int ngx_argc; 11 int ngx_argc;
12 char **ngx_argv; 12 char **ngx_argv;
13 char **ngx_os_argv; 13 char **ngx_os_argv;
14 14
15 15 ngx_int_t ngx_last_process;
16 ngx_pid_t ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx) 16 ngx_process_t ngx_processes[NGX_MAX_PROCESSES];
17
18
19 ngx_pid_t
20 ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn)
17 { 21 {
18 return /* STUB */ 0; 22 u_long rc, n;
23 ngx_int_t s;
24 ngx_pid_t pid;
25 ngx_exec_ctx_t ctx;
26 char file[MAX_PATH + 1];
27
28 if (respawn >= 0) {
29 s = respawn;
30
31 } else {
32 for (s = 0; s < ngx_last_process; s++) {
33 if (ngx_processes[s].handle == NULL) {
34 break;
35 }
36 }
37
38 if (s == NGX_MAX_PROCESSES) {
39 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
40 "no more than %d processes can be spawned",
41 NGX_MAX_PROCESSES);
42 return NGX_INVALID_PID;
43 }
44 }
45
46 n = GetModuleFileName(NULL, file, MAX_PATH);
47
48 if (n == 0) {
49 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
50 "GetModuleFileName() failed");
51 return NGX_INVALID_PID;
52 }
53
54 file[n] = '\0';
55
56 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
57 "GetModuleFileName: \"%s\"", file);
58
59 ctx.path = file;
60 ctx.name = name;
61 ctx.argv = NULL;
62 ctx.envp = NULL;
63
64 pid = ngx_execute(cycle, &ctx);
65
66 if (pid == NGX_INVALID_PID) {
67 return pid;
68 }
69
70 ngx_memzero(&ngx_processes[s], sizeof(ngx_process_t));
71
72 ngx_processes[s].handle = ctx.child;
73 ngx_processes[s].pid = pid;
74 ngx_processes[s].name = name;
75
76 ngx_sprintf(ngx_processes[s].term_event, "ngx_%s_term_%ul%Z", name, pid);
77 ngx_sprintf(ngx_processes[s].quit_event, "ngx_%s_quit_%ul%Z", name, pid);
78 ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%ul%Z",
79 name, pid);
80
81 rc = WaitForSingleObject(ngx_master_process_event, 5000);
82
83 ngx_time_update(0, 0);
84
85 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
86 "WaitForSingleObject: %ul", rc);
87
88 switch (rc) {
89
90 case WAIT_OBJECT_0:
91
92 ngx_processes[s].term = OpenEvent(EVENT_MODIFY_STATE, 0,
93 (char *) ngx_processes[s].term_event);
94 if (ngx_processes[s].term == NULL) {
95 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
96 "OpenEvent(\"%s\") failed",
97 ngx_processes[s].term_event);
98 goto failed;
99 }
100
101 ngx_processes[s].quit = OpenEvent(EVENT_MODIFY_STATE, 0,
102 (char *) ngx_processes[s].quit_event);
103 if (ngx_processes[s].quit == NULL) {
104 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
105 "OpenEvent(\"%s\") failed",
106 ngx_processes[s].quit_event);
107 goto failed;
108 }
109
110 ngx_processes[s].reopen = OpenEvent(EVENT_MODIFY_STATE, 0,
111 (char *) ngx_processes[s].reopen_event);
112 if (ngx_processes[s].reopen == NULL) {
113 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
114 "OpenEvent(\"%s\") failed",
115 ngx_processes[s].reopen_event);
116 goto failed;
117 }
118
119 if (ResetEvent(ngx_master_process_event) == 0) {
120 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
121 "ResetEvent(\"%s\") failed",
122 ngx_master_process_event_name);
123 goto failed;
124 }
125
126 break;
127
128 case WAIT_TIMEOUT:
129 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
130 "the event \"%s\" was not signaled for 5s",
131 ngx_master_process_event_name);
132 goto failed;
133
134 case WAIT_FAILED:
135 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
136 "WaitForSingleObject(\"%s\") failed",
137 ngx_master_process_event_name);
138
139 goto failed;
140 }
141
142 if (respawn >= 0) {
143 return pid;
144 }
145
146 switch (respawn) {
147
148 case NGX_PROCESS_RESPAWN:
149 ngx_processes[s].just_respawn = 0;
150 break;
151
152 case NGX_PROCESS_JUST_RESPAWN:
153 ngx_processes[s].just_respawn = 1;
154 break;
155 }
156
157 if (s == ngx_last_process) {
158 ngx_last_process++;
159 }
160
161 return pid;
162
163 failed:
164
165 if (ngx_processes[s].reopen) {
166 ngx_close_handle(ngx_processes[s].reopen);
167 }
168
169 if (ngx_processes[s].quit) {
170 ngx_close_handle(ngx_processes[s].quit);
171 }
172
173 if (ngx_processes[s].term) {
174 ngx_close_handle(ngx_processes[s].term);
175 }
176
177 TerminateProcess(ngx_processes[s].handle, 2);
178
179 if (ngx_processes[s].handle) {
180 ngx_close_handle(ngx_processes[s].handle);
181 }
182
183 return NGX_INVALID_PID;
19 } 184 }
185
186
187 ngx_pid_t
188 ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx)
189 {
190 STARTUPINFO si;
191 PROCESS_INFORMATION pi;
192
193 ngx_memzero(&si, sizeof(STARTUPINFO));
194 si.cb = sizeof(STARTUPINFO);
195
196 ngx_memzero(&pi, sizeof(PROCESS_INFORMATION));
197
198 if (CreateProcess(ctx->path, /* STUB */ NULL,
199 NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)
200 == 0)
201 {
202 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno,
203 "CreateProcess(\"%s\") failed", ngx_argv[0]);
204
205 return 0;
206 }
207
208 ctx->child = pi.hProcess;
209
210 if (CloseHandle(pi.hThread) == 0) {
211 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno,
212 "CloseHandle(pi.hThread) failed");
213 }
214
215 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0,
216 "start %s process %P", ctx->name, pi.dwProcessId);
217
218 return pi.dwProcessId;
219 }