diff src/core/ngx_times.c @ 3474:d4c4cfdffe30

*) 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
author Igor Sysoev <igor@sysoev.ru>
date Sat, 13 Mar 2010 18:08:07 +0000
parents bf38420c9e25
children ab353d7dc182
line wrap: on
line diff
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -28,6 +28,17 @@ volatile ngx_str_t       ngx_cached_err_
 volatile ngx_str_t       ngx_cached_http_time;
 volatile ngx_str_t       ngx_cached_http_log_time;
 
+#if !(NGX_HAVE_GETTIMEZONE)
+
+/*
+ * locatime() and localtime_r() are not Async-Signal-Safe functions, therefore,
+ * if ngx_time_update() is called by signal handler, it uses 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")];
@@ -50,15 +61,17 @@ ngx_time_init(void)
 
     ngx_cached_time = &cached_time[0];
 
-    ngx_time_update(0, 0);
+    ngx_time_update(0);
 }
 
 
 void
-ngx_time_update(time_t sec, ngx_uint_t msec)
+ngx_time_update(ngx_uint_t use_cached_gmtoff)
 {
     u_char          *p0, *p1, *p2;
     ngx_tm_t         tm, gmt;
+    time_t           sec;
+    ngx_uint_t       msec;
     ngx_time_t      *tp;
     struct timeval   tv;
 
@@ -66,12 +79,10 @@ ngx_time_update(time_t sec, ngx_uint_t m
         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;
 
@@ -109,15 +120,23 @@ ngx_time_update(time_t sec, ngx_uint_t m
     tp->gmtoff = ngx_gettimezone();
     ngx_gmtime(sec + tp->gmtoff * 60, &tm);
 
-#elif (NGX_HAVE_GMTOFF)
-
-    ngx_localtime(sec, &tm);
-    tp->gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
-
 #else
 
-    ngx_localtime(sec, &tm);
-    tp->gmtoff = ngx_timezone(tm.ngx_tm_isdst);
+    if (use_cached_gmtoff) {
+        ngx_gmtime(sec + cached_gmtoff * 60, &tm);
+
+    } else {
+        ngx_localtime(sec, &tm);
+
+#if (NGX_HAVE_GMTOFF)
+        cached_gmtoff = (ngx_int_t) (tm.ngx_tm_gmtoff / 60);
+#else
+        cached_gmtoff = ngx_timezone(tm.ngx_tm_isdst);
+#endif
+
+    }
+
+    tp->gmtoff = cached_gmtoff;
 
 #endif