From: Stephan Bosch Date: Sun, 16 Dec 2018 12:55:34 +0000 (+0100) Subject: lib: ioloop: Make the callback for io_loop_set_time_moved_callback() use struct timeval. X-Git-Tag: 2.3.8~204 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ece5fc77126b7226cae46a9c86bed56573af7adc;p=thirdparty%2Fdovecot%2Fcore.git lib: ioloop: Make the callback for io_loop_set_time_moved_callback() use struct timeval. This allows reporting sub-second glitches. --- diff --git a/src/lib-storage/mail-storage-service.c b/src/lib-storage/mail-storage-service.c index fd4dfcc9ae..14ee82390b 100644 --- a/src/lib-storage/mail-storage-service.c +++ b/src/lib-storage/mail-storage-service.c @@ -900,9 +900,11 @@ mail_storage_service_init_log(struct mail_storage_service_ctx *ctx, i_set_failure_send_prefix(user->log_prefix); } -static void mail_storage_service_time_moved(time_t old_time, time_t new_time) +static void +mail_storage_service_time_moved(const struct timeval *old_time, + const struct timeval *new_time) { - long diff = new_time - old_time; + long diff = new_time->tv_sec - old_time->tv_sec; if (diff > 0) { if (diff > MAX_NOWARN_FORWARD_SECS) @@ -927,7 +929,7 @@ static void mail_storage_service_time_moved(time_t old_time, time_t new_time) /* don't use sleep()'s return value, because it could get us to a long loop in case interrupts just keep coming */ - diff = old_time - time(NULL) + 1; + diff = old_time->tv_sec - time(NULL) + 1; } } } diff --git a/src/lib/ioloop.c b/src/lib/ioloop.c index 6f1ab7b86e..20016eac1a 100644 --- a/src/lib/ioloop.c +++ b/src/lib/ioloop.c @@ -550,11 +550,14 @@ static int timeout_cmp(const void *p1, const void *p2) return timeval_cmp(&to1->next_run, &to2->next_run); } -static void io_loop_default_time_moved(time_t old_time, time_t new_time) +static void +io_loop_default_time_moved(const struct timeval *old_time, + const struct timeval *new_time) { - if (old_time > new_time) { - i_warning("Time moved backwards by %ld seconds.", - (long)(old_time - new_time)); + long long diff = timeval_diff_usecs(old_time, new_time); + if (diff > 0) { + i_warning("Time moved backwards by %lld.%06lld seconds.", + diff / 1000000, diff % 1000000); } } @@ -634,10 +637,7 @@ static void io_loop_handle_timeouts_real(struct ioloop *ioloop) if (unlikely(diff_usecs < 0)) { /* time moved backwards */ io_loops_timeouts_update(diff_usecs); - if (unlikely(ioloop_time > ioloop_timeval.tv_sec)) { - ioloop->time_moved_callback(ioloop_time, - ioloop_timeval.tv_sec); - } + ioloop->time_moved_callback(&tv_old, &ioloop_timeval); i_assert(ioloop == current_ioloop); /* the callback may have slept, so check the time again. */ if (gettimeofday(&ioloop_timeval, NULL) < 0) @@ -648,12 +648,8 @@ static void io_loop_handle_timeouts_real(struct ioloop *ioloop) if (unlikely(diff_usecs < 0)) { io_loops_timeouts_update(-diff_usecs); /* time moved forwards */ - if (unlikely(ioloop_timeval.tv_sec > - ioloop->next_max_time.tv_sec)) { - ioloop->time_moved_callback( - ioloop->next_max_time.tv_sec, - ioloop_timeval.tv_sec); - } + ioloop->time_moved_callback(&ioloop->next_max_time, + &ioloop_timeval); i_assert(ioloop == current_ioloop); } ioloop_add_wait_time(ioloop); diff --git a/src/lib/ioloop.h b/src/lib/ioloop.h index 5178d135f1..9f60b2f9d6 100644 --- a/src/lib/ioloop.h +++ b/src/lib/ioloop.h @@ -32,7 +32,8 @@ enum io_notify_result { typedef void io_callback_t(void *context); typedef void timeout_callback_t(void *context); -typedef void io_loop_time_moved_callback_t(time_t old_time, time_t new_time); +typedef void io_loop_time_moved_callback_t(const struct timeval *old_time, + const struct timeval *new_time); typedef void io_switch_callback_t(struct ioloop *prev_ioloop); /* Time when the I/O loop started calling handlers. diff --git a/src/master/main.c b/src/master/main.c index 869a2b612f..477a9fb09f 100644 --- a/src/master/main.c +++ b/src/master/main.c @@ -589,16 +589,18 @@ static const char *get_full_config_path(struct service_list *list) return p_strdup(list->pool, abspath); } -static void master_time_moved(time_t old_time, time_t new_time) +static void +master_time_moved(const struct timeval *old_time, + const struct timeval *new_time) { time_t secs; - if (new_time >= old_time) + if (new_time->tv_sec >= old_time->tv_sec) return; /* time moved backwards. disable launching new service processes until */ - secs = old_time - new_time + 1; + secs = old_time->tv_sec - new_time->tv_sec + 1; if (secs > SERVICE_TIME_MOVED_BACKWARDS_MAX_THROTTLE_SECS) secs = SERVICE_TIME_MOVED_BACKWARDS_MAX_THROTTLE_SECS; services_throttle_time_sensitives(services, secs);