Mercurial > hg > nginx
annotate src/os/win32/ngx_process_cycle.c @ 6649:09c918460cc6
Win32: added per-thread random seeding.
The change in b91bcba29351 was not enough to fix random() seeding.
On Windows, the srand() seeds the PRNG only in the current thread,
and worse, is not inherited from the calling thread. Due to this,
worker threads were not properly seeded.
Reported by Marc Bevand.
author | Ruslan Ermilov <ru@nginx.com> |
---|---|
date | Thu, 04 Aug 2016 01:15:41 +0300 |
parents | 7640d6c213e1 |
children | 7d4e33092e2a |
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; |
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
765 ngx_cycle_t *cycle; |
2725 | 766 |
6649
09c918460cc6
Win32: added per-thread random seeding.
Ruslan Ermilov <ru@nginx.com>
parents:
6509
diff
changeset
|
767 srand((ngx_pid << 16) ^ (unsigned) ngx_time()); |
09c918460cc6
Win32: added per-thread random seeding.
Ruslan Ermilov <ru@nginx.com>
parents:
6509
diff
changeset
|
768 |
2725 | 769 cycle = (ngx_cycle_t *) ngx_cycle; |
770 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
771 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
|
772 if (cycle->modules[n]->init_process) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
773 if (cycle->modules[n]->init_process(cycle) == NGX_ERROR) { |
2725 | 774 /* fatal */ |
775 exit(2); | |
776 } | |
777 } | |
778 } | |
779 | |
780 while (!ngx_quit) { | |
781 | |
782 if (ngx_exiting) { | |
5896
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5633
diff
changeset
|
783 ngx_event_cancel_timers(); |
3efdd7788bb0
Events: introduced cancelable timers.
Valentin Bartenev <vbart@nginx.com>
parents:
5633
diff
changeset
|
784 |
2725 | 785 if (ngx_event_timer_rbtree.root |
786 == ngx_event_timer_rbtree.sentinel) | |
787 { | |
788 break; | |
789 } | |
790 } | |
791 | |
792 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "worker cycle"); | |
793 | |
794 ngx_process_events_and_timers(cycle); | |
795 | |
796 if (ngx_terminate) { | |
797 return 0; | |
798 } | |
799 | |
800 if (ngx_quit) { | |
801 ngx_quit = 0; | |
802 | |
803 if (!ngx_exiting) { | |
6220
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
804 ngx_exiting = 1; |
2725 | 805 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
|
806 ngx_close_idle_connections(cycle); |
2725 | 807 } |
808 } | |
809 | |
810 if (ngx_reopen) { | |
811 ngx_reopen = 0; | |
812 ngx_reopen_files(cycle, -1); | |
813 } | |
814 } | |
815 | |
816 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); | |
817 | |
818 return 0; | |
819 } | |
820 | |
821 | |
822 static void | |
823 ngx_worker_process_exit(ngx_cycle_t *cycle) | |
824 { | |
825 ngx_uint_t i; | |
826 ngx_connection_t *c; | |
827 | |
828 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit"); | |
829 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
830 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
|
831 if (cycle->modules[i]->exit_process) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
832 cycle->modules[i]->exit_process(cycle); |
2725 | 833 } |
834 } | |
835 | |
836 if (ngx_exiting) { | |
837 c = cycle->connections; | |
838 for (i = 0; i < cycle->connection_n; i++) { | |
5360
3d2d3e1cf427
Win32: MinGW GCC compatibility.
Maxim Dounin <mdounin@mdounin.ru>
parents:
4870
diff
changeset
|
839 if (c[i].fd != (ngx_socket_t) -1 |
2725 | 840 && c[i].read |
841 && !c[i].read->accept | |
842 && !c[i].read->channel | |
843 && !c[i].read->resolver) | |
844 { | |
845 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
|
846 "*%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
|
847 c[i].number, c[i].fd, i); |
2725 | 848 } |
849 } | |
461 | 850 } |
851 | |
2725 | 852 ngx_destroy_pool(cycle->pool); |
853 | |
854 exit(0); | |
855 } | |
856 | |
857 | |
858 static ngx_thread_value_t __stdcall | |
859 ngx_cache_manager_thread(void *data) | |
860 { | |
861 u_long ev; | |
862 HANDLE events[2]; | |
863 ngx_err_t err; | |
864 ngx_cycle_t *cycle; | |
865 | |
866 cycle = (ngx_cycle_t *) ngx_cycle; | |
867 | |
868 events[0] = ngx_cache_manager_event; | |
869 events[1] = ngx_cache_manager_mutex; | |
870 | |
871 for ( ;; ) { | |
872 ev = WaitForMultipleObjects(2, events, 0, INFINITE); | |
873 | |
874 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
|
875 ngx_time_update(); |
2725 | 876 |
877 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
878 "cache manager WaitForMultipleObjects: %ul", ev); | |
879 | |
880 if (ev == WAIT_FAILED) { | |
881 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, | |
882 "WaitForMultipleObjects() failed"); | |
883 } | |
884 | |
885 /* | |
886 * ev == WAIT_OBJECT_0 | |
887 * ev == WAIT_OBJECT_0 + 1 | |
888 * ev == WAIT_ABANDONED_0 + 1 | |
889 */ | |
890 | |
5633
b74f1106f920
Win32: fixed cpu hog by cache manager on exit (ticket #514).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5601
diff
changeset
|
891 if (ngx_terminate || ngx_quit || ngx_exiting) { |
2725 | 892 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); |
893 return 0; | |
894 } | |
895 | |
3021 | 896 break; |
2725 | 897 } |
898 | |
899 for ( ;; ) { | |
900 | |
5633
b74f1106f920
Win32: fixed cpu hog by cache manager on exit (ticket #514).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5601
diff
changeset
|
901 if (ngx_terminate || ngx_quit || ngx_exiting) { |
2725 | 902 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exiting"); |
903 break; | |
904 } | |
905 | |
906 ngx_cache_manager_process_handler(); | |
907 } | |
908 | |
909 if (ReleaseMutex(ngx_cache_manager_mutex) == 0) { | |
910 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
911 "ReleaseMutex() failed"); | |
912 } | |
913 | |
914 return 0; | |
915 } | |
916 | |
917 | |
918 static void | |
919 ngx_cache_manager_process_handler(void) | |
920 { | |
921 u_long ev; | |
922 time_t next, n; | |
923 ngx_uint_t i; | |
924 ngx_path_t **path; | |
925 | |
926 next = 60 * 60; | |
927 | |
4870
8a9b7b4e9f2d
Correct plural form for "path" in the whole source base.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
928 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
|
929 for (i = 0; i < ngx_cycle->paths.nelts; i++) { |
2725 | 930 |
931 if (path[i]->manager) { | |
932 n = path[i]->manager(path[i]->data); | |
933 | |
934 next = (n <= next) ? n : next; | |
935 | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
936 ngx_time_update(); |
2725 | 937 } |
938 } | |
939 | |
940 if (next == 0) { | |
941 next = 1; | |
942 } | |
943 | |
944 ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next * 1000); | |
945 | |
946 if (ev != WAIT_TIMEOUT) { | |
947 | |
3475
ab353d7dc182
*) introduce ngx_time_sigsafe_update() to update the error log time only
Igor Sysoev <igor@sysoev.ru>
parents:
3474
diff
changeset
|
948 ngx_time_update(); |
2725 | 949 |
950 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0, | |
951 "cache manager WaitForSingleObject: %ul", ev); | |
952 } | |
953 } | |
954 | |
955 | |
3022 | 956 static ngx_thread_value_t __stdcall |
957 ngx_cache_loader_thread(void *data) | |
958 { | |
959 ngx_uint_t i; | |
960 ngx_path_t **path; | |
961 ngx_cycle_t *cycle; | |
962 | |
963 ngx_msleep(60000); | |
964 | |
965 cycle = (ngx_cycle_t *) ngx_cycle; | |
966 | |
4870
8a9b7b4e9f2d
Correct plural form for "path" in the whole source base.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
967 path = cycle->paths.elts; |
8a9b7b4e9f2d
Correct plural form for "path" in the whole source base.
Andrey Belov <defan@nginx.com>
parents:
4412
diff
changeset
|
968 for (i = 0; i < cycle->paths.nelts; i++) { |
3022 | 969 |
5633
b74f1106f920
Win32: fixed cpu hog by cache manager on exit (ticket #514).
Maxim Dounin <mdounin@mdounin.ru>
parents:
5601
diff
changeset
|
970 if (ngx_terminate || ngx_quit || ngx_exiting) { |
3022 | 971 break; |
972 } | |
973 | |
974 if (path[i]->loader) { | |
975 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
|
976 ngx_time_update(); |
3022 | 977 } |
978 } | |
979 | |
980 return 0; | |
981 } | |
982 | |
983 | |
2725 | 984 void |
985 ngx_single_process_cycle(ngx_cycle_t *cycle) | |
986 { | |
987 ngx_tid_t tid; | |
988 | |
989 ngx_console_init(cycle); | |
990 | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
991 if (ngx_create_signal_events(cycle) != NGX_OK) { |
461 | 992 exit(2); |
993 } | |
994 | |
2725 | 995 if (ngx_create_thread(&tid, ngx_worker_thread, NULL, cycle->log) != 0) { |
461 | 996 /* fatal */ |
997 exit(2); | |
998 } | |
999 | |
2725 | 1000 /* STUB */ |
1001 WaitForSingleObject(ngx_stop_event, INFINITE); | |
461 | 1002 } |
1003 | |
1004 | |
2725 | 1005 ngx_int_t |
6483
3a50ccd94333
Fixed ngx_os_signal_process() prototype.
Ruslan Ermilov <ru@nginx.com>
parents:
6482
diff
changeset
|
1006 ngx_os_signal_process(ngx_cycle_t *cycle, char *sig, ngx_pid_t pid) |
461 | 1007 { |
2738
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1008 HANDLE ev; |
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1009 ngx_int_t rc; |
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1010 char evn[NGX_PROCESS_SYNC_NAME]; |
461 | 1011 |
6483
3a50ccd94333
Fixed ngx_os_signal_process() prototype.
Ruslan Ermilov <ru@nginx.com>
parents:
6482
diff
changeset
|
1012 ngx_sprintf((u_char *) evn, "Global\\ngx_%s_%P%Z", sig, pid); |
2725 | 1013 |
1014 ev = OpenEvent(EVENT_MODIFY_STATE, 0, evn); | |
1015 if (ev == NULL) { | |
1016 ngx_log_error(NGX_LOG_ERR, cycle->log, ngx_errno, | |
1017 "OpenEvent(\"%s\") failed", evn); | |
2738
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1018 return 1; |
2725 | 1019 } |
461 | 1020 |
2725 | 1021 if (SetEvent(ev) == 0) { |
1022 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
1023 "SetEvent(\"%s\") failed", evn); | |
2738
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1024 rc = 1; |
ae81441e23f4
implement "-s signal" option for Unix
Igor Sysoev <igor@sysoev.ru>
parents:
2725
diff
changeset
|
1025 |
2725 | 1026 } else { |
1027 rc = 0; | |
1028 } | |
1029 | |
1030 ngx_close_handle(ev); | |
1031 | |
1032 return rc; | |
1033 } | |
461 | 1034 |
1035 | |
2725 | 1036 void |
1037 ngx_close_handle(HANDLE h) | |
1038 { | |
1039 if (CloseHandle(h) == 0) { | |
1040 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, ngx_errno, | |
1041 "CloseHandle(%p) failed", h); | |
461 | 1042 } |
1043 } |