Mercurial > hg > nginx
annotate src/os/win32/ngx_process_cycle.c @ 8971:1e2f4e9c8195 quic
QUIC: reworked migration handling.
The quic connection now holds active, backup and probe paths instead
of sockets. The number of migration paths is now limited and cannot
be inflated by a bad client or an attacker.
The client id is now associated with path rather than socket. This allows
to simplify processing of output and connection ids handling.
New migration abandons any previously started migrations. This allows to
free consumed client ids and request new for use in future migrations and
make progress in case when connection id limit is hit during migration.
A path now can be revalidated without losing its state.
The patch also fixes various issues with NAT rebinding case handling:
- paths are now validated (previously, there was no validation
and paths were left in limited state)
- attempt to reuse id on different path is now again verified
(this was broken in 40445fc7c403)
- former path is now validated in case of apparent migration
author | Vladimir Homutov <vl@nginx.com> |
---|---|
date | Wed, 19 Jan 2022 22:39:24 +0300 |
parents | 8b84d60ef13d |
children | b809f53d3f5b |
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; |
7162
8b84d60ef13d
Fixed "changing binary" when reaper is not init.
Ruslan Ermilov <ru@nginx.com>
parents:
6930
diff
changeset
|
34 ngx_pid_t ngx_parent; |
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_sprintf((u_char *) ngx_master_process_event_name, | |
74 "ngx_master_%s%Z", ngx_unique); | |
75 | |
76 if (ngx_process == NGX_PROCESS_WORKER) { | |
77 ngx_worker_process_cycle(cycle, ngx_master_process_event_name); | |
78 return; | |
79 } | |
80 | |
81 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "master started"); | |
82 | |
83 ngx_console_init(cycle); | |
84 | |
85 SetEnvironmentVariable("ngx_unique", ngx_unique); | |
86 | |
87 ngx_master_process_event = CreateEvent(NULL, 1, 0, | |
88 ngx_master_process_event_name); | |
89 if (ngx_master_process_event == NULL) { | |
90 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
91 "CreateEvent(\"%s\") failed", | |
92 ngx_master_process_event_name); | |
93 exit(2); | |
94 } | |
95 | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
96 if (ngx_create_signal_events(cycle) != NGX_OK) { |
2725 | 97 exit(2); |
98 } | |
99 | |
100 ngx_sprintf((u_char *) ngx_cache_manager_mutex_name, | |
101 "ngx_cache_manager_mutex_%s%Z", ngx_unique); | |
102 | |
103 ngx_cache_manager_mutex = CreateMutex(NULL, 0, | |
104 ngx_cache_manager_mutex_name); | |
105 if (ngx_cache_manager_mutex == NULL) { | |
106 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
107 "CreateMutex(\"%s\") failed", ngx_cache_manager_mutex_name); | |
108 exit(2); | |
109 } | |
110 | |
111 | |
112 events[0] = ngx_stop_event; | |
113 events[1] = ngx_quit_event; | |
114 events[2] = ngx_reopen_event; | |
115 events[3] = ngx_reload_event; | |
116 | |
117 ngx_close_listening_sockets(cycle); | |
118 | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
119 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
|
120 exit(2); |
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
121 } |
2725 | 122 |
123 timer = 0; | |
124 timeout = INFINITE; | |
125 | |
126 for ( ;; ) { | |
127 | |
128 nev = 4; | |
129 for (n = 0; n < ngx_last_process; n++) { | |
130 if (ngx_processes[n].handle) { | |
131 events[nev++] = ngx_processes[n].handle; | |
132 } | |
133 } | |
134 | |
135 if (timer) { | |
136 timeout = timer > ngx_current_msec ? timer - ngx_current_msec : 0; | |
137 } | |
138 | |
139 ev = WaitForMultipleObjects(nev, events, 0, timeout); | |
140 | |
141 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
|
142 ngx_time_update(); |
2725 | 143 |
144 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
145 "master WaitForMultipleObjects: %ul", ev); | |
146 | |
147 if (ev == WAIT_OBJECT_0) { | |
148 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
|
149 |
2725 | 150 if (ResetEvent(ngx_stop_event) == 0) { |
151 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
152 "ResetEvent(\"%s\") failed", ngx_stop_event_name); | |
153 } | |
154 | |
155 if (timer == 0) { | |
156 timer = ngx_current_msec + 5000; | |
157 } | |
158 | |
159 ngx_terminate = 1; | |
160 ngx_quit_worker_processes(cycle, 0); | |
161 | |
162 continue; | |
163 } | |
164 | |
165 if (ev == WAIT_OBJECT_0 + 1) { | |
166 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "shutting down"); | |
167 | |
168 if (ResetEvent(ngx_quit_event) == 0) { | |
169 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
170 "ResetEvent(\"%s\") failed", ngx_quit_event_name); | |
171 } | |
172 | |
173 ngx_quit = 1; | |
174 ngx_quit_worker_processes(cycle, 0); | |
175 | |
176 continue; | |
177 } | |
178 | |
179 if (ev == WAIT_OBJECT_0 + 2) { | |
180 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reopening logs"); | |
181 | |
182 if (ResetEvent(ngx_reopen_event) == 0) { | |
183 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
184 "ResetEvent(\"%s\") failed", | |
185 ngx_reopen_event_name); | |
186 } | |
187 | |
188 ngx_reopen_files(cycle, -1); | |
189 ngx_reopen_worker_processes(cycle); | |
190 | |
191 continue; | |
192 } | |
193 | |
194 if (ev == WAIT_OBJECT_0 + 3) { | |
195 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "reconfiguring"); | |
196 | |
197 if (ResetEvent(ngx_reload_event) == 0) { | |
198 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
199 "ResetEvent(\"%s\") failed", | |
200 ngx_reload_event_name); | |
201 } | |
202 | |
2823 | 203 cycle = ngx_init_cycle(cycle); |
204 if (cycle == NULL) { | |
205 cycle = (ngx_cycle_t *) ngx_cycle; | |
206 continue; | |
207 } | |
208 | |
209 ngx_cycle = cycle; | |
210 | |
2928 | 211 ngx_close_listening_sockets(cycle); |
212 | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
213 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
|
214 ngx_quit_worker_processes(cycle, 1); |
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
215 } |
2725 | 216 |
217 continue; | |
218 } | |
219 | |
220 if (ev > WAIT_OBJECT_0 + 3 && ev < WAIT_OBJECT_0 + nev) { | |
221 | |
222 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "reap worker"); | |
223 | |
224 live = ngx_reap_worker(cycle, events[ev]); | |
225 | |
226 if (!live && (ngx_terminate || ngx_quit)) { | |
227 ngx_master_process_exit(cycle); | |
228 } | |
229 | |
230 continue; | |
231 } | |
232 | |
233 if (ev == WAIT_TIMEOUT) { | |
234 ngx_terminate_worker_processes(cycle); | |
235 | |
236 ngx_master_process_exit(cycle); | |
237 } | |
238 | |
239 if (ev == WAIT_FAILED) { | |
240 ngx_log_error(NGX_LOG_ALERT, cycle->log, err, | |
241 "WaitForMultipleObjects() failed"); | |
242 | |
243 continue; | |
244 } | |
245 | |
246 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
247 "WaitForMultipleObjects() returned unexpected value %ul", ev); | |
248 } | |
318
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 |
56496082668b
nginx-0.0.3-2004-04-16-09:14:16 import
Igor Sysoev <igor@sysoev.ru>
parents:
306
diff
changeset
|
251 |
2725 | 252 static void |
253 ngx_console_init(ngx_cycle_t *cycle) | |
254 { | |
255 ngx_core_conf_t *ccf; | |
256 | |
257 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | |
258 | |
259 if (ccf->daemon) { | |
260 if (FreeConsole() == 0) { | |
261 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
262 "FreeConsole() failed"); | |
263 } | |
264 | |
265 return; | |
266 } | |
267 | |
268 if (SetConsoleCtrlHandler(ngx_console_handler, 1) == 0) { | |
269 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
270 "SetConsoleCtrlHandler() failed"); | |
271 } | |
272 } | |
273 | |
274 | |
275 static int __stdcall | |
276 ngx_console_handler(u_long type) | |
277 { | |
278 char *msg; | |
279 | |
280 switch (type) { | |
281 | |
282 case CTRL_C_EVENT: | |
283 msg = "Ctrl-C pressed, exiting"; | |
284 break; | |
285 | |
286 case CTRL_BREAK_EVENT: | |
287 msg = "Ctrl-Break pressed, exiting"; | |
288 break; | |
289 | |
290 case CTRL_CLOSE_EVENT: | |
291 msg = "console closing, exiting"; | |
292 break; | |
293 | |
294 case CTRL_LOGOFF_EVENT: | |
295 msg = "user logs off, exiting"; | |
296 break; | |
297 | |
298 default: | |
299 return 0; | |
300 } | |
301 | |
302 ngx_log_error(NGX_LOG_NOTICE, ngx_cycle->log, 0, msg); | |
303 | |
304 if (ngx_stop_event == NULL) { | |
305 return 1; | |
306 } | |
307 | |
308 if (SetEvent(ngx_stop_event) == 0) { | |
309 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0, | |
310 "SetEvent(\"%s\") failed", ngx_stop_event_name); | |
2627 | 311 } |
312 | |
2725 | 313 return 1; |
314 } | |
315 | |
316 | |
317 static ngx_int_t | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
318 ngx_create_signal_events(ngx_cycle_t *cycle) |
2725 | 319 { |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
320 ngx_sprintf((u_char *) ngx_stop_event_name, |
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
321 "Global\\ngx_stop_%s%Z", ngx_unique); |
2725 | 322 |
323 ngx_stop_event = CreateEvent(NULL, 1, 0, ngx_stop_event_name); | |
324 if (ngx_stop_event == NULL) { | |
325 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
326 "CreateEvent(\"%s\") failed", ngx_stop_event_name); | |
327 return NGX_ERROR; | |
328 } | |
329 | |
330 | |
3751
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
331 ngx_sprintf((u_char *) ngx_quit_event_name, |
a4755d4fd91b
add "Global\" prefix for signal events
Igor Sysoev <igor@sysoev.ru>
parents:
3475
diff
changeset
|
332 "Global\\ngx_quit_%s%Z", ngx_unique); |
2725 | 333 |
334 ngx_quit_event = CreateEvent(NULL, 1, 0, ngx_quit_event_name); | |
335 if (ngx_quit_event == NULL) { | |
336 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
337 "CreateEvent(\"%s\") failed", ngx_quit_event_name); | |
338 return NGX_ERROR; | |
339 } | |
340 | |
341 | |
342 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
|
343 "Global\\ngx_reopen_%s%Z", ngx_unique); |
2725 | 344 |
345 ngx_reopen_event = CreateEvent(NULL, 1, 0, ngx_reopen_event_name); | |
346 if (ngx_reopen_event == NULL) { | |
347 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
348 "CreateEvent(\"%s\") failed", ngx_reopen_event_name); | |
349 return NGX_ERROR; | |
350 } | |
351 | |
352 | |
353 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
|
354 "Global\\ngx_reload_%s%Z", ngx_unique); |
2725 | 355 |
356 ngx_reload_event = CreateEvent(NULL, 1, 0, ngx_reload_event_name); | |
357 if (ngx_reload_event == NULL) { | |
358 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
359 "CreateEvent(\"%s\") failed", ngx_reload_event_name); | |
360 return NGX_ERROR; | |
361 } | |
362 | |
363 return NGX_OK; | |
364 } | |
365 | |
366 | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
367 static ngx_int_t |
2725 | 368 ngx_start_worker_processes(ngx_cycle_t *cycle, ngx_int_t type) |
369 { | |
370 ngx_int_t n; | |
371 ngx_core_conf_t *ccf; | |
372 | |
373 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "start worker processes"); | |
374 | |
375 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | |
376 | |
377 for (n = 0; n < ccf->worker_processes; n++) { | |
378 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
|
379 break; |
2725 | 380 } |
381 } | |
2922
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
382 |
f0604d0b28a6
*) exit if no workers could not be started
Igor Sysoev <igor@sysoev.ru>
parents:
2921
diff
changeset
|
383 return n; |
2627 | 384 } |
385 | |
386 | |
2725 | 387 static void |
388 ngx_reopen_worker_processes(ngx_cycle_t *cycle) | |
389 { | |
390 ngx_int_t n; | |
391 | |
392 for (n = 0; n < ngx_last_process; n++) { | |
393 | |
394 if (ngx_processes[n].handle == NULL) { | |
395 continue; | |
396 } | |
397 | |
398 if (SetEvent(ngx_processes[n].reopen) == 0) { | |
399 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
400 "SetEvent(\"%s\") failed", | |
401 ngx_processes[n].reopen_event); | |
402 } | |
403 } | |
404 } | |
405 | |
406 | |
407 static void | |
408 ngx_quit_worker_processes(ngx_cycle_t *cycle, ngx_uint_t old) | |
2627 | 409 { |
2725 | 410 ngx_int_t n; |
411 | |
412 for (n = 0; n < ngx_last_process; n++) { | |
413 | |
414 ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
2921 | 415 "process: %d %P %p e:%d j:%d", |
2725 | 416 n, |
417 ngx_processes[n].pid, | |
418 ngx_processes[n].handle, | |
419 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
|
420 ngx_processes[n].just_spawn); |
2725 | 421 |
3016
d82993af1da0
introduce NGX_PROCESS_JUST_SPAWN and change field name accordingly
Igor Sysoev <igor@sysoev.ru>
parents:
2928
diff
changeset
|
422 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
|
423 ngx_processes[n].just_spawn = 0; |
2725 | 424 continue; |
425 } | |
426 | |
427 if (ngx_processes[n].handle == NULL) { | |
428 continue; | |
429 } | |
430 | |
431 if (SetEvent(ngx_processes[n].quit) == 0) { | |
432 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
433 "SetEvent(\"%s\") failed", | |
434 ngx_processes[n].quit_event); | |
435 } | |
436 | |
437 ngx_processes[n].exiting = 1; | |
438 } | |
439 } | |
440 | |
441 | |
442 static void | |
443 ngx_terminate_worker_processes(ngx_cycle_t *cycle) | |
444 { | |
445 ngx_int_t n; | |
446 | |
447 for (n = 0; n < ngx_last_process; n++) { | |
448 | |
449 if (ngx_processes[n].handle == NULL) { | |
450 continue; | |
451 } | |
452 | |
453 if (TerminateProcess(ngx_processes[n].handle, 0) == 0) { | |
454 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
455 "TerminateProcess(\"%p\") failed", | |
456 ngx_processes[n].handle); | |
457 } | |
458 | |
459 ngx_processes[n].exiting = 1; | |
2627 | 460 |
2725 | 461 ngx_close_handle(ngx_processes[n].reopen); |
462 ngx_close_handle(ngx_processes[n].quit); | |
463 ngx_close_handle(ngx_processes[n].term); | |
464 ngx_close_handle(ngx_processes[n].handle); | |
465 } | |
466 } | |
467 | |
468 | |
469 static ngx_uint_t | |
470 ngx_reap_worker(ngx_cycle_t *cycle, HANDLE h) | |
471 { | |
472 u_long code; | |
473 ngx_int_t n; | |
474 | |
475 for (n = 0; n < ngx_last_process; n++) { | |
476 | |
477 if (ngx_processes[n].handle != h) { | |
478 continue; | |
479 } | |
480 | |
481 if (GetExitCodeProcess(h, &code) == 0) { | |
2908
234a8248812c
log GetExitCodeProcess()'s errno
Igor Sysoev <igor@sysoev.ru>
parents:
2823
diff
changeset
|
482 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, |
2725 | 483 "GetExitCodeProcess(%P) failed", |
484 ngx_processes[n].pid); | |
485 } | |
486 | |
487 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
|
488 "%s process %P exited with code %Xl", |
2725 | 489 ngx_processes[n].name, ngx_processes[n].pid, code); |
490 | |
491 ngx_close_handle(ngx_processes[n].reopen); | |
492 ngx_close_handle(ngx_processes[n].quit); | |
493 ngx_close_handle(ngx_processes[n].term); | |
494 ngx_close_handle(h); | |
2627 | 495 |
2725 | 496 ngx_processes[n].handle = NULL; |
497 ngx_processes[n].term = NULL; | |
498 ngx_processes[n].quit = NULL; | |
499 ngx_processes[n].reopen = NULL; | |
500 | |
501 if (!ngx_processes[n].exiting && !ngx_terminate && !ngx_quit) { | |
502 | |
503 if (ngx_spawn_process(cycle, ngx_processes[n].name, n) | |
504 == NGX_INVALID_PID) | |
505 { | |
506 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
|
507 "could not respawn %s", ngx_processes[n].name); |
2725 | 508 |
509 if (n == ngx_last_process - 1) { | |
510 ngx_last_process--; | |
511 } | |
512 } | |
513 } | |
2627 | 514 |
2725 | 515 goto found; |
516 } | |
517 | |
518 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, "unknown process handle %p", h); | |
519 | |
520 found: | |
521 | |
522 for (n = 0; n < ngx_last_process; n++) { | |
523 | |
524 ngx_log_debug5(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
2921 | 525 "process: %d %P %p e:%d j:%d", |
2725 | 526 n, |
527 ngx_processes[n].pid, | |
528 ngx_processes[n].handle, | |
529 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
|
530 ngx_processes[n].just_spawn); |
2725 | 531 |
532 if (ngx_processes[n].handle) { | |
533 return 1; | |
534 } | |
2627 | 535 } |
536 | |
537 return 0; | |
538 } | |
539 | |
540 | |
541 static void | |
2725 | 542 ngx_master_process_exit(ngx_cycle_t *cycle) |
543 { | |
544 ngx_uint_t i; | |
545 | |
546 ngx_delete_pidfile(cycle); | |
547 | |
548 ngx_close_handle(ngx_cache_manager_mutex); | |
549 ngx_close_handle(ngx_stop_event); | |
550 ngx_close_handle(ngx_quit_event); | |
551 ngx_close_handle(ngx_reopen_event); | |
552 ngx_close_handle(ngx_reload_event); | |
553 ngx_close_handle(ngx_master_process_event); | |
554 | |
555 ngx_log_error(NGX_LOG_NOTICE, cycle->log, 0, "exit"); | |
556 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
557 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
|
558 if (cycle->modules[i]->exit_master) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
559 cycle->modules[i]->exit_master(cycle); |
2725 | 560 } |
561 } | |
562 | |
563 ngx_destroy_pool(cycle->pool); | |
564 | |
565 exit(0); | |
566 } | |
567 | |
568 | |
569 static void | |
570 ngx_worker_process_cycle(ngx_cycle_t *cycle, char *mevn) | |
2627 | 571 { |
2725 | 572 char wtevn[NGX_PROCESS_SYNC_NAME]; |
573 char wqevn[NGX_PROCESS_SYNC_NAME]; | |
574 char wroevn[NGX_PROCESS_SYNC_NAME]; | |
575 HANDLE mev, events[3]; | |
576 u_long nev, ev; | |
577 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
|
578 ngx_tid_t wtid, cmtid, cltid; |
2725 | 579 ngx_log_t *log; |
580 | |
581 log = cycle->log; | |
582 | |
583 ngx_log_debug0(NGX_LOG_DEBUG_CORE, log, 0, "worker started"); | |
584 | |
6482
2b7dacb381ed
Fixed ngx_pid_t formatting in ngx_sprintf() and logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6379
diff
changeset
|
585 ngx_sprintf((u_char *) wtevn, "ngx_worker_term_%P%Z", ngx_pid); |
2725 | 586 events[0] = CreateEvent(NULL, 1, 0, wtevn); |
587 if (events[0] == NULL) { | |
588 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
589 "CreateEvent(\"%s\") failed", wtevn); | |
590 goto failed; | |
591 } | |
592 | |
6482
2b7dacb381ed
Fixed ngx_pid_t formatting in ngx_sprintf() and logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6379
diff
changeset
|
593 ngx_sprintf((u_char *) wqevn, "ngx_worker_quit_%P%Z", ngx_pid); |
2725 | 594 events[1] = CreateEvent(NULL, 1, 0, wqevn); |
595 if (events[1] == NULL) { | |
596 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
597 "CreateEvent(\"%s\") failed", wqevn); | |
598 goto failed; | |
599 } | |
600 | |
6482
2b7dacb381ed
Fixed ngx_pid_t formatting in ngx_sprintf() and logging.
Sergey Kandaurov <pluknet@nginx.com>
parents:
6379
diff
changeset
|
601 ngx_sprintf((u_char *) wroevn, "ngx_worker_reopen_%P%Z", ngx_pid); |
2725 | 602 events[2] = CreateEvent(NULL, 1, 0, wroevn); |
603 if (events[2] == NULL) { | |
604 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
605 "CreateEvent(\"%s\") failed", wroevn); | |
606 goto failed; | |
607 } | |
608 | |
609 mev = OpenEvent(EVENT_MODIFY_STATE, 0, mevn); | |
610 if (mev == NULL) { | |
611 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
612 "OpenEvent(\"%s\") failed", mevn); | |
613 goto failed; | |
614 } | |
615 | |
616 if (SetEvent(mev) == 0) { | |
617 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
618 "SetEvent(\"%s\") failed", mevn); | |
619 goto failed; | |
620 } | |
621 | |
622 | |
623 ngx_sprintf((u_char *) ngx_cache_manager_mutex_name, | |
624 "ngx_cache_manager_mutex_%s%Z", ngx_unique); | |
625 | |
626 ngx_cache_manager_mutex = OpenMutex(SYNCHRONIZE, 0, | |
627 ngx_cache_manager_mutex_name); | |
628 if (ngx_cache_manager_mutex == NULL) { | |
629 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
630 "OpenMutex(\"%s\") failed", ngx_cache_manager_mutex_name); | |
631 goto failed; | |
632 } | |
633 | |
634 ngx_cache_manager_event = CreateEvent(NULL, 1, 0, NULL); | |
635 if (ngx_cache_manager_event == NULL) { | |
636 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
637 "CreateEvent(\"ngx_cache_manager_event\") failed"); | |
638 goto failed; | |
639 } | |
640 | |
641 | |
642 if (ngx_create_thread(&wtid, ngx_worker_thread, NULL, log) != 0) { | |
643 goto failed; | |
644 } | |
645 | |
646 if (ngx_create_thread(&cmtid, ngx_cache_manager_thread, NULL, log) != 0) { | |
647 goto failed; | |
648 } | |
649 | |
3352
5c43621c580a
a cache manager thread handle was overwritten by a cache loader thread handle,
Igor Sysoev <igor@sysoev.ru>
parents:
3035
diff
changeset
|
650 if (ngx_create_thread(&cltid, ngx_cache_loader_thread, NULL, log) != 0) { |
3022 | 651 goto failed; |
652 } | |
653 | |
2725 | 654 for ( ;; ) { |
655 ev = WaitForMultipleObjects(3, events, 0, INFINITE); | |
656 | |
657 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
|
658 ngx_time_update(); |
461 | 659 |
2725 | 660 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, |
661 "worker WaitForMultipleObjects: %ul", ev); | |
662 | |
663 if (ev == WAIT_OBJECT_0) { | |
664 ngx_terminate = 1; | |
665 ngx_log_error(NGX_LOG_NOTICE, log, 0, "exiting"); | |
666 | |
667 if (ResetEvent(events[0]) == 0) { | |
668 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
669 "ResetEvent(\"%s\") failed", wtevn); | |
670 } | |
671 | |
672 break; | |
673 } | |
674 | |
675 if (ev == WAIT_OBJECT_0 + 1) { | |
676 ngx_quit = 1; | |
677 ngx_log_error(NGX_LOG_NOTICE, log, 0, "gracefully shutting down"); | |
678 break; | |
679 } | |
680 | |
681 if (ev == WAIT_OBJECT_0 + 2) { | |
682 ngx_reopen = 1; | |
683 ngx_log_error(NGX_LOG_NOTICE, log, 0, "reopening logs"); | |
684 | |
685 if (ResetEvent(events[2]) == 0) { | |
686 ngx_log_error(NGX_LOG_ALERT, log, 0, | |
687 "ResetEvent(\"%s\") failed", wroevn); | |
688 } | |
689 | |
690 continue; | |
691 } | |
692 | |
693 if (ev == WAIT_FAILED) { | |
694 ngx_log_error(NGX_LOG_ALERT, log, err, | |
695 "WaitForMultipleObjects() failed"); | |
696 | |
697 goto failed; | |
698 } | |
699 } | |
700 | |
701 /* wait threads */ | |
461 | 702 |
2725 | 703 if (SetEvent(ngx_cache_manager_event) == 0) { |
704 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, | |
705 "SetEvent(\"ngx_cache_manager_event\") failed"); | |
706 } | |
707 | |
708 events[1] = wtid; | |
709 events[2] = cmtid; | |
710 | |
711 nev = 3; | |
712 | |
713 for ( ;; ) { | |
714 ev = WaitForMultipleObjects(nev, events, 0, INFINITE); | |
715 | |
716 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
|
717 ngx_time_update(); |
2725 | 718 |
719 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0, | |
720 "worker exit WaitForMultipleObjects: %ul", ev); | |
721 | |
722 if (ev == WAIT_OBJECT_0) { | |
723 break; | |
724 } | |
725 | |
726 if (ev == WAIT_OBJECT_0 + 1) { | |
727 if (nev == 2) { | |
728 break; | |
729 } | |
730 | |
731 events[1] = events[2]; | |
732 nev = 2; | |
733 continue; | |
734 } | |
735 | |
736 if (ev == WAIT_OBJECT_0 + 2) { | |
737 nev = 2; | |
738 continue; | |
739 } | |
740 | |
741 if (ev == WAIT_FAILED) { | |
742 ngx_log_error(NGX_LOG_ALERT, log, err, | |
743 "WaitForMultipleObjects() failed"); | |
744 break; | |
745 } | |
461 | 746 } |
747 | |
2725 | 748 ngx_close_handle(ngx_cache_manager_event); |
749 ngx_close_handle(events[0]); | |
750 ngx_close_handle(events[1]); | |
751 ngx_close_handle(events[2]); | |
752 ngx_close_handle(mev); | |
753 | |
754 ngx_worker_process_exit(cycle); | |
755 | |
756 failed: | |
757 | |
758 exit(2); | |
759 } | |
760 | |
761 | |
762 static ngx_thread_value_t __stdcall | |
763 ngx_worker_thread(void *data) | |
764 { | |
6220
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
765 ngx_int_t n; |
6651
7d4e33092e2a
Always seed PRNG with PID, seconds, and milliseconds.
Ruslan Ermilov <ru@nginx.com>
parents:
6649
diff
changeset
|
766 ngx_time_t *tp; |
6220
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
767 ngx_cycle_t *cycle; |
2725 | 768 |
6651
7d4e33092e2a
Always seed PRNG with PID, seconds, and milliseconds.
Ruslan Ermilov <ru@nginx.com>
parents:
6649
diff
changeset
|
769 tp = ngx_timeofday(); |
7d4e33092e2a
Always seed PRNG with PID, seconds, and milliseconds.
Ruslan Ermilov <ru@nginx.com>
parents:
6649
diff
changeset
|
770 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
|
771 |
2725 | 772 cycle = (ngx_cycle_t *) ngx_cycle; |
773 | |
6379
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
774 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
|
775 if (cycle->modules[n]->init_process) { |
cf5e822cf470
Dynamic modules: changed ngx_modules to cycle->modules.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6220
diff
changeset
|
776 if (cycle->modules[n]->init_process(cycle) == NGX_ERROR) { |
2725 | 777 /* fatal */ |
778 exit(2); | |
779 } | |
780 } | |
781 } | |
782 | |
783 while (!ngx_quit) { | |
784 | |
785 if (ngx_exiting) { | |
6929
3069dd358ba2
Cancelable timers are now preserved if there are other timers.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6727
diff
changeset
|
786 if (ngx_event_no_timers_left() == NGX_OK) { |
2725 | 787 break; |
788 } | |
789 } | |
790 | |
791 ngx_log_debug0(NGX_LOG_DEBUG_CORE, cycle->log, 0, "worker cycle"); | |
792 | |
793 ngx_process_events_and_timers(cycle); | |
794 | |
795 if (ngx_terminate) { | |
796 return 0; | |
797 } | |
798 | |
799 if (ngx_quit) { | |
800 ngx_quit = 0; | |
801 | |
802 if (!ngx_exiting) { | |
6220
5e6142609e48
Core: idle connections now closed only once on exiting.
Valentin Bartenev <vbart@nginx.com>
parents:
6151
diff
changeset
|
803 ngx_exiting = 1; |
6930
97c99bb43737
Introduced worker_shutdown_timeout.
Maxim Dounin <mdounin@mdounin.ru>
parents:
6929
diff
changeset
|
804 ngx_set_shutdown_timer(cycle); |
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 ngx_uint_t i; | |
6727
ca709bca4b77
Cache: cache manager limits.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6651
diff
changeset
|
923 ngx_msec_t next, n; |
2725 | 924 ngx_path_t **path; |
925 | |
6727
ca709bca4b77
Cache: cache manager limits.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6651
diff
changeset
|
926 next = 60 * 60 * 1000; |
2725 | 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 | |
6727
ca709bca4b77
Cache: cache manager limits.
Dmitry Volyntsev <xeioex@nginx.com>
parents:
6651
diff
changeset
|
944 ev = WaitForSingleObject(ngx_cache_manager_event, (u_long) next); |
2725 | 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 } |