From ce56a85b19e13287d2613f8de33f479a9c1104b5 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Tue, 8 Aug 2017 15:30:42 +0200 Subject: [PATCH] unix: make uv_poll_stop() remove fd from pollset Avoid repeated wake-ups in `uv__io_poll()` when the previously watched file descriptor has been duplicated (with `dup(2)`) and then closed. Because epoll reports events for _file descriptions_ rather than _file descriptors_, events on the duplicated file descriptor cause the event loop to wake up. Libuv then tries to unregister the event listener for the original file descriptor but that fails with EBADF because the file descriptor is closed. Since libuv uses epoll in level-triggered mode, it effectively results in a busy loop because the event is re-reported as soon as libuv calls epoll_wait() again. I tried hard to write a test case for this but there is no directly observable behavior, only increased CPU usuage. Fixes: https://github.com/libuv/libuv/issues/1148 PR-URL: https://github.com/libuv/libuv/pull/1468 Reviewed-By: Colin Ihrig --- src/unix/poll.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/unix/poll.c b/src/unix/poll.c index 2001fc8c..816c7dc2 100644 --- a/src/unix/poll.c +++ b/src/unix/poll.c @@ -101,6 +101,7 @@ static void uv__poll_stop(uv_poll_t* handle) { &handle->io_watcher, POLLIN | POLLOUT | UV__POLLRDHUP | UV__POLLPRI); uv__handle_stop(handle); + uv__platform_invalidate_fd(handle->loop, handle->io_watcher.fd); }