From 54e4bbeabdd1cd92e5c2b461f85c6c03d8645838 Mon Sep 17 00:00:00 2001 From: antirez Date: Tue, 11 Jul 2017 00:13:52 +0200 Subject: [PATCH] Event loop: call after sleep() only from top level. In general we do not want before/after sleep() callbacks to be called when we re-enter the event loop, since those calls are only designed in order to perform operations every main iteration of the event loop, and re-entering is often just a way to incrementally serve clietns with error messages or other auxiliary operations. However, if we call the callbacks, we are then forced to think at before/after sleep callbacks as re-entrant, which is much harder without any good need. However here there was also a clear bug: beforeSleep() was actually never called when re-entering the event loop. But the new afterSleep() callback was. This is broken and in this instance re-entering afterSleep() caused a modules GIL dead lock. --- src/ae.c | 5 +++-- src/ae.h | 1 + 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ae.c b/src/ae.c index ecbaa94f..742388d8 100644 --- a/src/ae.c +++ b/src/ae.c @@ -344,6 +344,7 @@ static int processTimeEvents(aeEventLoop *eventLoop) { * if flags has AE_FILE_EVENTS set, file events are processed. * if flags has AE_TIME_EVENTS set, time events are processed. * if flags has AE_DONT_WAIT set the function returns ASAP until all + * if flags has AE_CALL_AFTER_SLEEP set, the aftersleep callback is called. * the events that's possible to process without to wait are processed. * * The function returns the number of events processed. */ @@ -403,7 +404,7 @@ int aeProcessEvents(aeEventLoop *eventLoop, int flags) numevents = aeApiPoll(eventLoop, tvp); /* After sleep callback. */ - if (eventLoop->aftersleep != NULL) + if (eventLoop->aftersleep != NULL && flags & AE_CALL_AFTER_SLEEP) eventLoop->aftersleep(eventLoop); for (j = 0; j < numevents; j++) { @@ -460,7 +461,7 @@ void aeMain(aeEventLoop *eventLoop) { while (!eventLoop->stop) { if (eventLoop->beforesleep != NULL) eventLoop->beforesleep(eventLoop); - aeProcessEvents(eventLoop, AE_ALL_EVENTS); + aeProcessEvents(eventLoop, AE_ALL_EVENTS|AE_CALL_AFTER_SLEEP); } } diff --git a/src/ae.h b/src/ae.h index e3617759..c49bfe23 100644 --- a/src/ae.h +++ b/src/ae.h @@ -46,6 +46,7 @@ #define AE_TIME_EVENTS 2 #define AE_ALL_EVENTS (AE_FILE_EVENTS|AE_TIME_EVENTS) #define AE_DONT_WAIT 4 +#define AE_CALL_AFTER_SLEEP 8 #define AE_NOMORE -1 #define AE_DELETED_EVENT_ID -1