]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: ioloop - Handle "time moved forwards" only after 100ms difference
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 4 Aug 2021 16:52:14 +0000 (19:52 +0300)
committerTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 4 Aug 2021 16:59:17 +0000 (19:59 +0300)
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

src/lib/ioloop.c

index 5aa4731dc410f35e07755c683bba1d3708242938..db68b7e4549783163192f66aa780ca15b3d14e8e 100644 (file)
 
 #include <unistd.h>
 
+/* 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,