comparison src/os/unix/ngx_process_cycle.c @ 3440:88741ec7731a stable-0.7

merge r3294, r3305: Fix a bug introduced in r2032: After a child process has read a terminate message from a channel, the process tries to read the channel again. The kernel (at least FreeBSD) may preempt the process and sends a SIGIO signal to a master process. The master process sends a new terminate message, the kernel switches again to the the child process, and the child process reads the messages instead of an EAGAIN error. And this may repeat over and over. Being that the child process can not exit the cycle and test the termination flag set by the message handler. The fix disallow the master process to send a new terminate message on SIGIO signal reception. It may send the message only on SIGALARM signal.
author Igor Sysoev <igor@sysoev.ru>
date Mon, 01 Feb 2010 15:49:36 +0000
parents 8c76116820f3
children e1409e56ba7c
comparison
equal deleted inserted replaced
3439:3354dfba9da4 3440:88741ec7731a
84 { 84 {
85 char *title; 85 char *title;
86 u_char *p; 86 u_char *p;
87 size_t size; 87 size_t size;
88 ngx_int_t i; 88 ngx_int_t i;
89 ngx_uint_t n; 89 ngx_uint_t n, sigio;
90 sigset_t set; 90 sigset_t set;
91 struct itimerval itv; 91 struct itimerval itv;
92 ngx_uint_t live; 92 ngx_uint_t live;
93 ngx_msec_t delay; 93 ngx_msec_t delay;
94 ngx_listening_t *ls; 94 ngx_listening_t *ls;
137 NGX_PROCESS_RESPAWN); 137 NGX_PROCESS_RESPAWN);
138 ngx_start_cache_manager_processes(cycle, 0); 138 ngx_start_cache_manager_processes(cycle, 0);
139 139
140 ngx_new_binary = 0; 140 ngx_new_binary = 0;
141 delay = 0; 141 delay = 0;
142 sigio = 0;
142 live = 1; 143 live = 1;
143 144
144 for ( ;; ) { 145 for ( ;; ) {
145 if (delay) { 146 if (delay) {
146 if (ngx_sigalrm) { 147 if (ngx_sigalrm) {
148 sigio = 0;
147 delay *= 2; 149 delay *= 2;
148 ngx_sigalrm = 0; 150 ngx_sigalrm = 0;
149 } 151 }
150 152
151 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0, 153 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
166 168
167 sigsuspend(&set); 169 sigsuspend(&set);
168 170
169 ngx_time_update(0, 0); 171 ngx_time_update(0, 0);
170 172
171 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "wake up"); 173 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
174 "wake up, sigio %i", sigio);
172 175
173 if (ngx_reap) { 176 if (ngx_reap) {
174 ngx_reap = 0; 177 ngx_reap = 0;
175 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children"); 178 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");
176 179
183 186
184 if (ngx_terminate) { 187 if (ngx_terminate) {
185 if (delay == 0) { 188 if (delay == 0) {
186 delay = 50; 189 delay = 50;
187 } 190 }
191
192 if (sigio) {
193 sigio--;
194 continue;
195 }
196
197 sigio = ccf->worker_processes + 2 /* cache processes */;
188 198
189 if (delay > 1000) { 199 if (delay > 1000) {
190 ngx_signal_worker_processes(cycle, SIGKILL); 200 ngx_signal_worker_processes(cycle, SIGKILL);
191 } else { 201 } else {
192 ngx_signal_worker_processes(cycle, 202 ngx_signal_worker_processes(cycle,