ioloop.c (dovecot-2.3.16) | : | ioloop.c (dovecot-2.3.17) | ||
---|---|---|---|---|
skipping to change at line 13 | skipping to change at line 13 | |||
#include "lib.h" | #include "lib.h" | |||
#include "array.h" | #include "array.h" | |||
#include "backtrace-string.h" | #include "backtrace-string.h" | |||
#include "llist.h" | #include "llist.h" | |||
#include "time-util.h" | #include "time-util.h" | |||
#include "istream-private.h" | #include "istream-private.h" | |||
#include "ioloop-private.h" | #include "ioloop-private.h" | |||
#include <unistd.h> | #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; | time_t ioloop_time = 0; | |||
struct timeval ioloop_timeval; | struct timeval ioloop_timeval; | |||
struct ioloop *current_ioloop = NULL; | struct ioloop *current_ioloop = NULL; | |||
uint64_t ioloop_global_wait_usecs = 0; | uint64_t ioloop_global_wait_usecs = 0; | |||
static ARRAY(io_switch_callback_t *) io_switch_callbacks = ARRAY_INIT; | static ARRAY(io_switch_callback_t *) io_switch_callbacks = ARRAY_INIT; | |||
static ARRAY(io_destroy_callback_t *) io_destroy_callbacks = ARRAY_INIT; | static ARRAY(io_destroy_callback_t *) io_destroy_callbacks = ARRAY_INIT; | |||
static bool panic_on_leak = FALSE, panic_on_leak_set = FALSE; | static bool panic_on_leak = FALSE, panic_on_leak_set = FALSE; | |||
static time_t data_stack_last_free_unused = 0; | static time_t data_stack_last_free_unused = 0; | |||
skipping to change at line 473 | skipping to change at line 482 | |||
if (tv_r->tv_sec < 0) { | if (tv_r->tv_sec < 0) { | |||
/* The timeout should have been called already */ | /* The timeout should have been called already */ | |||
tv_r->tv_sec = 0; | tv_r->tv_sec = 0; | |||
tv_r->tv_usec = 0; | tv_r->tv_usec = 0; | |||
return 0; | return 0; | |||
} | } | |||
if (tv_r->tv_sec == 0 && tv_r->tv_usec == 1 && !in_timeout_loop) { | if (tv_r->tv_sec == 0 && tv_r->tv_usec == 1 && !in_timeout_loop) { | |||
/* Possibly 0 ms timeout. Don't wait for a full millisecond | /* Possibly 0 ms timeout. Don't wait for a full millisecond | |||
for it to trigger. */ | for it to trigger. */ | |||
tv_r->tv_usec = 0; | ||||
return 0; | return 0; | |||
} | } | |||
if (tv_r->tv_sec > INT_MAX/1000-1) | if (tv_r->tv_sec > INT_MAX/1000-1) | |||
tv_r->tv_sec = INT_MAX/1000-1; | tv_r->tv_sec = INT_MAX/1000-1; | |||
/* round wait times up to next millisecond */ | /* round wait times up to next millisecond */ | |||
ret = tv_r->tv_sec * 1000 + (tv_r->tv_usec + 999) / 1000; | ret = tv_r->tv_sec * 1000 + (tv_r->tv_usec + 999) / 1000; | |||
i_assert(ret >= 0 && tv_r->tv_sec >= 0 && tv_r->tv_usec >= 0); | i_assert(ret >= 0 && tv_r->tv_sec >= 0 && tv_r->tv_usec >= 0); | |||
return ret; | return ret; | |||
} | } | |||
skipping to change at line 649 | skipping to change at line 659 | |||
if (unlikely(diff_usecs < 0)) { | if (unlikely(diff_usecs < 0)) { | |||
/* time moved backwards */ | /* time moved backwards */ | |||
io_loops_timeouts_update(diff_usecs); | io_loops_timeouts_update(diff_usecs); | |||
ioloop->time_moved_callback(&tv_old, &ioloop_timeval); | ioloop->time_moved_callback(&tv_old, &ioloop_timeval); | |||
i_assert(ioloop == current_ioloop); | i_assert(ioloop == current_ioloop); | |||
/* the callback may have slept, so check the time again. */ | /* the callback may have slept, so check the time again. */ | |||
i_gettimeofday(&ioloop_timeval); | i_gettimeofday(&ioloop_timeval); | |||
} else { | } else { | |||
diff_usecs = timeval_diff_usecs(&ioloop->next_max_time, | diff_usecs = timeval_diff_usecs(&ioloop->next_max_time, | |||
&ioloop_timeval); | &ioloop_timeval); | |||
if (unlikely(diff_usecs < 0)) { | if (unlikely(-diff_usecs >= IOLOOP_TIME_MOVED_FORWARDS_MIN_USECS) ) { | |||
io_loops_timeouts_update(-diff_usecs); | io_loops_timeouts_update(-diff_usecs); | |||
/* time moved forwards */ | /* time moved forwards */ | |||
ioloop->time_moved_callback(&ioloop->next_max_time, | ioloop->time_moved_callback(&ioloop->next_max_time, | |||
&ioloop_timeval); | &ioloop_timeval); | |||
i_assert(ioloop == current_ioloop); | i_assert(ioloop == current_ioloop); | |||
} | } | |||
ioloop_add_wait_time(ioloop); | ioloop_add_wait_time(ioloop); | |||
} | } | |||
ioloop_time = ioloop_timeval.tv_sec; | ioloop_time = ioloop_timeval.tv_sec; | |||
End of changes. 3 change blocks. | ||||
1 lines changed or deleted | 11 lines changed or added |