summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaxim Dounin <mdounin@mdounin.ru>2018-03-01 20:25:50 +0300
committerMaxim Dounin <mdounin@mdounin.ru>2018-03-01 20:25:50 +0300
commitc7e8a6f2123c653b63ed8013a805eddff502b9ee (patch)
tree1b4dd1cd6c27935fbadb2b4a00a514e0a27bdce0
parent6e30556127157ddf04e925480ce1e0ef9df2ca0a (diff)
downloadnginx-c7e8a6f2123c653b63ed8013a805eddff502b9ee.tar.gz
Core: ngx_current_msec now uses monotonic time if available.
When clock_gettime(CLOCK_MONOTONIC) (or faster variants, _FAST on FreeBSD, and _COARSE on Linux) is available, we now use it for ngx_current_msec. This should improve handling of timers if system time changes (ticket #189).
-rw-r--r--auto/unix24
-rw-r--r--src/core/ngx_times.c30
2 files changed, 53 insertions, 1 deletions
diff --git a/auto/unix b/auto/unix
index 3be8b27a5..90b5894a3 100644
--- a/auto/unix
+++ b/auto/unix
@@ -791,6 +791,30 @@ ngx_feature_test="struct tm t; time_t c=0; localtime_r(&c, &t)"
. auto/feature
+ngx_feature="clock_gettime(CLOCK_MONOTONIC)"
+ngx_feature_name="NGX_HAVE_CLOCK_MONOTONIC"
+ngx_feature_run=no
+ngx_feature_incs="#include <time.h>"
+ngx_feature_path=
+ngx_feature_libs=
+ngx_feature_test="struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts)"
+. auto/feature
+
+
+if [ $ngx_found = no ]; then
+
+ # Linux before glibc 2.17, notably CentOS 6
+
+ ngx_feature="clock_gettime(CLOCK_MONOTONIC) in librt"
+ ngx_feature_libs="-lrt"
+ . auto/feature
+
+ if [ $ngx_found = yes ]; then
+ CORE_LIBS="$CORE_LIBS -lrt"
+ fi
+fi
+
+
ngx_feature="posix_memalign()"
ngx_feature_name="NGX_HAVE_POSIX_MEMALIGN"
ngx_feature_run=no
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index b2edf1a5f..7964b008f 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -9,6 +9,9 @@
#include <ngx_core.h>
+static ngx_msec_t ngx_monotonic_time(time_t sec, ngx_uint_t msec);
+
+
/*
* The time may be updated by signal handler or by several threads.
* The time update operations are rare and require to hold the ngx_time_lock.
@@ -93,7 +96,7 @@ ngx_time_update(void)
sec = tv.tv_sec;
msec = tv.tv_usec / 1000;
- ngx_current_msec = (ngx_msec_t) sec * 1000 + msec;
+ ngx_current_msec = ngx_monotonic_time(sec, msec);
tp = &cached_time[slot];
@@ -189,6 +192,31 @@ ngx_time_update(void)
}
+static ngx_msec_t
+ngx_monotonic_time(time_t sec, ngx_uint_t msec)
+{
+#if (NGX_HAVE_CLOCK_MONOTONIC)
+ struct timespec ts;
+
+#if defined(CLOCK_MONOTONIC_FAST)
+ clock_gettime(CLOCK_MONOTONIC_FAST, &ts);
+
+#elif defined(CLOCK_MONOTONIC_COARSE)
+ clock_gettime(CLOCK_MONOTONIC_COARSE, &ts);
+
+#else
+ clock_gettime(CLOCK_MONOTONIC, &ts);
+#endif
+
+ sec = ts.tv_sec;
+ msec = ts.tv_nsec / 1000000;
+
+#endif
+
+ return (ngx_msec_t) sec * 1000 + msec;
+}
+
+
#if !(NGX_WIN32)
void