From 3ceb260c654cb861bb1337bbe37948254312fbf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Wed, 27 May 2015 11:36:02 +0200 Subject: [PATCH] unix: prevent infinite loop in uv__run_pending If any of the callbacks called in uv__run_pending calls uv__io_feed we enter an infinite loop, because we add the handle to the same queue we are iterating over. Refs: https://github.com/libuv/libuv/issues/301 PR-URL: https://github.com/libuv/libuv/pull/371 Reviewed-By: Ben Noordhuis --- src/unix/core.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/unix/core.c b/src/unix/core.c index 0777c15c..37d1df78 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -700,16 +700,20 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { static int uv__run_pending(uv_loop_t* loop) { QUEUE* q; + QUEUE pq; uv__io_t* w; if (QUEUE_EMPTY(&loop->pending_queue)) return 0; - while (!QUEUE_EMPTY(&loop->pending_queue)) { - q = QUEUE_HEAD(&loop->pending_queue); + QUEUE_INIT(&pq); + q = QUEUE_HEAD(&loop->pending_queue); + QUEUE_SPLIT(&loop->pending_queue, q, &pq); + + while (!QUEUE_EMPTY(&pq)) { + q = QUEUE_HEAD(&pq); QUEUE_REMOVE(q); QUEUE_INIT(q); - w = QUEUE_DATA(q, uv__io_t, pending_queue); w->cb(loop, w, UV__POLLOUT); }