Created
January 8, 2016 09:26
-
-
Save antirez/628f3c9ee86bdf6c1270 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/src/ae.c b/src/ae.c | |
index 63a1ab4..79fcde6 100644 | |
--- a/src/ae.c | |
+++ b/src/ae.c | |
@@ -221,21 +221,12 @@ long long aeCreateTimeEvent(aeEventLoop *eventLoop, long long milliseconds, | |
int aeDeleteTimeEvent(aeEventLoop *eventLoop, long long id) | |
{ | |
- aeTimeEvent *te, *prev = NULL; | |
- | |
- te = eventLoop->timeEventHead; | |
+ aeTimeEvent *te = eventLoop->timeEventHead; | |
while(te) { | |
if (te->id == id) { | |
- if (prev == NULL) | |
- eventLoop->timeEventHead = te->next; | |
- else | |
- prev->next = te->next; | |
- if (te->finalizerProc) | |
- te->finalizerProc(eventLoop, te->clientData); | |
- zfree(te); | |
+ te->id = AE_DELETED_EVENT_ID; | |
return AE_OK; | |
} | |
- prev = te; | |
te = te->next; | |
} | |
return AE_ERR; /* NO event with the specified ID found */ | |
@@ -270,7 +261,7 @@ static aeTimeEvent *aeSearchNearestTimer(aeEventLoop *eventLoop) | |
/* Process time events */ | |
static int processTimeEvents(aeEventLoop *eventLoop) { | |
int processed = 0; | |
- aeTimeEvent *te; | |
+ aeTimeEvent *te, *prev; | |
long long maxId; | |
time_t now = time(NULL); | |
@@ -291,12 +282,28 @@ static int processTimeEvents(aeEventLoop *eventLoop) { | |
} | |
eventLoop->lastTime = now; | |
+ prev = NULL; | |
te = eventLoop->timeEventHead; | |
maxId = eventLoop->timeEventNextId-1; | |
while(te) { | |
long now_sec, now_ms; | |
long long id; | |
+ /* Remove events scheduled for deletion. */ | |
+ if (te->id == AE_DELETED_EVENT_ID) { | |
+ aeTimeEvent *next = te->next; | |
+ if (prev == NULL) | |
+ eventLoop->timeEventHead = te->next; | |
+ else | |
+ prev->next = te->next; | |
+ if (te->finalizerProc) | |
+ te->finalizerProc(eventLoop, te->clientData); | |
+ zfree(te); | |
+ te = next; | |
+ continue; | |
+ } | |
+ | |
+ /* Don't process time events created by time events in this iteration. */ | |
if (te->id > maxId) { | |
te = te->next; | |
continue; | |
@@ -310,28 +317,14 @@ static int processTimeEvents(aeEventLoop *eventLoop) { | |
id = te->id; | |
retval = te->timeProc(eventLoop, id, te->clientData); | |
processed++; | |
- /* After an event is processed our time event list may | |
- * no longer be the same, so we restart from head. | |
- * Still we make sure to don't process events registered | |
- * by event handlers itself in order to don't loop forever. | |
- * To do so we saved the max ID we want to handle. | |
- * | |
- * FUTURE OPTIMIZATIONS: | |
- * Note that this is NOT great algorithmically. Redis uses | |
- * a single time event so it's not a problem but the right | |
- * way to do this is to add the new elements on head, and | |
- * to flag deleted elements in a special way for later | |
- * deletion (putting references to the nodes to delete into | |
- * another linked list). */ | |
if (retval != AE_NOMORE) { | |
aeAddMillisecondsToNow(retval,&te->when_sec,&te->when_ms); | |
} else { | |
- aeDeleteTimeEvent(eventLoop, id); | |
+ te->id = AE_DELETED_EVENT_ID; | |
} | |
- te = eventLoop->timeEventHead; | |
- } else { | |
- te = te->next; | |
} | |
+ prev = te; | |
+ te = te->next; | |
} | |
return processed; | |
} | |
diff --git a/src/ae.h b/src/ae.h | |
index 15ca1b5..827c4c9 100644 | |
--- a/src/ae.h | |
+++ b/src/ae.h | |
@@ -33,6 +33,8 @@ | |
#ifndef __AE_H__ | |
#define __AE_H__ | |
+#include <time.h> | |
+ | |
#define AE_OK 0 | |
#define AE_ERR -1 | |
@@ -46,6 +48,7 @@ | |
#define AE_DONT_WAIT 4 | |
#define AE_NOMORE -1 | |
+#define AE_DELETED_EVENT_ID -1 | |
/* Macros */ | |
#define AE_NOTUSED(V) ((void) V) | |
diff --git a/src/anet.h b/src/anet.h | |
index 8740a95..7142f78 100644 | |
--- a/src/anet.h | |
+++ b/src/anet.h | |
@@ -31,6 +31,8 @@ | |
#ifndef ANET_H | |
#define ANET_H | |
+#include <sys/types.h> | |
+ | |
#define ANET_OK 0 | |
#define ANET_ERR -1 | |
#define ANET_ERR_LEN 256 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment