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