Mercurial > hg > nginx
annotate src/os/win32/ngx_process_cycle.c @ 6791:cb4a4e9bba8e
Perl: fixed optimization in SSI command handler.
As the pointer to the first argument was tested instead of the argument
itself, array of arguments was always created, even if there were no
arguments. Fix is to test args[0] instead of args.
Found by Coverity (CID 1356862).
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 01 Nov 2016 20:39:21 +0300 |
parents | ca709bca4b77 |
children | 3069dd358ba2 |
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:
368
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:
368
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 |
4412 | 4 * Copyright (C) Nginx, Inc. |
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:
368
diff
changeset
|
5 */ |
da8c5707af39
nginx-0.1.0-2004-09-28-12:34:51 import; set copyright and remove unused files
Igor Sysoev <igor@sysoev.ru>
parents:
368
diff
changeset
|
6 |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
7 |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
8 #include <ngx_config.h> |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
9 #include <ngx_core.h> |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
10 #include <ngx_event.h> |
461 | 11 #include <nginx.h> |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
12 |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
13 |
2725 | 14 static void ngx_console_init(ngx_cycle_t *cycle); |
15 static int __stdcall ngx_console_handler(u_long type); | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
16 static ngx_int_t ngx_create_signal_events(ngx_cycle_t *cycle); |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
17 static ngx_int_t ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type); |
2725 | 18 static void ngx_reopen_worker_processes(ngx_cycle_t *cycle); |
19 static void ngx_quit_worker_processes(ngx_cycle_t *cycle, ngx_uint_t old); | |
20 static void ngx_terminate_worker_processes(ngx_cycle_t *cycle); | |
21 static ngx_uint_t ngx_reap_worker(ngx_cycle_t *cycle, HANDLE h); | |
22 static void ngx_master_process_exit(ngx_cycle_t *cycle); | |
23 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, char *mevn); | |
24 static void ngx_worker_process_exit(ngx_cycle_t *cycle); | |
25 static ngx_thread_value_t __stdcall ngx_worker_thread(void *data); | |
26 static ngx_thread_value_t __stdcall ngx_cache_manager_thread(void *data); | |
27 static void ngx_cache_manager_process_handler(void); | |
3022 | 28 static ngx_thread_value_t __stdcall ngx_cache_loader_thread(void *data); |
368
15c84a40e87d
nginx-0.0.7-2004-06-24-20:07:04 import
Igor Sysoev <igor@sysoev.ru>
parents:
326
diff
changeset
|
29 |
306
6b91bfbc4123
nginx-0.0.3-2004-04-05-00:32:09 import
Igor Sysoev <igor@sysoev.ru>
parents:
302
diff
changeset
|
30 |
2725 | 31 ngx_uint_t ngx_process; |
6151
b4cc553aafeb
Introduced worker number, ngx_worker.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6111
diff
changeset
|
32 ngx_uint_t ngx_worker; |
2725 | 33 ngx_pid_t ngx_pid; |
290
87e73f067470
nginx-0.0.2-2004-03-16-10:10:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
282
diff
changeset
|
34 |
2725 | 35 ngx_uint_t ngx_inherited; |
36 ngx_pid_t ngx_new_binary; | |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
37 |
2725 | 38 sig_atomic_t ngx_terminate; |
39 sig_atomic_t ngx_quit; | |
40 sig_atomic_t ngx_reopen; | |
41 sig_atomic_t ngx_reconfigure; | |
42 ngx_uint_t ngx_exiting; | |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
43 |
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
44 |
2725 | 45 HANDLE ngx_master_process_event; |
46 char ngx_master_process_event_name[NGX_PROCESS_SYNC_NAME]; | |
47 | |
48 static HANDLE ngx_stop_event; | |
49 static char ngx_stop_event_name[NGX_PROCESS_SYNC_NAME]; | |
50 static HANDLE ngx_quit_event; | |
51 static char ngx_quit_event_name[NGX_PROCESS_SYNC_NAME]; | |
52 static HANDLE ngx_reopen_event; | |
53 static char ngx_reopen_event_name[NGX_PROCESS_SYNC_NAME]; | |
54 static HANDLE ngx_reload_event; | |
55 static char ngx_reload_event_name[NGX_PROCESS_SYNC_NAME]; | |
56 | |
57 HANDLE ngx_cache_manager_mutex; | |
58 char ngx_cache_manager_mutex_name[NGX_PROCESS_SYNC_NAME]; | |
59 HANDLE ngx_cache_manager_event; | |
461 | 60 |
290
87e73f067470
nginx-0.0.2-2004-03-16-10:10:12 import
Igor Sysoev <igor@sysoev.ru>
parents:
282
diff
changeset
|
61 |
509 | 62 void |
63 ngx_master_process_cycle(ngx_cycle_t *cycle) | |
278
0ba4821f4460
nginx-0.0.2-2004-03-04-10:04:55 import
Igor Sysoev <igor@sysoev.ru>
parents:
diff
changeset
|
64 { |
2725 | 65 u_long nev, ev, timeout; |
66 ngx_err_t err; | |
67 ngx_int_t n; | |
68 ngx_msec_t timer; | |
69 ngx_uint_t live; | |
70 HANDLE events[MAXIMUM_WAIT_OBJECTS]; | |
71 | |
72 ngx_sprintf((u_char *) ngx_master_process_event_name, | |
73 "ngx_master_%s%Z", ngx_unique); | |
74 | |
75 if (ngx_process == NGX_PROCESS_WORKER) { | |
76 ngx_worker_process_cycle(cycle, ngx_master_process_event_name); | |
77 return; | |
78 } | |
79 | |
80 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "master started"); | |
81 | |
82 ngx_console_init(cycle); | |
83 | |
84 SetEnvironmentVariable("ngx_unique", ngx_unique); | |
85 | |
86 ngx_master_process_event = CreateEvent(NULL, 1, 0, | |
87 ngx_master_process_event_name); | |
88 if (ngx_master_process_event == NULL) { | |
89 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
90 "CreateEvent(\"%s\") failed", | |
91 ngx_master_process_event_name); | |
92 exit(2); | |
93 } | |
94 | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
95 if (ngx_create_signal_events(cycle) != NGX_OK) { |
2725 | 96 exit(2); |
97 } | |
98 | |
99 ngx_sprintf((u_char *) ngx_cache_manager_mutex_name, | |
100 "ngx_cache_manager_mutex_%s%Z", ngx_unique); | |
101 | |
102 ngx_cache_manager_mutex = CreateMutex(NULL, 0, | |
103 ngx_cache_manager_mutex_name); | |
104 if (ngx_cache_manager_mutex == NULL) { | |
105 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
106 "CreateMutex(\"%s\") failed", ngx_cache_manager_mutex_name); | |
107 exit(2); | |
108 } | |
109 | |
110 | |
111 events[0] = ngx_stop_event; | |
112 events[1] = ngx_quit_event; | |
113 events[2] = ngx_reopen_event; | |
114 events[3] = ngx_reload_event; | |
115 | |
116 ngx_close_listening_sockets(cycle); | |
117 | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
118 if (ngx_start_worker_processes(cycle, NGX_PROCESS_RESPAWN) == 0) { |
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
119 exit(2); |
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
120 } |
2725 | 121 |
122 timer = 0; | |
123 timeout = INFINITE; | |
124 | |
125 for ( ;; ) { | |
126 | |
127 nev = 4; | |
128 for (n = 0; n < ngx_last_process; n++) { | |
129 if (ngx_processes[n].handle) { | |
130 events[nev++] = ngx_processes[n].handle; | |
131 } | |
132 } | |
133 | |
134 if (timer) { | |
135 timeout = timer > ngx_current_msec ? timer - ngx_current_msec : 0; | |
136 } | |
137 | |
138 ev = WaitForMultipleObjects(nev, events, 0, timeout); | |
139 | |
140 err = ngx_errno; | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
141 ngx_time_update(); |
2725 | 142 |
143 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
144 "master WaitForMultipleObjects: %ul", ev); | |
145 | |
146 if (ev == WAIT_OBJECT_0) { | |
147 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); | |
324
0ab66f4b6c4d
nginx-0.0.3-2004-04-22-00:13:48 import
Igor Sysoev <igor@sysoev.ru>
parents:
318
diff
changeset
|
148 |
2725 | 149 if (ResetEvent(ngx_stop_event) == 0) { |
150 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
151 "ResetEvent(\"%s\") failed", ngx_stop_event_name); | |
152 } | |
153 | |
154 if (timer == 0) { | |
155 timer = ngx_current_msec + 5000; | |
156 } | |
157 | |
158 ngx_terminate = 1; | |
159 ngx_quit_worker_processes(cycle, 0); | |
160 | |
161 continue; | |
162 } | |
163 | |
164 if (ev == WAIT_OBJECT_0 + 1) { | |
165 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "shutting down"); | |
166 | |
167 if (ResetEvent(ngx_quit_event) == 0) { | |
168 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
169 "ResetEvent(\"%s\") failed", ngx_quit_event_name); | |
170 } | |
171 | |
172 ngx_quit = 1; | |
173 ngx_quit_worker_processes(cycle, 0); | |
174 | |
175 continue; | |
176 } | |
177 | |
178 if (ev == WAIT_OBJECT_0 + 2) { | |
179 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); | |
180 | |
181 if (ResetEvent(ngx_reopen_event) == 0) { | |
182 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
183 "ResetEvent(\"%s\") failed", | |
184 ngx_reopen_event_name); | |
185 } | |
186 | |
187 ngx_reopen_files(cycle, -1); | |
188 ngx_reopen_worker_processes(cycle); | |
189 | |
190 continue; | |
191 } | |
192 | |
193 if (ev == WAIT_OBJECT_0 + 3) { | |
194 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring"); | |
195 | |
196 if (ResetEvent(ngx_reload_event) == 0) { | |
197 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
198 "ResetEvent(\"%s\") failed", | |
199 ngx_reload_event_name); | |
200 } | |
201 | |
2823 | 202 cycle = ngx_init_cycle(cycle); |
203 if (cycle == NULL) { | |
204 cycle = (ngx_cycle_t *) ngx_cycle; | |
205 continue; | |
206 } | |
207 | |
208 ngx_cycle = cycle; | |
209 | |
2928 | 210 ngx_close_listening_sockets(cycle); |
211 | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
212 if (ngx_start_worker_processes(cycle, NGX_PROCESS_JUST_RESPAWN)) { |
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
213 ngx_quit_worker_processes(cycle, 1); |
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
214 } |
2725 | 215 |
216 continue; | |
217 } | |
218 | |
219 if (ev > WAIT_OBJECT_0 + 3 && ev < WAIT_OBJECT_0 + nev) { | |
220 | |
221 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "reap worker"); | |
222 | |
223 live = ngx_reap_worker(cycle, events[ev]); | |
224 | |
225 if (!live && (ngx_terminate || ngx_quit)) { | |
226 ngx_master_process_exit(cycle); | |
227 } | |
228 | |
229 continue; | |
230 } | |
231 | |
232 if (ev == WAIT_TIMEOUT) { | |
233 ngx_terminate_worker_processes(cycle); | |
234 | |
235 ngx_master_process_exit(cycle); | |
236 } | |
237 | |
238 if (ev == WAIT_FAILED) { | |
239 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, | |
240 "WaitForMultipleObjects() failed"); | |
241 | |
242 continue; | |
243 } | |
244 | |
245 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
246 "WaitForMultipleObjects() returned unexpected value %ul", ev); | |
247 } | |
318
56496082668b
nginx-0.0.3-2004-04-16-09:14:16 import
Igor Sysoev <igor@sysoev.ru>
parents:
306
diff
changeset
|
248 } |
56496082668b
nginx-0.0.3-2004-04-16-09:14:16 import
Igor Sysoev <igor@sysoev.ru>
parents:
306
diff
changeset
|
249 |
56496082668b
nginx-0.0.3-2004-04-16-09:14:16 import
Igor Sysoev <igor@sysoev.ru>
parents:
306
diff
changeset
|
250 |
2725 | 251 static void |
252 ngx_console_init(ngx_cycle_t *cycle) | |
253 { | |
254 ngx_core_conf_t *ccf; | |
255 | |
256 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | |
257 | |
258 if (ccf->daemon) { | |
259 if (FreeConsole() == 0) { | |
260 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
261 "FreeConsole() failed"); | |
262 } | |
263 | |
264 return; | |
265 } | |
266 | |
267 if (SetConsoleCtrlHandler(ngx_console_handler, 1) == 0) { | |
268 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
269 "SetConsoleCtrlHandler() failed"); | |
270 } | |
271 } | |
272 | |
273 | |
274 static int __stdcall | |
275 ngx_console_handler(u_long type) | |
276 { | |
277 char *msg; | |
278 | |
279 switch (type) { | |
280 | |
281 case CTRL_C_EVENT: | |
282 msg = "Ctrl-C pressed, exiting"; | |
283 break; | |
284 | |
285 case CTRL_BREAK_EVENT: | |
286 msg = "Ctrl-Break pressed, exiting"; | |
287 break; | |
288 | |
289 case CTRL_CLOSE_EVENT: | |
290 msg = "console closing, exiting"; | |
291 break; | |
292 | |
293 case CTRL_LOGOFF_EVENT: | |
294 msg = "user logs off, exiting"; | |
295 break; | |
296 | |
297 default: | |
298 return 0; | |
299 } | |
300 | |
301 ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, msg); | |
302 | |
303 if (ngx_stop_event == NULL) { | |
304 return 1; | |
305 } | |
306 | |
307 if (SetEvent(ngx_stop_event) == 0) { | |
308 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, | |
309 "SetEvent(\"%s\") failed", ngx_stop_event_name); | |
2627 | 310 } |
311 | |
2725 | 312 return 1; |
313 } | |
314 | |
315 | |
316 static ngx_int_t | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
317 ngx_create_signal_events(ngx_cycle_t *cycle) |
2725 | 318 { |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
319 ngx_sprintf((u_char *) ngx_stop_event_name, |
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
320 "Global\\ngx_stop_%s%Z", ngx_unique); |
2725 | 321 |
322 ngx_stop_event = CreateEvent(NULL, 1, 0, ngx_stop_event_name); | |
323 if (ngx_stop_event == NULL) { | |
324 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
325 "CreateEvent(\"%s\") failed", ngx_stop_event_name); | |
326 return NGX_ERROR; | |
327 } | |
328 | |
329 | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
330 ngx_sprintf((u_char *) ngx_quit_event_name, |
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
331 "Global\\ngx_quit_%s%Z", ngx_unique); |
2725 | 332 |
333 ngx_quit_event = CreateEvent(NULL, 1, 0, ngx_quit_event_name); | |
334 if (ngx_quit_event == NULL) { | |
335 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
336 "CreateEvent(\"%s\") failed", ngx_quit_event_name); | |
337 return NGX_ERROR; | |
338 } | |
339 | |
340 | |
341 ngx_sprintf((u_char *) ngx_reopen_event_name, | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
342 "Global\\ngx_reopen_%s%Z", ngx_unique); |
2725 | 343 |
344 ngx_reopen_event = CreateEvent(NULL, 1, 0, ngx_reopen_event_name); | |
345 if (ngx_reopen_event == NULL) { | |
346 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
347 "CreateEvent(\"%s\") failed", ngx_reopen_event_name); | |
348 return NGX_ERROR; | |
349 } | |
350 | |
351 | |
352 ngx_sprintf((u_char *) ngx_reload_event_name, | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
353 "Global\\ngx_reload_%s%Z", ngx_unique); |
2725 | 354 |
355 ngx_reload_event = CreateEvent(NULL, 1, 0, ngx_reload_event_name); | |
356 if (ngx_reload_event == NULL) { | |
357 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
358 "CreateEvent(\"%s\") failed", ngx_reload_event_name); | |
359 return NGX_ERROR; | |
360 } | |
361 | |
362 return NGX_OK; | |
363 } | |
364 | |
365 | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
366 static ngx_int_t |
2725 | 367 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type) |
368 { | |
369 ngx_int_t n; | |
370 ngx_core_conf_t *ccf; | |
371 | |
372 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); | |
373 | |
374 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | |
375 | |
376 for (n = 0; n < ccf->worker_processes; n++) { | |
377 if (ngx_spawn_process(cycle, "worker", type) == NGX_INVALID_PID) { | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
378 break; |
2725 | 379 } |
380 } | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
381 |
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
382 return n; |
2627 | 383 } |
384 | |
385 | |
2725 | 386 static void |
387 ngx_reopen_worker_processes(ngx_cycle_t *cycle) | |
388 { | |
389 ngx_int_t n; | |
390 | |
391 for (n = 0; n < ngx_last_process; n++) { | |
392 | |
393 if (ngx_processes[n].handle == NULL) { | |
394 continue; | |
395 } | |
396 | |
397 if (SetEvent(ngx_processes[n].reopen) == 0) { | |
398 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
399 "SetEvent(\"%s\") failed", | |
400 ngx_processes[n].reopen_event); | |
401 } | |
402 } | |
403 } | |
404 | |
405 | |
406 static void | |
407 ngx_quit_worker_processes(ngx_cycle_t *cycle, ngx_uint_t old) | |
2627 | 408 { |
2725 | 409 ngx_int_t n; |
410 | |
411 for (n = 0; n < ngx_last_process; n++) { | |
412 | |
413 ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
2921 | 414 "process: %d %P %p e:%d j:%d", |
2725 | 415 n, |
416 ngx_processes[n].pid, | |
417 ngx_processes[n].handle, | |
418 ngx_processes[n].exiting, | |
3016
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2928
diff
changeset
|
419 ngx_processes[n].just_spawn); |
2725 | 420 |
3016
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2928
diff
changeset
|
421 if (old && ngx_processes[n].just_spawn) { |
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2928
diff
changeset
|
422 ngx_processes[n].just_spawn = 0; |
2725 | 423 continue; |
424 } | |
425 | |
426 if (ngx_processes[n].handle == NULL) { | |
427 continue; | |
428 } | |
429 | |
430 if (SetEvent(ngx_processes[n].quit) == 0) { | |
431 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
432 "SetEvent(\"%s\") failed", | |
433 ngx_processes[n].quit_event); | |
434 } | |
435 | |
436 ngx_processes[n].exiting = 1; | |
437 } | |
438 } | |
439 | |
440 | |
441 static void | |
442 ngx_terminate_worker_processes(ngx_cycle_t *cycle) | |
443 { | |
444 ngx_int_t n; | |
445 | |
446 for (n = 0; n < ngx_last_process; n++) { | |
447 | |
448 if (ngx_processes[n].handle == NULL) { | |
449 continue; | |
450 } | |
451 | |
452 if (TerminateProcess(ngx_processes[n].handle, 0) == 0) { | |
453 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
454 "TerminateProcess(\"%p\") failed", | |
455 ngx_processes[n].handle); | |
456 } | |
457 | |
458 ngx_processes[n].exiting = 1; | |
2627 | 459 |
2725 | 460 ngx_close_handle(ngx_processes[n].reopen); |
461 ngx_close_handle(ngx_processes[n].quit); | |
462 ngx_close_handle(ngx_processes[n].term); | |
463 ngx_close_handle(ngx_processes[n].handle); | |
464 } | |
465 } | |
466 | |
467 | |
468 static ngx_uint_t | |
469 ngx_reap_worker(ngx_cycle_t *cycle, HANDLE h) | |
470 { | |
471 u_long code; | |
472 ngx_int_t n; | |
473 | |
474 for (n = 0; n < ngx_last_process; n++) { | |
475 | |
476 if (ngx_processes[n].handle != h) { | |
477 continue; | |
478 } | |
479 | |
480 if (GetExitCodeProcess(h, &code) == 0) { | |
2908
234a8248812c
log GetExitCodeProcess()'s errno
Igor Sysoev <igor@sysoev.ru>
parents:
2823
diff
changeset
|
481 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, |
2725 | 482 "GetExitCodeProcess(%P) failed", |
483 ngx_processes[n].pid); | |
484 } | |
485 | |
486 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, | |
6509
7640d6c213e1
Removed redundant "u" format specifier.
Ruslan Ermilov <ru@nginx.com>
parents:
6483
diff
changeset
|
487 "%s process %P exited with code %Xl", |
2725 | 488 ngx_processes[n].name, ngx_processes[n].pid, code); |
489 | |
490 ngx_close_handle(ngx_processes[n].reopen); | |
491 ngx_close_handle(ngx_processes[n].quit); | |
492 ngx_close_handle(ngx_processes[n].term); | |
493 ngx_close_handle(h); | |
2627 | 494 |
2725 | 495 ngx_processes[n].handle = NULL; |
496 ngx_processes[n].term = NULL; | |
497 ngx_processes[n].quit = NULL; | |
498 ngx_processes[n].reopen = NULL; | |
499 | |
500 if (!ngx_processes[n].exiting && !ngx_terminate && !ngx_quit) { | |
501 | |
502 if (ngx_spawn_process(cycle, ngx_processes[n].name, n) | |
503 == NGX_INVALID_PID) | |
504 { | |
505 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
4133
59b99f217c6d
Replaced "can not" with "cannot" and "could not" in a bunch of places.
Ruslan Ermilov <ru@nginx.com>
parents:
3751
diff
changeset
|
506 "could not respawn %s", ngx_processes[n].name); |
2725 | 507 |
508 if (n == ngx_last_process - 1) { | |
509 ngx_last_process--; | |
510 } | |
511 } | |
512 } | |
2627 | 513 |
2725 | 514 goto found; |
515 } | |
516 | |
517 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unknown process handle %p", h); | |
518 | |
519 found: | |
520 | |
521 for (n = 0; n < ngx_last_process; n++) { | |
522 | |
523 ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
2921 | 524 "process: %d %P %p e:%d j:%d", |
2725 | 525 n, |
526 ngx_processes[n].pid, | |
527 ngx_processes[n].handle, | |
528 ngx_processes[n].exiting, | |
3016
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2928
diff
changeset
|
529 ngx_processes[n].just_spawn); |
2725 | 530 |
531 if (ngx_processes[n].handle) { | |
532 return 1; | |
533 } | |
2627 | 534 } |
535 | |
536 return 0; | |
537 } | |
538 | |
539 | |
540 static void | |
2725 | 541 ngx_master_process_exit(ngx_cycle_t *cycle) |
542 { | |
543 ngx_uint_t i; | |
544 | |
545 ngx_delete_pidfile(cycle); | |
546 | |
547 ngx_close_handle(ngx_cache_manager_mutex); | |
548 ngx_close_handle(ngx_stop_event); | |
549 ngx_close_handle(ngx_quit_event); | |
550 ngx_close_handle(ngx_reopen_event); | |
551 ngx_close_handle(ngx_reload_event); | |
552 ngx_close_handle(ngx_master_process_event); | |
553 | |
554 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit"); | |
555 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
556 for (i = 0; cycle->modules[i]; i++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
557 if (cycle->modules[i]->exit_master) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
558 cycle->modules[i]->exit_master(cycle); |
2725 | 559 } |
560 } | |
561 | |
562 ngx_destroy_pool(cycle->pool); | |
563 | |
564 exit(0); | |
565 } | |
566 | |
567 | |
568 static void | |
569 ngx_worker_process_cycle(ngx_cycle_t *cycle, char *mevn) | |
2627 | 570 { |
2725 | 571 char wtevn[NGX_PROCESS_SYNC_NAME]; |
572 char wqevn[NGX_PROCESS_SYNC_NAME]; | |
573 char wroevn[NGX_PROCESS_SYNC_NAME]; | |
574 HANDLE mev, events[3]; | |
575 u_long nev, ev; | |
576 ngx_err_t err; | |
3352
5c43621c580a
a cache manager thread handle was overwritten by a cache loader thread handle,
Igor Sysoev <igor@sysoev.ru>
parents:
3035
diff
changeset
|
577 ngx_tid_t wtid, cmtid, cltid; |
2725 | 578 ngx_log_t *log; |
579 | |
580 log = cycle->log; | |
581 | |
582 ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "worker started"); | |
583 | |
6482
2b7dacb381ed
Fixed ngx_pid_t formatting in ngx_sprintf() and logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6379
diff
changeset
|
584 ngx_sprintf((u_char *) wtevn, "ngx_worker_term_%P%Z", ngx_pid); |
2725 | 585 events[0] = CreateEvent(NULL, 1, 0, wtevn); |
586 if (events[0] == NULL) { | |
587 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
588 "CreateEvent(\"%s\") failed", wtevn); | |
589 goto failed; | |
590 } | |
591 | |
6482
2b7dacb381ed
Fixed ngx_pid_t formatting in ngx_sprintf() and logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6379
diff
changeset
|
592 ngx_sprintf((u_char *) wqevn, "ngx_worker_quit_%P%Z", ngx_pid); |
2725 | 593 events[1] = CreateEvent(NULL, 1, 0, wqevn); |
594 if (events[1] == NULL) { | |
595 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
596 "CreateEvent(\"%s\") failed", wqevn); | |
597 goto failed; | |
598 } | |
599 | |
6482
2b7dacb381ed
Fixed ngx_pid_t formatting in ngx_sprintf() and logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6379
diff
changeset
|
600 ngx_sprintf((u_char *) wroevn, "ngx_worker_reopen_%P%Z", ngx_pid); |
2725 | 601 events[2] = CreateEvent(NULL, 1, 0, wroevn); |
602 if (events[2] == NULL) { | |
603 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
604 "CreateEvent(\"%s\") failed", wroevn); | |
605 goto failed; | |
606 } | |
607 | |
608 mev = OpenEvent(EVENT_MODIFY_STATE, 0, mevn); | |
609 if (mev == NULL) { | |
610 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
611 "OpenEvent(\"%s\") failed", mevn); | |
612 goto failed; | |
613 } | |
614 | |
615 if (SetEvent(mev) == 0) { | |
616 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
617 "SetEvent(\"%s\") failed", mevn); | |
618 goto failed; | |
619 } | |
620 | |
621 | |
622 ngx_sprintf((u_char *) ngx_cache_manager_mutex_name, | |
623 "ngx_cache_manager_mutex_%s%Z", ngx_unique); | |
624 | |
625 ngx_cache_manager_mutex = OpenMutex(SYNCHRONIZE, 0, | |
626 ngx_cache_manager_mutex_name); | |
627 if (ngx_cache_manager_mutex == NULL) { | |
628 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
629 "OpenMutex(\"%s\") failed", ngx_cache_manager_mutex_name); | |
630 goto failed; | |
631 } | |
632 | |
633 ngx_cache_manager_event = CreateEvent(NULL, 1, 0, NULL); | |
634 if (ngx_cache_manager_event == NULL) { | |
635 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
636 "CreateEvent(\"ngx_cache_manager_event\") failed"); | |
637 goto failed; | |
638 } | |
639 | |
640 | |
641 if (ngx_create_thread(&wtid, ngx_worker_thread, NULL, log) != 0) { | |
642 goto failed; | |
643 } | |
644 | |
645 if (ngx_create_thread(&cmtid, ngx_cache_manager_thread, NULL, log) != 0) { | |
646 goto failed; | |
647 } | |
648 | |
3352
5c43621c580a
a cache manager thread handle was overwritten by a cache loader thread handle,
Igor Sysoev <igor@sysoev.ru>
parents:
3035
diff
changeset
|
649 if (ngx_create_thread(&cltid, ngx_cache_loader_thread, NULL, log) != 0) { |
3022 | 650 goto failed; |
651 } | |
652 | |
2725 | 653 for ( ;; ) { |
654 ev = WaitForMultipleObjects(3, events, 0, INFINITE); | |
655 | |
656 err = ngx_errno; | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
657 ngx_time_update(); |
461 | 658 |
2725 | 659 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, |
660 "worker WaitForMultipleObjects: %ul", ev); | |
661 | |
662 if (ev == WAIT_OBJECT_0) { | |
663 ngx_terminate = 1; | |
664 ngx_log_error(NGX_LOG_NOTICE, log, 0, "exiting"); | |
665 | |
666 if (ResetEvent(events[0]) == 0) { | |
667 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
668 "ResetEvent(\"%s\") failed", wtevn); | |
669 } | |
670 | |
671 break; | |
672 } | |
673 | |
674 if (ev == WAIT_OBJECT_0 + 1) { | |
675 ngx_quit = 1; | |
676 ngx_log_error(NGX_LOG_NOTICE, log, 0, "gracefully shutting down"); | |
677 break; | |
678 } | |
679 | |
680 if (ev == WAIT_OBJECT_0 + 2) { | |
681 ngx_reopen = 1; | |
682 ngx_log_error(NGX_LOG_NOTICE, log, 0, "reopening logs"); | |
683 | |
684 if (ResetEvent(events[2]) == 0) { | |
685 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
686 "ResetEvent(\"%s\") failed", wroevn); | |
687 } | |
688 | |
689 continue; | |
690 } | |
691 | |
692 if (ev == WAIT_FAILED) { | |
693 ngx_log_error(NGX_LOG_ALERT, log, err, | |
694 "WaitForMultipleObjects() failed"); | |
695 | |
696 goto failed; | |
697 } | |
698 } | |
699 | |
700 /* wait threads */ | |
461 | 701 |
2725 | 702 if (SetEvent(ngx_cache_manager_event) == 0) { |
703 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
704 "SetEvent(\"ngx_cache_manager_event\") failed"); | |
705 } | |
706 | |
707 events[1] = wtid; | |
708 events[2] = cmtid; | |
709 | |
710 nev = 3; | |
711 | |
712 for ( ;; ) { | |
713 ev = WaitForMultipleObjects(nev, events, 0, INFINITE); | |
714 | |
715 err = ngx_errno; | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
716 ngx_time_update(); |
2725 | 717 |
718 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, | |
719 "worker exit WaitForMultipleObjects: %ul", ev); | |
720 | |
721 if (ev == WAIT_OBJECT_0) { | |
722 break; | |
723 } | |
724 | |
725 if (ev == WAIT_OBJECT_0 + 1) { | |
726 if (nev == 2) { | |
727 break; | |
728 } | |
729 | |
730 events[1] = events[2]; | |
731 nev = 2; | |
732 continue; | |
733 } | |
734 | |
735 if (ev == WAIT_OBJECT_0 + 2) { | |
736 nev = 2; | |
737 continue; | |
738 } | |
739 | |
740 if (ev == WAIT_FAILED) { | |
741 ngx_log_error(NGX_LOG_ALERT, log, err, | |
742 "WaitForMultipleObjects() failed"); | |
743 break; | |
744 } | |
461 | 745 } |
746 | |
2725 | 747 ngx_close_handle(ngx_cache_manager_event); |
748 ngx_close_handle(events[0]); | |
749 ngx_close_handle(events[1]); | |
750 ngx_close_handle(events[2]); | |
751 ngx_close_handle(mev); | |
752 | |
753 ngx_worker_process_exit(cycle); | |
754 | |
755 failed: | |
756 | |
757 exit(2); | |
758 } | |
759 | |
760 | |
761 static ngx_thread_value_t __stdcall | |
762 ngx_worker_thread(void *data) | |
763 { | |
6220
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
764 ngx_int_t n; |
6651
7d4e33092e2a
Always seed PRNG with PID, seconds, and milliseconds.
Ruslan Ermilov <ru@nginx.com>
parents:
6649
diff
changeset
|
765 ngx_time_t *tp; |
6220
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
766 ngx_cycle_t *cycle; |
2725 | 767 |
6651
7d4e33092e2a
Always seed PRNG with PID, seconds, and milliseconds.
Ruslan Ermilov <ru@nginx.com>
parents:
6649
diff
changeset
|
768 tp = ngx_timeofday(); |
7d4e33092e2a
Always seed PRNG with PID, seconds, and milliseconds.
Ruslan Ermilov <ru@nginx.com>
parents:
6649
diff
changeset
|
769 srand((ngx_pid << 16) ^ (unsigned) tp->sec ^ tp->msec); |
6649
09c918460cc6
Win32: added per-thread random seeding.
Ruslan Ermilov <ru@nginx.com>
parents:
6509
diff
changeset
|
770 |
2725 | 771 cycle = (ngx_cycle_t *) ngx_cycle; |
772 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
773 for (n = 0; cycle->modules[n]; n++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
774 if (cycle->modules[n]->init_process) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
775 if (cycle->modules[n]->init_process(cycle) == NGX_ERROR) { |
2725 | 776 /* fatal */ |
777 exit(2); | |
778 } | |
779 } | |
780 } | |
781 | |
782 while (!ngx_quit) { | |
783 | |
784 if (ngx_exiting) { | |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5633
diff
changeset
|
785 ngx_event_cancel_timers(); |
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5633
diff
changeset
|
786 |
2725 | 787 if (ngx_event_timer_rbtree.root |
788 == ngx_event_timer_rbtree.sentinel) | |
789 { | |
790 break; | |
791 } | |
792 } | |
793 | |
794 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "worker cycle"); | |
795 | |
796 ngx_process_events_and_timers(cycle); | |
797 | |
798 if (ngx_terminate) { | |
799 return 0; | |
800 } | |
801 | |
802 if (ngx_quit) { | |
803 ngx_quit = 0; | |
804 | |
805 if (!ngx_exiting) { | |
6220
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
806 ngx_exiting = 1; |
2725 | 807 ngx_close_listening_sockets(cycle); |
6220
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
808 ngx_close_idle_connections(cycle); |
2725 | 809 } |
810 } | |
811 | |
812 if (ngx_reopen) { | |
813 ngx_reopen = 0; | |
814 ngx_reopen_files(cycle, -1); | |
815 } | |
816 } | |
817 | |
818 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); | |
819 | |
820 return 0; | |
821 } | |
822 | |
823 | |
824 static void | |
825 ngx_worker_process_exit(ngx_cycle_t *cycle) | |
826 { | |
827 ngx_uint_t i; | |
828 ngx_connection_t *c; | |
829 | |
830 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit"); | |
831 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
832 for (i = 0; cycle->modules[i]; i++) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
833 if (cycle->modules[i]->exit_process) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
834 cycle->modules[i]->exit_process(cycle); |
2725 | 835 } |
836 } | |
837 | |
838 if (ngx_exiting) { | |
839 c = cycle->connections; | |
840 for (i = 0; i < cycle->connection_n; i++) { | |
5360
3d2d3e1cf427
Win32: MinGW GCC compatibility.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4870
diff
changeset
|
841 if (c[i].fd != (ngx_socket_t) -1 |
2725 | 842 && c[i].read |
843 && !c[i].read->accept | |
844 && !c[i].read->channel | |
845 && !c[i].read->resolver) | |
846 { | |
847 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
5601
e45fa57ef725
Added connection serial number in logging of left open sockets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5452
diff
changeset
|
848 "*%uA open socket #%d left in connection %ui", |
e45fa57ef725
Added connection serial number in logging of left open sockets.
Sergey Kandaurov <pluknet@nginx.com>
parents:
5452
diff
changeset
|
849 c[i].number, c[i].fd, i); |
2725 | 850 } |
851 } | |
461 | 852 } |
853 | |
2725 | 854 ngx_destroy_pool(cycle->pool); |
855 | |
856 exit(0); | |
857 } | |
858 | |
859 | |
860 static ngx_thread_value_t __stdcall | |
861 ngx_cache_manager_thread(void *data) | |
862 { | |
863 u_long ev; | |
864 HANDLE events[2]; | |
865 ngx_err_t err; | |
866 ngx_cycle_t *cycle; | |
867 | |
868 cycle = (ngx_cycle_t *) ngx_cycle; | |
869 | |
870 events[0] = ngx_cache_manager_event; | |
871 events[1] = ngx_cache_manager_mutex; | |
872 | |
873 for ( ;; ) { | |
874 ev = WaitForMultipleObjects(2, events, 0, INFINITE); | |
875 | |
876 err = ngx_errno; | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
877 ngx_time_update(); |
2725 | 878 |
879 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
880 "cache manager WaitForMultipleObjects: %ul", ev); | |
881 | |
882 if (ev == WAIT_FAILED) { | |
883 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, | |
884 "WaitForMultipleObjects() failed"); | |
885 } | |
886 | |
887 /* | |
888 * ev == WAIT_OBJECT_0 | |
889 * ev == WAIT_OBJECT_0 + 1 | |
890 * ev == WAIT_ABANDONED_0 + 1 | |
891 */ | |
892 | |
5633
b74f1106f920
Win32: fixed cpu hog by cache manager on exit (ticket #514).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5601
diff
changeset
|
893 if (ngx_terminate || ngx_quit || ngx_exiting) { |
2725 | 894 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); |
895 return 0; | |
896 } | |
897 | |
3021 | 898 break; |
2725 | 899 } |
900 | |
901 for ( ;; ) { | |
902 | |
5633
b74f1106f920
Win32: fixed cpu hog by cache manager on exit (ticket #514).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5601
diff
changeset
|
903 if (ngx_terminate || ngx_quit || ngx_exiting) { |
2725 | 904 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); |
905 break; | |
906 } | |
907 | |
908 ngx_cache_manager_process_handler(); | |
909 } | |
910 | |
911 if (ReleaseMutex(ngx_cache_manager_mutex) == 0) { | |
912 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
913 "ReleaseMutex() failed"); | |
914 } | |
915 | |
916 return 0; | |
917 } | |
918 | |
919 | |
920 static void | |
921 ngx_cache_manager_process_handler(void) | |
922 { | |
923 u_long ev; | |
924 ngx_uint_t i; | |
6727
ca709bca4b77
Cache: cache manager limits.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6651
diff
changeset
|
925 ngx_msec_t next, n; |
2725 | 926 ngx_path_t **path; |
927 | |
6727
ca709bca4b77
Cache: cache manager limits.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6651
diff
changeset
|
928 next = 60 * 60 * 1000; |
2725 | 929 |
4870
8a9b7b4e9f2d
Correct plural form for "path" in the whole source base.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
930 path = ngx_cycle->paths.elts; |
8a9b7b4e9f2d
Correct plural form for "path" in the whole source base.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
931 for (i = 0; i < ngx_cycle->paths.nelts; i++) { |
2725 | 932 |
933 if (path[i]->manager) { | |
934 n = path[i]->manager(path[i]->data); | |
935 | |
936 next = (n <= next) ? n : next; | |
937 | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
938 ngx_time_update(); |
2725 | 939 } |
940 } | |
941 | |
942 if (next == 0) { | |
943 next = 1; | |
944 } | |
945 | |
6727
ca709bca4b77
Cache: cache manager limits.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6651
diff
changeset
|
946 ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next); |
2725 | 947 |
948 if (ev != WAIT_TIMEOUT) { | |
949 | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
950 ngx_time_update(); |
2725 | 951 |
952 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, | |
953 "cache manager WaitForSingleObject: %ul", ev); | |
954 } | |
955 } | |
956 | |
957 | |
3022 | 958 static ngx_thread_value_t __stdcall |
959 ngx_cache_loader_thread(void *data) | |
960 { | |
961 ngx_uint_t i; | |
962 ngx_path_t **path; | |
963 ngx_cycle_t *cycle; | |
964 | |
965 ngx_msleep(60000); | |
966 | |
967 cycle = (ngx_cycle_t *) ngx_cycle; | |
968 | |
4870
8a9b7b4e9f2d
Correct plural form for "path" in the whole source base.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
969 path = cycle->paths.elts; |
8a9b7b4e9f2d
Correct plural form for "path" in the whole source base.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
970 for (i = 0; i < cycle->paths.nelts; i++) { |
3022 | 971 |
5633
b74f1106f920
Win32: fixed cpu hog by cache manager on exit (ticket #514).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5601
diff
changeset
|
972 if (ngx_terminate || ngx_quit || ngx_exiting) { |
3022 | 973 break; |
974 } | |
975 | |
976 if (path[i]->loader) { | |
977 path[i]->loader(path[i]->data); | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
978 ngx_time_update(); |
3022 | 979 } |
980 } | |
981 | |
982 return 0; | |
983 } | |
984 | |
985 | |
2725 | 986 void |
987 ngx_single_process_cycle(ngx_cycle_t *cycle) | |
988 { | |
989 ngx_tid_t tid; | |
990 | |
991 ngx_console_init(cycle); | |
992 | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
993 if (ngx_create_signal_events(cycle) != NGX_OK) { |
461 | 994 exit(2); |
995 } | |
996 | |
2725 | 997 if (ngx_create_thread(&tid, ngx_worker_thread, NULL, cycle->log) != 0) { |
461 | 998 /* fatal */ |
999 exit(2); | |
1000 } | |
1001 | |
2725 | 1002 /* STUB */ |
1003 WaitForSingleObject(ngx_stop_event, INFINITE); | |
461 | 1004 } |
1005 | |
1006 | |
2725 | 1007 ngx_int_t |
6483
3a50ccd94333
Fixed ngx_os_signal_process() prototype.
Ruslan Ermilov <ru@nginx.com>
parents:
6482
diff
changeset
|
1008 ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid) |
461 | 1009 { |
2738
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1010 HANDLE ev; |
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1011 ngx_int_t rc; |
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1012 char evn[NGX_PROCESS_SYNC_NAME]; |
461 | 1013 |
6483
3a50ccd94333
Fixed ngx_os_signal_process() prototype.
Ruslan Ermilov <ru@nginx.com>
parents:
6482
diff
changeset
|
1014 ngx_sprintf((u_char *) evn, "Global\\ngx_%s_%P%Z", sig, pid); |
2725 | 1015 |
1016 ev = OpenEvent(EVENT_MODIFY_STATE, 0, evn); | |
1017 if (ev == NULL) { | |
1018 ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, | |
1019 "OpenEvent(\"%s\") failed", evn); | |
2738
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1020 return 1; |
2725 | 1021 } |
461 | 1022 |
2725 | 1023 if (SetEvent(ev) == 0) { |
1024 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
1025 "SetEvent(\"%s\") failed", evn); | |
2738
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1026 rc = 1; |
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1027 |
2725 | 1028 } else { |
1029 rc = 0; | |
1030 } | |
1031 | |
1032 ngx_close_handle(ev); | |
1033 | |
1034 return rc; | |
1035 } | |
461 | 1036 |
1037 | |
2725 | 1038 void |
1039 ngx_close_handle(HANDLE h) | |
1040 { | |
1041 if (CloseHandle(h) == 0) { | |
1042 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, | |
1043 "CloseHandle(%p) failed", h); | |
461 | 1044 } |
1045 } |