Mercurial > hg > nginx
annotate src/os/win32/ngx_process.c @ 3818:a21a6d898685
bump version
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 06 Dec 2010 14:40:40 +0000 |
parents | ab353d7dc182 |
children | d620f497c50f |
rev | line source |
---|---|
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
280
diff
changeset
|
1 |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
280
diff
changeset
|
2 /* |
444
42d11f017717
nginx-0.1.0-2004-09-29-20:00:49 import; remove years from copyright
Igor Sysoev <igor@sysoev.ru>
parents:
441
diff
changeset
|
3 * Copyright (C) Igor Sysoev |
441
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
280
diff
changeset
|
4 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
280
diff
changeset
|
5 |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
6 |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 #include <ngx_config.h> |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_core.h> |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 |
2725 | 11 int ngx_argc; |
12 char **ngx_argv; | |
13 char **ngx_os_argv; | |
14 | |
15 ngx_int_t ngx_last_process; | |
16 ngx_process_t ngx_processes[NGX_MAX_PROCESSES]; | |
452 | 17 |
18 | |
2725 | 19 ngx_pid_t |
20 ngx_spawn_process(ngx_cycle_t *cycle, char *name, ngx_int_t respawn) | |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
21 { |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
22 u_long rc, n, code; |
2725 | 23 ngx_int_t s; |
24 ngx_pid_t pid; | |
25 ngx_exec_ctx_t ctx; | |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
26 HANDLE events[2]; |
2725 | 27 char file[MAX_PATH + 1]; |
28 | |
29 if (respawn >= 0) { | |
30 s = respawn; | |
31 | |
32 } else { | |
33 for (s = 0; s < ngx_last_process; s++) { | |
34 if (ngx_processes[s].handle == NULL) { | |
35 break; | |
36 } | |
37 } | |
38 | |
39 if (s == NGX_MAX_PROCESSES) { | |
40 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
41 "no more than %d processes can be spawned", | |
42 NGX_MAX_PROCESSES); | |
43 return NGX_INVALID_PID; | |
44 } | |
45 } | |
46 | |
47 n = GetModuleFileName(NULL, file, MAX_PATH); | |
48 | |
49 if (n == 0) { | |
50 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
51 "GetModuleFileName() failed"); | |
52 return NGX_INVALID_PID; | |
53 } | |
54 | |
55 file[n] = '\0'; | |
56 | |
57 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
58 "GetModuleFileName: \"%s\"", file); | |
59 | |
60 ctx.path = file; | |
61 ctx.name = name; | |
2745
1983932b8075
pass command lines options to workers
Igor Sysoev <igor@sysoev.ru>
parents:
2737
diff
changeset
|
62 ctx.args = GetCommandLine(); |
2725 | 63 ctx.argv = NULL; |
64 ctx.envp = NULL; | |
65 | |
66 pid = ngx_execute(cycle, &ctx); | |
67 | |
68 if (pid == NGX_INVALID_PID) { | |
69 return pid; | |
70 } | |
71 | |
72 ngx_memzero(&ngx_processes[s], sizeof(ngx_process_t)); | |
73 | |
74 ngx_processes[s].handle = ctx.child; | |
75 ngx_processes[s].pid = pid; | |
76 ngx_processes[s].name = name; | |
77 | |
78 ngx_sprintf(ngx_processes[s].term_event, "ngx_%s_term_%ul%Z", name, pid); | |
79 ngx_sprintf(ngx_processes[s].quit_event, "ngx_%s_quit_%ul%Z", name, pid); | |
80 ngx_sprintf(ngx_processes[s].reopen_event, "ngx_%s_reopen_%ul%Z", | |
81 name, pid); | |
82 | |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
83 events[0] = ngx_master_process_event; |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
84 events[1] = ctx.child; |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
85 |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
86 rc = WaitForMultipleObjects(2, events, 0, 5000); |
2725 | 87 |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
88 ngx_time_update(); |
2725 | 89 |
90 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
91 "WaitForMultipleObjects: %ul", rc); |
2725 | 92 |
93 switch (rc) { | |
94 | |
95 case WAIT_OBJECT_0: | |
96 | |
97 ngx_processes[s].term = OpenEvent(EVENT_MODIFY_STATE, 0, | |
98 (char *) ngx_processes[s].term_event); | |
99 if (ngx_processes[s].term == NULL) { | |
100 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
101 "OpenEvent(\"%s\") failed", | |
102 ngx_processes[s].term_event); | |
103 goto failed; | |
104 } | |
105 | |
106 ngx_processes[s].quit = OpenEvent(EVENT_MODIFY_STATE, 0, | |
107 (char *) ngx_processes[s].quit_event); | |
108 if (ngx_processes[s].quit == NULL) { | |
109 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
110 "OpenEvent(\"%s\") failed", | |
111 ngx_processes[s].quit_event); | |
112 goto failed; | |
113 } | |
114 | |
115 ngx_processes[s].reopen = OpenEvent(EVENT_MODIFY_STATE, 0, | |
116 (char *) ngx_processes[s].reopen_event); | |
117 if (ngx_processes[s].reopen == NULL) { | |
118 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
119 "OpenEvent(\"%s\") failed", | |
120 ngx_processes[s].reopen_event); | |
121 goto failed; | |
122 } | |
123 | |
124 if (ResetEvent(ngx_master_process_event) == 0) { | |
125 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
126 "ResetEvent(\"%s\") failed", | |
127 ngx_master_process_event_name); | |
128 goto failed; | |
129 } | |
130 | |
131 break; | |
2737
d52cf82d0d77
style fix: remove trailing spaces
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
132 |
2909
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
133 case WAIT_OBJECT_0 + 1: |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
134 if (GetExitCodeProcess(ctx.child, &code) == 0) { |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
135 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
136 "GetExitCodeProcess(%P) failed", pid); |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
137 } |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
138 |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
139 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
140 "%s process %P exited with code %Xul", |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
141 name, pid, code); |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
142 |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
143 goto failed; |
3f287b615408
test premature process termination
Igor Sysoev <igor@sysoev.ru>
parents:
2745
diff
changeset
|
144 |
2725 | 145 case WAIT_TIMEOUT: |
146 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
147 "the event \"%s\" was not signaled for 5s", | |
148 ngx_master_process_event_name); | |
149 goto failed; | |
150 | |
151 case WAIT_FAILED: | |
152 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
153 "WaitForSingleObject(\"%s\") failed", | |
154 ngx_master_process_event_name); | |
155 | |
156 goto failed; | |
157 } | |
158 | |
159 if (respawn >= 0) { | |
160 return pid; | |
161 } | |
162 | |
163 switch (respawn) { | |
164 | |
165 case NGX_PROCESS_RESPAWN: | |
3016
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2909
diff
changeset
|
166 ngx_processes[s].just_spawn = 0; |
2725 | 167 break; |
168 | |
169 case NGX_PROCESS_JUST_RESPAWN: | |
3016
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2909
diff
changeset
|
170 ngx_processes[s].just_spawn = 1; |
2725 | 171 break; |
172 } | |
173 | |
174 if (s == ngx_last_process) { | |
175 ngx_last_process++; | |
176 } | |
177 | |
178 return pid; | |
179 | |
180 failed: | |
181 | |
182 if (ngx_processes[s].reopen) { | |
183 ngx_close_handle(ngx_processes[s].reopen); | |
184 } | |
185 | |
186 if (ngx_processes[s].quit) { | |
187 ngx_close_handle(ngx_processes[s].quit); | |
188 } | |
189 | |
190 if (ngx_processes[s].term) { | |
191 ngx_close_handle(ngx_processes[s].term); | |
192 } | |
193 | |
194 TerminateProcess(ngx_processes[s].handle, 2); | |
195 | |
196 if (ngx_processes[s].handle) { | |
197 ngx_close_handle(ngx_processes[s].handle); | |
198 } | |
199 | |
200 return NGX_INVALID_PID; | |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
201 } |
2725 | 202 |
203 | |
204 ngx_pid_t | |
205 ngx_execute(ngx_cycle_t *cycle, ngx_exec_ctx_t *ctx) | |
206 { | |
207 STARTUPINFO si; | |
208 PROCESS_INFORMATION pi; | |
209 | |
210 ngx_memzero(&si, sizeof(STARTUPINFO)); | |
211 si.cb = sizeof(STARTUPINFO); | |
212 | |
213 ngx_memzero(&pi, sizeof(PROCESS_INFORMATION)); | |
214 | |
2745
1983932b8075
pass command lines options to workers
Igor Sysoev <igor@sysoev.ru>
parents:
2737
diff
changeset
|
215 if (CreateProcess(ctx->path, ctx->args, |
2725 | 216 NULL, NULL, 0, CREATE_NO_WINDOW, NULL, NULL, &si, &pi) |
217 == 0) | |
218 { | |
219 ngx_log_error(NGX_LOG_CRIT, cycle->log, ngx_errno, | |
220 "CreateProcess(\"%s\") failed", ngx_argv[0]); | |
221 | |
222 return 0; | |
223 } | |
224 | |
225 ctx->child = pi.hProcess; | |
226 | |
227 if (CloseHandle(pi.hThread) == 0) { | |
228 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
229 "CloseHandle(pi.hThread) failed"); | |
230 } | |
231 | |
232 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, | |
233 "start %s process %P", ctx->name, pi.dwProcessId); | |
234 | |
235 return pi.dwProcessId; | |
236 } |