diff options
author | Maxim Dounin <mdounin@mdounin.ru> | 2018-03-01 20:25:50 +0300 |
---|---|---|
committer | Maxim Dounin <mdounin@mdounin.ru> | 2018-03-01 20:25:50 +0300 |
commit | c7e8a6f2123c653b63ed8013a805eddff502b9ee (patch) | |
tree | 1b4dd1cd6c27935fbadb2b4a00a514e0a27bdce0 | |
parent | 6e30556127157ddf04e925480ce1e0ef9df2ca0a (diff) | |
download | nginx-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/unix | 24 | ||||
-rw-r--r-- | src/core/ngx_times.c | 30 |
2 files changed, 53 insertions, 1 deletions
@@ -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 |