From: Timo Sirainen Date: Wed, 4 Aug 2021 16:52:14 +0000 (+0300) Subject: lib: ioloop - Handle "time moved forwards" only after 100ms difference X-Git-Tag: 2.3.17~252 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=24216a4924d03756cb66f18f285ab8e8023b2e2a;p=thirdparty%2Fdovecot%2Fcore.git lib: ioloop - Handle "time moved forwards" only after 100ms difference Previously this was done after even a single microsecond difference, causing it to happen almost constantly. This was causing performance problems when there were many timeouts that had to be updated. Especially master process could have been spending a lot of time unnecessarily here. Broken by b258137d0e0618ae792e3606071a1715d26f107b --- diff --git a/src/lib/ioloop.c b/src/lib/ioloop.c index 5aa4731dc4..db68b7e454 100644 --- a/src/lib/ioloop.c +++ b/src/lib/ioloop.c @@ -10,6 +10,15 @@ #include +/* Dovecot attempts to detect also when time suddenly jumps forwards. + This is done by getting the minimum timeout wait in epoll() (or similar) + and then seeing if the current time after epoll() is past the timeout. + This can't be very exact, so likely the difference is always at least + 1 microsecond. In high load situations it can be somewhat higher. + Dovecot generally doesn't have very important short timeouts, so to avoid + logging many warnings about this, use a rather high value. */ +#define IOLOOP_TIME_MOVED_FORWARDS_MIN_USECS (100000) + time_t ioloop_time = 0; struct timeval ioloop_timeval; struct ioloop *current_ioloop = NULL; @@ -647,7 +656,7 @@ static void io_loop_handle_timeouts_real(struct ioloop *ioloop) } else { diff_usecs = timeval_diff_usecs(&ioloop->next_max_time, &ioloop_timeval); - if (unlikely(diff_usecs < 0)) { + if (unlikely(-diff_usecs >= IOLOOP_TIME_MOVED_FORWARDS_MIN_USECS)) { io_loops_timeouts_update(-diff_usecs); /* time moved forwards */ ioloop->time_moved_callback(&ioloop->next_max_time,