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 <info@bnoordhuis.nl>
This commit is contained in:
Saúl Ibarra Corretgé 2015-05-27 11:36:02 +02:00
parent 7005d29514
commit 3ceb260c65

View File

@ -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);
}