aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Noordhuis <info@bnoordhuis.nl>2017-08-08 15:30:42 +0200
committerBen Noordhuis <info@bnoordhuis.nl>2017-08-10 16:20:40 +0200
commitce56a85b19e13287d2613f8de33f479a9c1104b5 (patch)
tree775464f2cc9aefdf91cac5c9e88445e6b532cfbf
parent3af5512950bd6f3a0d386b0825cdd3e78a3e7f48 (diff)
downloadlibuv-ce56a85b19e13287d2613f8de33f479a9c1104b5.tar.gz
libuv-ce56a85b19e13287d2613f8de33f479a9c1104b5.zip
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 <cjihrig@gmail.com Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
-rw-r--r--src/unix/poll.c1
1 files changed, 1 insertions, 0 deletions
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);
}