Closed Math2 closed 1 year ago
IIUC, the selector can mistakenly assume that events for a certain FD are already being polled, but they aren't because the FD has been closed and reopened since last time.
Yeah, I saw some code in libev
which was trying to work around this.
Here are the notes:
/*
* general notes about epoll:
*
* a) epoll silently removes fds from the fd set. as nothing tells us
* that an fd has been removed otherwise, we have to continually
* "rearm" fds that we suspect *might* have changed (same
* problem with kqueue, but much less costly there).
* b) the fact that ADD != MOD creates a lot of extra syscalls due to a)
* and seems not to have any advantage.
* c) the inability to handle fork or file descriptors (think dup)
* limits the applicability over poll, so this is not a generic
* poll replacement.
* d) epoll doesn't work the same as select with many file descriptors
* (such as files). while not critical, no other advanced interface
* seems to share this (rather non-unixy) limitation.
* e) epoll claims to be embeddable, but in practise you never get
* a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32).
* f) epoll_ctl returning EPERM means the fd is always ready.
*
* lots of "weird code" and complication handling in this file is due
* to these design problems with epoll, as we try very hard to avoid
* epoll_ctl syscalls for common usage patterns and handle the breakage
* ensuing from receiving events for closed and otherwise long gone
* file descriptors.
*/
We might need to be more pessimistic about the cache.
Types of Changes
Contribution
Notes
I think I found another problem. Probably related to the "lazy disarming" optimization.
IIUC, the selector can mistakenly assume that events for a certain FD are already being polled, but they aren't because the FD has been closed and reopened since last time.
The test case works if you comment out
local.close
.I think it's triggering some other problem I was investigating, but not sure...