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