linux: fix abort() on epoll_ctl() race condition

Don't check the return value of epoll_ctl(EPOLL_CTL_DEL). When the
file descriptor is closed, we're potentially racing with another
thread and that means the errno is not a reliable indicator of
the actual error.

The other event mechanisms (kqueue, event ports) are not affected
because:

* kqueue returns either EBADF or ENOENT. Both are handled by libuv.
* event ports rearms all file descriptors on each call to port_getn().

Fixes joyent/node#4558.
This commit is contained in:
Ben Noordhuis 2013-02-20 21:05:38 +01:00
parent fd24a69c52
commit 26fa6f8031

View File

@ -218,11 +218,12 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
w = loop->watchers[fd];
if (w == NULL) {
/* File descriptor that we've stopped watching, disarm it. */
if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, pe))
if (errno != EBADF && errno != ENOENT)
abort();
/* File descriptor that we've stopped watching, disarm it.
*
* Ignore all errors because we may be racing with another thread
* when the file descriptor is closed.
*/
uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, pe);
continue;
}