diff --git a/src/ae.c b/src/ae.c index 28b50c660..b6a1ce0b1 100644 --- a/src/ae.c +++ b/src/ae.c @@ -183,7 +183,9 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) { * is removed. */ if (mask & AE_WRITABLE) mask |= AE_BARRIER; - aeApiDelEvent(eventLoop, fd, mask); + /* Only remove attached events */ + mask = mask & fe->mask; + fe->mask = fe->mask & (~mask); if (fd == eventLoop->maxfd && fe->mask == AE_NONE) { /* Update the max fd */ @@ -193,6 +195,15 @@ void aeDeleteFileEvent(aeEventLoop *eventLoop, int fd, int mask) { if (eventLoop->events[j].mask != AE_NONE) break; eventLoop->maxfd = j; } + + /* Check whether there are events to be removed. + * Note: user may remove the AE_BARRIER without + * touching the actual events. */ + if (mask & (AE_READABLE | AE_WRITABLE)) { + /* Must be invoked after the eventLoop mask is modified, + * which is required by evport and epoll */ + aeApiDelEvent(eventLoop, fd, mask); + } } void *aeGetFileClientData(aeEventLoop *eventLoop, int fd) { diff --git a/src/ae_epoll.c b/src/ae_epoll.c index 78820b99b..c8b4ac743 100644 --- a/src/ae_epoll.c +++ b/src/ae_epoll.c @@ -87,10 +87,12 @@ static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) { return 0; } -static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) { +static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) { aeApiState *state = eventLoop->apidata; struct epoll_event ee = {0}; /* avoid valgrind warning */ - int mask = eventLoop->events[fd].mask & (~delmask); + + /* We rely on the fact that our caller has already updated the mask in the eventLoop. */ + mask = eventLoop->events[fd].mask; ee.events = 0; if (mask & AE_READABLE) ee.events |= EPOLLIN;