Klaus Demo nginx / e66eb15
merge r3473, r3474, r3385, r3386, r3537: signal processing stability: *) use sys_errlist[] in signal handler instead of non Async-Signal-Safe strerror_r() *) do not update time in the timer signal handler, since localtime_r() is not Async-Signal-Safe function *) use previously cached GMT offset value to update time from a signal handler *) change ngx_time_update() interface since there are no notification methods those return time *) introduce ngx_time_sigsafe_update() to update the error log time only *) change ngx_time_update() interface Igor Sysoev 12 years ago
20 changed file(s) with 140 addition(s) and 54 deletion(s). Raw diff Collapse all Expand all
132132 . auto/feature
133133
134134
135 ngx_feature="sys_errlist[]"
136 ngx_feature_name="NGX_HAVE_SYS_ERRLIST"
137 ngx_feature_run=yes
138 ngx_feature_incs="#include <stdio.h>"
139 ngx_feature_path=
140 ngx_feature_libs=
141 ngx_feature_test="int n = sys_nerr; const char *p = sys_errlist[1];"
142 . auto/feature
143
144
135145 ngx_feature="localtime_r()"
136146 ngx_feature_name="NGX_HAVE_LOCALTIME_R"
137147 ngx_feature_run=no
6262 tp = ngx_timeofday();
6363 tp->sec = 0;
6464
65 ngx_time_update(0, 0);
65 ngx_time_update();
6666
6767
6868 log = old_cycle->log;
2727 volatile ngx_str_t ngx_cached_http_time;
2828 volatile ngx_str_t ngx_cached_http_log_time;
2929
30 #if !(NGX_WIN32)
31
32 /*
33 * locatime() and localtime_r() are not Async-Signal-Safe functions, therefore,
34 * they must not be called by a signal handler, so we use the cached
35 * GMT offset value. Fortunately the value is changed only two times a year.
36 */
37
38 static ngx_int_t cached_gmtoff;
39 #endif
40
3041 static ngx_time_t cached_time[NGX_TIME_SLOTS];
3142 static u_char cached_err_log_time[NGX_TIME_SLOTS]
3243 [sizeof("1970/09/28 12:00:00")];
4960
5061 ngx_cached_time = &cached_time[0];
5162
52 ngx_time_update(0, 0);
63 ngx_time_update();
5364 }
5465
5566
5667 void
57 ngx_time_update(time_t sec, ngx_uint_t msec)
68 ngx_time_update(void)
5869 {
5970 u_char *p0, *p1, *p2;
6071 ngx_tm_t tm, gmt;
72 time_t sec;
73 ngx_uint_t msec;
6174 ngx_time_t *tp;
6275 struct timeval tv;
6376
6578 return;
6679 }
6780
68 if (sec == 0) {
69 ngx_gettimeofday(&tv);
70
71 sec = tv.tv_sec;
72 msec = tv.tv_usec / 1000;
73 }
81 ngx_gettimeofday(&tv);
82
83 sec = tv.tv_sec;
84 msec = tv.tv_usec / 1000;
7485
7586 ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;
7687
111122 #elif (NGX_HAVE_GMTOFF)
112123
113124 ngx_localtime(sec, &tm);
114 tp->gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
125 cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
126 tp->gmtoff = cached_gmtoff;
115127
116128 #else
117129
118130 ngx_localtime(sec, &tm);
119 tp->gmtoff = ngx_timezone(tm.ngx_tm_isdst);
131 cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst);
132 tp->gmtoff = cached_gmtoff;
120133
121134 #endif
122135
148161
149162 ngx_unlock(&ngx_time_lock);
150163 }
164
165
166 #if !(NGX_WIN32)
167
168 void
169 ngx_time_sigsafe_update(void)
170 {
171 u_char *p;
172 ngx_tm_t tm;
173 time_t sec;
174 ngx_time_t *tp;
175 struct timeval tv;
176
177 if (!ngx_trylock(&ngx_time_lock)) {
178 return;
179 }
180
181 ngx_gettimeofday(&tv);
182
183 sec = tv.tv_sec;
184
185 tp = &cached_time[slot];
186
187 if (tp->sec == sec) {
188 ngx_unlock(&ngx_time_lock);
189 return;
190 }
191
192 if (slot == NGX_TIME_SLOTS - 1) {
193 slot = 0;
194 } else {
195 slot++;
196 }
197
198 ngx_gmtime(sec + cached_gmtoff * 60, &tm);
199
200 p = &cached_err_log_time[slot][0];
201
202 (void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d",
203 tm.ngx_tm_year, tm.ngx_tm_mon,
204 tm.ngx_tm_mday, tm.ngx_tm_hour,
205 tm.ngx_tm_min, tm.ngx_tm_sec);
206
207 ngx_memory_barrier();
208
209 ngx_cached_err_log_time.data = p;
210
211 ngx_unlock(&ngx_time_lock);
212 }
213
214 #endif
151215
152216
153217 u_char *
1919
2020
2121 void ngx_time_init(void);
22 void ngx_time_update(time_t sec, ngx_uint_t msec);
22 void ngx_time_update(void);
23 void ngx_time_sigsafe_update(void);
2324 u_char *ngx_http_time(u_char *buf, time_t t);
2425 u_char *ngx_http_cookie_time(u_char *buf, time_t t);
2526 void ngx_gmtime(time_t t, ngx_tm_t *tp);
374374 err = 0;
375375 }
376376
377 if (flags & NGX_UPDATE_TIME) {
378 ngx_time_update(0, 0);
377 if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
378 ngx_time_update();
379379 }
380380
381381 if (err) {
406406 err = 0;
407407 }
408408
409 if (flags & NGX_UPDATE_TIME) {
410 ngx_time_update(0, 0);
409 if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
410 ngx_time_update();
411411 }
412412
413413 if (err) {
404404 err = ngx_errno;
405405
406406 if (flags & NGX_UPDATE_TIME) {
407 ngx_time_update(0, 0);
407 ngx_time_update();
408408 }
409409
410410 if (n == -1) {
438438 for (i = 0; i < events; i++) {
439439
440440 if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
441 ngx_time_update(0, 0);
441 ngx_time_update();
442442 continue;
443443 }
444444
162162 for ( ;; ) {
163163 Sleep(timer);
164164
165 ngx_time_update(0, 0);
165 ngx_time_update();
166166 #if 1
167167 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer");
168168 #endif
257257 delta = ngx_current_msec;
258258
259259 if (flags & NGX_UPDATE_TIME) {
260 ngx_time_update(0, 0);
260 ngx_time_update();
261261 }
262262
263263 ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
542542 err = 0;
543543 }
544544
545 if (flags & NGX_UPDATE_TIME) {
546 ngx_time_update(0, 0);
545 if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
546 ngx_time_update();
547547 }
548548
549549 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
594594 #if (NGX_HAVE_TIMER_EVENT)
595595
596596 if (event_list[i].filter == EVFILT_TIMER) {
597 ngx_time_update(0, 0);
597 ngx_time_update();
598598 continue;
599599 }
600600
265265 err = 0;
266266 }
267267
268 if (flags & NGX_UPDATE_TIME) {
269 ngx_time_update(0, 0);
268 if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
269 ngx_time_update();
270270 }
271271
272272 ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
322322 "rtsig signo:%d", signo);
323323
324324 if (flags & NGX_UPDATE_TIME) {
325 ngx_time_update(0, 0);
325 ngx_time_update();
326326 }
327327
328328 if (err == NGX_EAGAIN) {
348348 signo, si.si_fd, si.si_band);
349349
350350 if (flags & NGX_UPDATE_TIME) {
351 ngx_time_update(0, 0);
351 ngx_time_update();
352352 }
353353
354354 rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
418418
419419 } else if (signo == SIGALRM) {
420420
421 ngx_time_update(0, 0);
421 ngx_time_update();
422422
423423 return NGX_OK;
424424
670670 }
671671
672672 if (flags & NGX_UPDATE_TIME) {
673 ngx_time_update(0, 0);
673 ngx_time_update();
674674 }
675675
676676 ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
265265 err = 0;
266266 }
267267
268 if (flags & NGX_UPDATE_TIME) {
269 ngx_time_update(0, 0);
268 if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
269 ngx_time_update();
270270 }
271271
272272 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
272272 }
273273
274274 if (flags & NGX_UPDATE_TIME) {
275 ngx_time_update(0, 0);
275 ngx_time_update();
276276 }
277277
278278 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
561561 {
562562 ngx_event_timer_alarm = 1;
563563
564 ngx_time_update(0, 0);
565
566564 #if 1
567565 ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
568566 #endif
11271127
11281128 if (cache->files++ > 100) {
11291129
1130 ngx_time_update(0, 0);
1130 ngx_time_update();
11311131
11321132 elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
11331133
11441144
11451145 ngx_msleep(200);
11461146
1147 ngx_time_update(0, 0);
1147 ngx_time_update();
11481148 }
11491149
11501150 cache->last = ngx_current_msec;
6363
6464 /* Solaris and Tru64 UNIX have thread-safe strerror() */
6565
66 #define ngx_strerror_r(err, errstr, size) \
66 #define ngx_strerror_r(err, errstr, size) \
6767 ngx_cpystrn(errstr, (u_char *) strerror(err), size)
6868
6969 #endif
7070
7171
72 #if (NGX_HAVE_SYS_ERRLIST)
73
74 #define ngx_sigsafe_strerror(err) \
75 (err > 0 && err < sys_nerr) ? sys_errlist[err] : "Unknown error"
76
77 #else
78
79 #define ngx_sigsafe_strerror(err) ""
80
81 #endif
82
83
7284 #endif /* _NGX_ERRNO_H_INCLUDED_ */
314314 }
315315 }
316316
317 ngx_time_update(0, 0);
317 ngx_time_sigsafe_update();
318318
319319 action = "";
320320
475475 */
476476
477477 if (err == NGX_ECHILD) {
478 ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, errno,
479 "waitpid() failed");
478 ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
479 "waitpid() failed (%d: %s)",
480 err, ngx_sigsafe_strerror(err));
480481 return;
481482 }
482483
483484 #endif
484485
485 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, errno,
486 "waitpid() failed");
487
486 ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
487 "waitpid() failed (%d: %s)",
488 err, ngx_sigsafe_strerror(err));
488489 return;
489490 }
490491
167167
168168 sigsuspend(&set);
169169
170 ngx_time_update(0, 0);
170 ngx_time_update();
171171
172172 ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
173173 "wake up, sigio %i", sigio);
13361336
13371337 next = (n <= next) ? n : next;
13381338
1339 ngx_time_update(0, 0);
1339 ngx_time_update();
13401340 }
13411341 }
13421342
13661366
13671367 if (path[i]->loader) {
13681368 path[i]->loader(path[i]->data);
1369 ngx_time_update(0, 0);
1369 ngx_time_update();
13701370 }
13711371 }
13721372
8484
8585 rc = WaitForMultipleObjects(2, events, 0, 5000);
8686
87 ngx_time_update(0, 0);
87 ngx_time_update();
8888
8989 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
9090 "WaitForMultipleObjects: %ul", rc);
139139 ev = WaitForMultipleObjects(nev, events, 0, timeout);
140140
141141 err = ngx_errno;
142 ngx_time_update(0, 0);
142 ngx_time_update();
143143
144144 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
145145 "master WaitForMultipleObjects: %ul", ev);
678678 ev = WaitForMultipleObjects(3, events, 0, INFINITE);
679679
680680 err = ngx_errno;
681 ngx_time_update(0, 0);
681 ngx_time_update();
682682
683683 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
684684 "worker WaitForMultipleObjects: %ul", ev);
737737 ev = WaitForMultipleObjects(nev, events, 0, INFINITE);
738738
739739 err = ngx_errno;
740 ngx_time_update(0, 0);
740 ngx_time_update();
741741
742742 ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
743743 "worker exit WaitForMultipleObjects: %ul", ev);
906906 ev = WaitForMultipleObjects(2, events, 0, INFINITE);
907907
908908 err = ngx_errno;
909 ngx_time_update(0, 0);
909 ngx_time_update();
910910
911911 ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
912912 "cache manager WaitForMultipleObjects: %ul", ev);
967967
968968 next = (n <= next) ? n : next;
969969
970 ngx_time_update(0, 0);
970 ngx_time_update();
971971 }
972972 }
973973
979979
980980 if (ev != WAIT_TIMEOUT) {
981981
982 ngx_time_update(0, 0);
982 ngx_time_update();
983983
984984 ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
985985 "cache manager WaitForSingleObject: %ul", ev);
10071007
10081008 if (path[i]->loader) {
10091009 path[i]->loader(path[i]->data);
1010 ngx_time_update(0, 0);
1010 ngx_time_update();
10111011 }
10121012 }
10131013