]> git.saurik.com Git - redis.git/blobdiff - src/ae.c
Merge pull request #544 from dvirsky/2.6
[redis.git] / src / ae.c
index ba53b456805ad3b33910f96e57a2a2e8490cddd2..d2faed326307f8ea12fdb5c718a676b7c6c257a9 100644 (file)
--- a/src/ae.c
+++ b/src/ae.c
@@ -37,6 +37,7 @@
 #include <stdlib.h>
 #include <poll.h>
 #include <string.h>
+#include <time.h>
 
 #include "ae.h"
 #include "zmalloc.h"
@@ -67,6 +68,7 @@ aeEventLoop *aeCreateEventLoop(int setsize) {
     eventLoop->fired = zmalloc(sizeof(aeFiredEvent)*setsize);
     if (eventLoop->events == NULL || eventLoop->fired == NULL) goto err;
     eventLoop->setsize = setsize;
+    eventLoop->lastTime = time(NULL);
     eventLoop->timeEventHead = NULL;
     eventLoop->timeEventNextId = 0;
     eventLoop->stop = 0;
@@ -236,6 +238,24 @@ static int processTimeEvents(aeEventLoop *eventLoop) {
     int processed = 0;
     aeTimeEvent *te;
     long long maxId;
+    time_t now = time(NULL);
+
+    /* If the system clock is moved to the future, and then set back to the
+     * right value, time events may be delayed in a random way. Often this
+     * means that scheduled operations will not be performed soon enough.
+     *
+     * Here we try to detect system clock skews, and force all the time
+     * events to be processed ASAP when this happens: the idea is that
+     * processing events earlier is less dangerous than delaying them
+     * indefinitely, and practice suggests it is. */
+    if (now < eventLoop->lastTime) {
+        te = eventLoop->timeEventHead;
+        while(te) {
+            te->when_sec = 0;
+            te = te->next;
+        }
+    }
+    eventLoop->lastTime = now;
 
     te = eventLoop->timeEventHead;
     maxId = eventLoop->timeEventNextId-1;