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