diff options
author | antirez <antirez@gmail.com> | 2017-07-11 00:13:52 +0200 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2017-07-11 00:13:52 +0200 |
commit | 54e4bbeabdd1cd92e5c2b461f85c6c03d8645838 (patch) | |
tree | 9cd9d8021aeab6dd2cd7242d08cc3b8bf84549a0 /src/ae.c | |
parent | 11182a1a58ef6d36f76f7a5e06d0598254b524d9 (diff) | |
download | redis-54e4bbeabdd1cd92e5c2b461f85c6c03d8645838.tar.gz |
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.
Diffstat (limited to 'src/ae.c')
-rw-r--r-- | src/ae.c | 5 |
1 files changed, 3 insertions, 2 deletions
@@ -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); } } |