summaryrefslogtreecommitdiff
path: root/src/ae_epoll.c
diff options
context:
space:
mode:
authorOran Agra <oran@redislabs.com>2021-04-13 07:35:03 +0300
committerGitHub <noreply@github.com>2021-04-13 07:35:03 +0300
commit175a9e3199f79305827e826b5d2da3ed5d8a3502 (patch)
tree0bcc8ae49d33b75889d404d41f7a83c132c58c01 /src/ae_epoll.c
parent5e3a15ae1b58630a10639b34cd016ba9c0ff6b15 (diff)
downloadredis-175a9e3199f79305827e826b5d2da3ed5d8a3502.tar.gz
Fix busy loop in ae.c when timer event is about to fire (#8764)
The code used to decide on the next time to wake on a timer with microsecond accuracy, but when deciding to go to sleep it used milliseconds accuracy (with truncation), this means that it would wake up too early, see that there's no timer to process, and go to sleep again for 0ms again and again until the right microsecond arrived. i.e. a timer for 100ms, would sleep for 99ms, but then do a busy loop through the kernel in the last millisecond, triggering many calls to beforeSleep. The fix is to change all the logic in ae.c to work with microseconds, which is good since most of the ae backends support micro (or even nano) seconds. however the epoll backend, doesn't support micro, so to avoid this problem it needs to round upwards, rather than truncate. Issue created by the monotonic timer PR #7644 (redis 6.2) Before that, all the timers in ae.c were in milliseconds (using mstime), so when it requested the backend to sleep till the next timer event, it would have worked ok.
Diffstat (limited to 'src/ae_epoll.c')
-rw-r--r--src/ae_epoll.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/src/ae_epoll.c b/src/ae_epoll.c
index 07ca8ca41..023c93a17 100644
--- a/src/ae_epoll.c
+++ b/src/ae_epoll.c
@@ -111,7 +111,7 @@ static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
int retval, numevents = 0;
retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,
- tvp ? (tvp->tv_sec*1000 + tvp->tv_usec/1000) : -1);
+ tvp ? (tvp->tv_sec*1000 + (tvp->tv_usec + 999)/1000) : -1);
if (retval > 0) {
int j;