Skip to content

Instantly share code, notes, and snippets.

@antirez
Created January 8, 2016 09:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save antirez/628f3c9ee86bdf6c1270 to your computer and use it in GitHub Desktop.
Save antirez/628f3c9ee86bdf6c1270 to your computer and use it in GitHub Desktop.
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