. auto/feature
+ngx_feature="sys_errlist[]"
+ngx_feature_name="NGX_HAVE_SYS_ERRLIST"
+ngx_feature_run=yes
+ngx_feature_incs="#include <stdio.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="int n = sys_nerr; const char *p = sys_errlist[1];"
+. auto/feature
+
+
ngx_feature="localtime_r()"
ngx_feature_name="NGX_HAVE_LOCALTIME_R"
ngx_feature_run=no
tp = ngx_timeofday();
tp->sec = 0;
- ngx_time_update(0, 0);
+ ngx_time_update();
log = old_cycle->log;
volatile ngx_str_t ngx_cached_http_time;
volatile ngx_str_t ngx_cached_http_log_time;
+#if !(NGX_WIN32)
+
+/*
+ * locatime() and localtime_r() are not Async-Signal-Safe functions, therefore,
+ * they must not be called by a signal handler, so we use the cached
+ * GMT offset value. Fortunately the value is changed only two times a year.
+ */
+
+static ngx_int_t cached_gmtoff;
+#endif
+
static ngx_time_t cached_time[NGX_TIME_SLOTS];
static u_char cached_err_log_time[NGX_TIME_SLOTS]
[sizeof("1970/09/28 12:00:00")];
ngx_cached_time = &cached_time[0];
- ngx_time_update(0, 0);
+ ngx_time_update();
}
void
-ngx_time_update(time_t sec, ngx_uint_t msec)
+ngx_time_update(void)
{
u_char *p0, *p1, *p2;
ngx_tm_t tm, gmt;
+ time_t sec;
+ ngx_uint_t msec;
ngx_time_t *tp;
struct timeval tv;
return;
}
- if (sec == 0) {
- ngx_gettimeofday(&tv);
+ ngx_gettimeofday(&tv);
- sec = tv.tv_sec;
- msec = tv.tv_usec / 1000;
- }
+ sec = tv.tv_sec;
+ msec = tv.tv_usec / 1000;
ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;
#elif (NGX_HAVE_GMTOFF)
ngx_localtime(sec, &tm);
- tp->gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
+ cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
+ tp->gmtoff = cached_gmtoff;
#else
ngx_localtime(sec, &tm);
- tp->gmtoff = ngx_timezone(tm.ngx_tm_isdst);
+ cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst);
+ tp->gmtoff = cached_gmtoff;
#endif
}
+#if !(NGX_WIN32)
+
+void
+ngx_time_sigsafe_update(void)
+{
+ u_char *p;
+ ngx_tm_t tm;
+ time_t sec;
+ ngx_time_t *tp;
+ struct timeval tv;
+
+ if (!ngx_trylock(&ngx_time_lock)) {
+ return;
+ }
+
+ ngx_gettimeofday(&tv);
+
+ sec = tv.tv_sec;
+
+ tp = &cached_time[slot];
+
+ if (tp->sec == sec) {
+ ngx_unlock(&ngx_time_lock);
+ return;
+ }
+
+ if (slot == NGX_TIME_SLOTS - 1) {
+ slot = 0;
+ } else {
+ slot++;
+ }
+
+ ngx_gmtime(sec + cached_gmtoff * 60, &tm);
+
+ p = &cached_err_log_time[slot][0];
+
+ (void) ngx_sprintf(p, "%4d/%02d/%02d %02d:%02d:%02d",
+ tm.ngx_tm_year, tm.ngx_tm_mon,
+ tm.ngx_tm_mday, tm.ngx_tm_hour,
+ tm.ngx_tm_min, tm.ngx_tm_sec);
+
+ ngx_memory_barrier();
+
+ ngx_cached_err_log_time.data = p;
+
+ ngx_unlock(&ngx_time_lock);
+}
+
+#endif
+
+
u_char *
ngx_http_time(u_char *buf, time_t t)
{
void ngx_time_init(void);
-void ngx_time_update(time_t sec, ngx_uint_t msec);
+void ngx_time_update(void);
+void ngx_time_sigsafe_update(void);
u_char *ngx_http_time(u_char *buf, time_t t);
u_char *ngx_http_cookie_time(u_char *buf, time_t t);
void ngx_gmtime(time_t t, ngx_tm_t *tp);
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
if (err) {
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
if (err) {
err = ngx_errno;
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
if (n == -1) {
for (i = 0; i < events; i++) {
if (event_list[i].portev_source == PORT_SOURCE_TIMER) {
- ngx_time_update(0, 0);
+ ngx_time_update();
continue;
}
for ( ;; ) {
Sleep(timer);
- ngx_time_update(0, 0);
+ ngx_time_update();
#if 1
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer");
#endif
delta = ngx_current_msec;
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
ngx_log_debug4(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
#if (NGX_HAVE_TIMER_EVENT)
if (event_list[i].filter == EVFILT_TIMER) {
- ngx_time_update(0, 0);
+ ngx_time_update();
continue;
}
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
ngx_log_debug2(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"rtsig signo:%d", signo);
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
if (err == NGX_EAGAIN) {
signo, si.si_fd, si.si_band);
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
rtscf = ngx_event_get_conf(ngx_cycle->conf_ctx, ngx_rtsig_module);
} else if (signo == SIGALRM) {
- ngx_time_update(0, 0);
+ ngx_time_update();
return NGX_OK;
}
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
ngx_log_error(NGX_LOG_ALERT, cycle->log, 0,
err = 0;
}
- if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ if (flags & NGX_UPDATE_TIME || ngx_event_timer_alarm) {
+ ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
}
if (flags & NGX_UPDATE_TIME) {
- ngx_time_update(0, 0);
+ ngx_time_update();
}
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
{
ngx_event_timer_alarm = 1;
- ngx_time_update(0, 0);
-
#if 1
ngx_log_debug0(NGX_LOG_DEBUG_EVENT, ngx_cycle->log, 0, "timer signal");
#endif
if (cache->files++ > 100) {
- ngx_time_update(0, 0);
+ ngx_time_update();
elapsed = ngx_abs((ngx_msec_int_t) (ngx_current_msec - cache->last));
ngx_msleep(200);
- ngx_time_update(0, 0);
+ ngx_time_update();
}
cache->last = ngx_current_msec;
/* Solaris and Tru64 UNIX have thread-safe strerror() */
-#define ngx_strerror_r(err, errstr, size) \
+#define ngx_strerror_r(err, errstr, size) \
ngx_cpystrn(errstr, (u_char *) strerror(err), size)
#endif
+#if (NGX_HAVE_SYS_ERRLIST)
+
+#define ngx_sigsafe_strerror(err) \
+ (err > 0 && err < sys_nerr) ? sys_errlist[err] : "Unknown error"
+
+#else
+
+#define ngx_sigsafe_strerror(err) ""
+
+#endif
+
+
#endif /* _NGX_ERRNO_H_INCLUDED_ */
}
}
- ngx_time_update(0, 0);
+ ngx_time_sigsafe_update();
action = "";
*/
if (err == NGX_ECHILD) {
- ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, errno,
- "waitpid() failed");
+ ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
+ "waitpid() failed (%d: %s)",
+ err, ngx_sigsafe_strerror(err));
return;
}
#endif
- ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, errno,
- "waitpid() failed");
-
+ ngx_log_error(NGX_LOG_ALERT, ngx_cycle->log, 0,
+ "waitpid() failed (%d: %s)",
+ err, ngx_sigsafe_strerror(err));
return;
}
sigsuspend(&set);
- ngx_time_update(0, 0);
+ ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_EVENT, cycle->log, 0,
"wake up, sigio %i", sigio);
next = (n <= next) ? n : next;
- ngx_time_update(0, 0);
+ ngx_time_update();
}
}
if (path[i]->loader) {
path[i]->loader(path[i]->data);
- ngx_time_update(0, 0);
+ ngx_time_update();
}
}
rc = WaitForMultipleObjects(2, events, 0, 5000);
- ngx_time_update(0, 0);
+ ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
"WaitForMultipleObjects: %ul", rc);
ev = WaitForMultipleObjects(nev, events, 0, timeout);
err = ngx_errno;
- ngx_time_update(0, 0);
+ ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
"master WaitForMultipleObjects: %ul", ev);
ev = WaitForMultipleObjects(3, events, 0, INFINITE);
err = ngx_errno;
- ngx_time_update(0, 0);
+ ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
"worker WaitForMultipleObjects: %ul", ev);
ev = WaitForMultipleObjects(nev, events, 0, INFINITE);
err = ngx_errno;
- ngx_time_update(0, 0);
+ ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_CORE, log, 0,
"worker exit WaitForMultipleObjects: %ul", ev);
ev = WaitForMultipleObjects(2, events, 0, INFINITE);
err = ngx_errno;
- ngx_time_update(0, 0);
+ ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_CORE, cycle->log, 0,
"cache manager WaitForMultipleObjects: %ul", ev);
next = (n <= next) ? n : next;
- ngx_time_update(0, 0);
+ ngx_time_update();
}
}
if (ev != WAIT_TIMEOUT) {
- ngx_time_update(0, 0);
+ ngx_time_update();
ngx_log_debug1(NGX_LOG_DEBUG_CORE, ngx_cycle->log, 0,
"cache manager WaitForSingleObject: %ul", ev);
if (path[i]->loader) {
path[i]->loader(path[i]->data);
- ngx_time_update(0, 0);
+ ngx_time_update();
}
}