Mercurial > hg > nginx-quic
comparison src/os/unix/ngx_process_cycle.c @ 317:1308b98496a2
nginx-0.0.3-2004-04-15-19:34:36 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Thu, 15 Apr 2004 15:34:36 +0000 |
parents | 39b6f2df45c0 |
children | 56496082668b |
comparison
equal
deleted
inserted
replaced
316:a0beefedaf94 | 317:1308b98496a2 |
---|---|
4 #include <ngx_event.h> | 4 #include <ngx_event.h> |
5 | 5 |
6 #include <nginx.h> | 6 #include <nginx.h> |
7 | 7 |
8 | 8 |
9 static void ngx_start_worker_processes(ngx_cycle_y *cycle, ngx_int_t n) | |
9 static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); | 10 static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx); |
10 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); | 11 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data); |
11 #if (NGX_THREADS) | 12 #if (NGX_THREADS) |
12 static int ngx_worker_thread_cycle(void *data); | 13 static int ngx_worker_thread_cycle(void *data); |
13 #endif | 14 #endif |
14 | 15 |
15 | 16 |
16 ngx_int_t ngx_process; | 17 ngx_int_t ngx_process; |
17 ngx_pid_t ngx_pid; | 18 ngx_pid_t ngx_pid; |
18 ngx_pid_t ngx_new_binary; | |
19 ngx_int_t ngx_inherited; | |
20 ngx_int_t ngx_threaded; | 19 ngx_int_t ngx_threaded; |
21 | 20 |
22 sig_atomic_t ngx_reap; | 21 sig_atomic_t ngx_reap; |
23 sig_atomic_t ngx_timer; | 22 sig_atomic_t ngx_timer; |
24 sig_atomic_t ngx_terminate; | 23 sig_atomic_t ngx_terminate; |
25 sig_atomic_t ngx_quit; | 24 sig_atomic_t ngx_quit; |
26 sig_atomic_t ngx_noaccept; | |
27 sig_atomic_t ngx_reconfigure; | 25 sig_atomic_t ngx_reconfigure; |
28 sig_atomic_t ngx_reopen; | 26 sig_atomic_t ngx_reopen; |
27 | |
29 sig_atomic_t ngx_change_binary; | 28 sig_atomic_t ngx_change_binary; |
30 | 29 ngx_pid_t ngx_new_binary; |
31 | 30 ngx_int_t ngx_inherited; |
32 /* TODO: broken NGX_PROCESS_SINGLE */ | 31 |
32 sig_atomic_t ngx_noaccept; | |
33 ngx_uint_t ngx_noaccepting; | |
34 ngx_uint_t ngx_restart; | |
35 | |
36 | |
37 void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) | |
38 { | |
39 int signo; | |
40 sigset_t set; | |
41 struct timeval tv; | |
42 struct itimerval itv; | |
43 ngx_uint_t i, live; | |
44 ngx_msec_t delay; | |
45 ngx_core_conf_t *ccf; | |
46 | |
47 sigemptyset(&set); | |
48 sigaddset(&set, SIGCHLD); | |
49 sigaddset(&set, SIGALRM); | |
50 sigaddset(&set, SIGINT); | |
51 sigaddset(&set, ngx_signal_value(NGX_RECONFIGURE_SIGNAL)); | |
52 sigaddset(&set, ngx_signal_value(NGX_REOPEN_SIGNAL)); | |
53 sigaddset(&set, ngx_signal_value(NGX_NOACCEPT_SIGNAL)); | |
54 sigaddset(&set, ngx_signal_value(NGX_TERMINATE_SIGNAL)); | |
55 sigaddset(&set, ngx_signal_value(NGX_SHUTDOWN_SIGNAL)); | |
56 sigaddset(&set, ngx_signal_value(NGX_CHANGEBIN_SIGNAL)); | |
57 | |
58 if (sigprocmask(SIG_BLOCK, &set, NULL) == -1) { | |
59 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
60 "sigprocmask() failed"); | |
61 } | |
62 | |
63 sigemptyset(&set); | |
64 | |
65 ngx_setproctitle("master process"); | |
66 | |
67 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, ngx_core_module); | |
68 | |
69 ngx_start_worker_processes(ccf->worker_processes); | |
70 | |
71 ngx_new_binary = 0; | |
72 delay = 0; | |
73 signo = 0; | |
74 live = 1; | |
75 | |
76 for ( ;; ) { | |
77 if (delay) { | |
78 delay *= 2; | |
79 | |
80 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
81 "temination cycle: %d", delay); | |
82 | |
83 itv.it_interval.tv_sec = 0; | |
84 itv.it_interval.tv_usec = 0; | |
85 itv.it_value.tv_sec = delay / 1000; | |
86 itv.it_value.tv_usec = (delay % 1000 ) * 1000; | |
87 | |
88 if (setitimer(ITIMER_REAL, &itv, NULL) == -1) { | |
89 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
90 "setitimer() failed"); | |
91 } | |
92 } | |
93 | |
94 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "sigsuspend"); | |
95 | |
96 sigsuspend(&set); | |
97 | |
98 ngx_gettimeofday(&tv); | |
99 ngx_time_update(tv.tv_sec); | |
100 | |
101 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "wake up"); | |
102 | |
103 if (ngx_reap) { | |
104 ngx_reap = 0; | |
105 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap childs"); | |
106 | |
107 live = 0; | |
108 for (i = 0; i < ngx_last_process; i++) { | |
109 | |
110 ngx_log_debug5(NGX_LOG_DEBUG_EVENT, cycle->log, 0, | |
111 "child: " PID_T_FMT " e:%d t:%d d:%d r:%d", | |
112 ngx_processes[i].pid, | |
113 ngx_processes[i].exiting, | |
114 ngx_processes[i].exited, | |
115 ngx_processes[i].detached, | |
116 ngx_processes[i].respawn); | |
117 | |
118 if (ngx_processes[i].exited) { | |
119 | |
120 if (ngx_processes[i].respawn | |
121 && !ngx_processes[i].exiting | |
122 && !ngx_terminate | |
123 && !ngx_quit) | |
124 { | |
125 if (ngx_spawn_process(cycle, ngx_processes[i].proc, | |
126 ngx_processes[i].data, | |
127 ngx_processes[i].name, i) | |
128 == NGX_ERROR) | |
129 { | |
130 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0, | |
131 "can not respawn %s", | |
132 ngx_processes[i].name); | |
133 continue; | |
134 } | |
135 | |
136 live = 1; | |
137 | |
138 continue; | |
139 } | |
140 | |
141 if (ngx_processes[i].pid == ngx_new_binary) { | |
142 ngx_new_binary = 0; | |
143 if (ngx_noaccepting) { | |
144 ngx_restart = 1; | |
145 ngx_noaccepting = 0; | |
146 } | |
147 } | |
148 | |
149 if (i != --ngx_last_process) { | |
150 ngx_processes[i--] = ngx_processes[ngx_last_process]; | |
151 } | |
152 | |
153 } else if (ngx_processes[i].exiting | |
154 || !ngx_processes[i].detached) | |
155 { | |
156 live = 1; | |
157 } | |
158 } | |
159 } | |
160 | |
161 if (!live && (ngx_terminate || ngx_quit)) { | |
162 ngx_master_exit(cycle, ctx); | |
163 } | |
164 | |
165 if (ngx_terminate) { | |
166 if (delay == 0) { | |
167 delay = 50; | |
168 } | |
169 | |
170 if (delay > 1000) { | |
171 signo = SIGKILL; | |
172 } else { | |
173 signo = ngx_signal_value(NGX_TERMINATE_SIGNAL); | |
174 } | |
175 | |
176 } else if (ngx_quit) { | |
177 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | |
178 | |
179 } else if (ngx_timer) { | |
180 ngx_start_worker_processes(ccf->worker_processes); | |
181 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | |
182 | |
183 } else if (ngx_reconfigure) { | |
184 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reconfiguring"); | |
185 | |
186 cycle = ngx_init_cycle(cycle); | |
187 if (cycle == NULL) { | |
188 cycle = (ngx_cycle_t *) ngx_cycle; | |
189 continue; | |
190 } | |
191 | |
192 ngx_cycle = cycle; | |
193 ccf = (ngx_core_conf_t *) ngx_get_conf(cycle->conf_ctx, | |
194 ngx_core_module); | |
195 ngx_start_worker_processes(ccf->worker_processes); | |
196 | |
197 ngx_reconfigure = 0; | |
198 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | |
199 | |
200 } else if (ngx_restart) { | |
201 ngx_start_worker_processes(ccf->worker_processes); | |
202 ngx_restart = 0; | |
203 | |
204 } else if (ngx_reopen) { | |
205 if (ngx_process == NGX_PROCESS_MASTER) { | |
206 signo = ngx_signal_value(NGX_REOPEN_SIGNAL); | |
207 ngx_reopen = 0; | |
208 | |
209 } else { /* NGX_PROCESS_SINGLE */ | |
210 ngx_reopen = 0; | |
211 } | |
212 | |
213 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, | |
214 "reopening logs"); | |
215 ngx_reopen_files(cycle, ccf->user); | |
216 | |
217 } else if (ngx_change_binary) { | |
218 ngx_change_binary = 0; | |
219 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, | |
220 "changing binary"); | |
221 ngx_new_binary = ngx_exec_new_binary(cycle, ctx->argv); | |
222 | |
223 } else if (ngx_noaccept) { | |
224 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | |
225 } | |
226 } | |
227 | |
228 if (signo) { | |
229 for (i = 0; i < ngx_last_process; i++) { | |
230 | |
231 if (ngx_processes[i].detached) { | |
232 continue; | |
233 } | |
234 | |
235 ngx_log_debug2(NGX_LOG_DEBUG_CORE, cycle->log, 0, | |
236 "kill (" PID_T_FMT ", %d)" , | |
237 ngx_processes[i].pid, signo); | |
238 | |
239 if (kill(ngx_processes[i].pid, signo) == -1) { | |
240 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
241 "kill(%d, %d) failed", | |
242 ngx_processes[i].pid, signo); | |
243 continue; | |
244 } | |
245 | |
246 if (signo != ngx_signal_value(NGX_REOPEN_SIGNAL)) { | |
247 ngx_processes[i].exiting = 1; | |
248 } | |
249 } | |
250 | |
251 signo = 0; | |
252 } | |
253 | |
254 | |
255 | |
256 | |
257 | |
258 | |
259 | |
260 | |
261 | |
262 | |
263 } | |
264 } | |
265 | |
33 | 266 |
34 void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) | 267 void ngx_master_process_cycle(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) |
35 { | 268 { |
36 int signo; | 269 int signo; |
37 sigset_t set; | 270 sigset_t set; |
236 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | 469 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); |
237 | 470 |
238 } else if (ngx_timer) { | 471 } else if (ngx_timer) { |
239 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | 472 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); |
240 | 473 |
241 } else { | 474 } else if (ngx_reconfigure) { |
242 | 475 ngx_reconfigure = 0; |
243 if (ngx_noaccept) { | 476 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "reconfiguring"); |
244 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | 477 |
245 } | 478 cycle = ngx_init_cycle(cycle); |
246 | 479 if (cycle == NULL) { |
247 if (ngx_change_binary) { | 480 cycle = (ngx_cycle_t *) ngx_cycle; |
481 continue; | |
482 } | |
483 | |
484 ngx_cycle = cycle; | |
485 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | |
486 | |
487 } else if (ngx_reopen) { | |
488 if (ngx_process == NGX_PROCESS_MASTER) { | |
489 signo = ngx_signal_value(NGX_REOPEN_SIGNAL); | |
490 ngx_reopen = 0; | |
491 | |
492 } else { /* NGX_PROCESS_SINGLE */ | |
493 ngx_reopen = 0; | |
494 } | |
495 | |
496 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, | |
497 "reopening logs"); | |
498 ngx_reopen_files(cycle, ccf->user); | |
499 | |
500 } else if (ngx_change_binary) { | |
248 ngx_change_binary = 0; | 501 ngx_change_binary = 0; |
249 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, | 502 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, |
250 "changing binary"); | 503 "changing binary"); |
251 ngx_new_binary = ngx_exec_new_binary(cycle, ctx->argv); | 504 ngx_new_binary = ngx_exec_new_binary(cycle, ctx->argv); |
252 } | 505 |
253 | 506 } else if (ngx_noaccept) { |
254 if (ngx_reconfigure) { | |
255 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); | 507 signo = ngx_signal_value(NGX_SHUTDOWN_SIGNAL); |
256 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, | |
257 "reconfiguring"); | |
258 } | |
259 | |
260 if (ngx_reopen) { | |
261 if (ngx_process == NGX_PROCESS_MASTER) { | |
262 signo = ngx_signal_value(NGX_REOPEN_SIGNAL); | |
263 ngx_reopen = 0; | |
264 | |
265 } else { /* NGX_PROCESS_SINGLE */ | |
266 ngx_reopen = 0; | |
267 } | |
268 | |
269 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, | |
270 "reopening logs"); | |
271 ngx_reopen_files(cycle, ccf->user); | |
272 } | 508 } |
273 } | 509 } |
274 | 510 |
275 if (signo) { | 511 if (signo) { |
276 for (i = 0; i < ngx_last_process; i++) { | 512 for (i = 0; i < ngx_last_process; i++) { |
324 ngx_reconfigure = 0; | 560 ngx_reconfigure = 0; |
325 } | 561 } |
326 | 562 |
327 break; | 563 break; |
328 } | 564 } |
565 } | |
566 } | |
567 | |
568 | |
569 static void ngx_start_worker_processes(ngx_cycle_y *cycle, ngx_int_t n) | |
570 { | |
571 struct itimerval itv; | |
572 | |
573 ngx_log_error(NGX_LOG_INFO, cycle->log, 0, "start worker processes"); | |
574 | |
575 while (n--) { | |
576 ngx_spawn_process(cycle, ngx_worker_process_cycle, NULL, | |
577 "worker process", NGX_PROCESS_RESPAWN); | |
578 } | |
579 | |
580 /* | |
581 * we have to limit the maximum life time of the worker processes | |
582 * by 10 days because our millisecond event timer is limited | |
583 * by 24 days on 32-bit platforms | |
584 */ | |
585 | |
586 itv.it_interval.tv_sec = 0; | |
587 itv.it_interval.tv_usec = 0; | |
588 itv.it_value.tv_sec = 10 * 24 * 60 * 60; | |
589 itv.it_value.tv_usec = 0; | |
590 | |
591 if (setitimer(ITIMER_REAL, &itv, NULL) == -1) { | |
592 ngx_log_error(NGX_LOG_ALERT, cycle->log, ngx_errno, | |
593 "setitimer() failed"); | |
329 } | 594 } |
330 } | 595 } |
331 | 596 |
332 | 597 |
333 static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) | 598 static void ngx_master_exit(ngx_cycle_t *cycle, ngx_master_ctx_t *ctx) |