diff --git a/src/unix/core.c b/src/unix/core.c index 10f6f70bd..6f284ffa7 100644 --- a/src/unix/core.c +++ b/src/unix/core.c @@ -74,7 +74,7 @@ #include #endif -static void uv__run_pending(uv_loop_t* loop); +static int uv__run_pending(uv_loop_t* loop); /* Verify that uv_buf_t is ABI-compatible with struct iovec. */ STATIC_ASSERT(sizeof(uv_buf_t) == sizeof(struct iovec)); @@ -304,6 +304,7 @@ int uv_loop_alive(const uv_loop_t* loop) { int uv_run(uv_loop_t* loop, uv_run_mode mode) { int timeout; int r; + int ran_pending; r = uv__loop_alive(loop); if (!r) @@ -312,12 +313,12 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) { while (r != 0 && loop->stop_flag == 0) { uv__update_time(loop); uv__run_timers(loop); - uv__run_pending(loop); + ran_pending = uv__run_pending(loop); uv__run_idle(loop); uv__run_prepare(loop); timeout = 0; - if (mode != UV_RUN_NOWAIT) + if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) timeout = uv_backend_timeout(loop); uv__io_poll(loop, timeout); @@ -693,10 +694,13 @@ int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { } -static void uv__run_pending(uv_loop_t* loop) { +static int uv__run_pending(uv_loop_t* loop) { QUEUE* q; 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_REMOVE(q); @@ -705,6 +709,8 @@ static void uv__run_pending(uv_loop_t* loop) { w = QUEUE_DATA(q, uv__io_t, pending_queue); w->cb(loop, w, UV__POLLOUT); } + + return 1; } diff --git a/src/win/core.c b/src/win/core.c index 23d6561ce..2bef8b7f3 100644 --- a/src/win/core.c +++ b/src/win/core.c @@ -387,6 +387,7 @@ int uv_loop_alive(const uv_loop_t* loop) { int uv_run(uv_loop_t *loop, uv_run_mode mode) { DWORD timeout; int r; + int ran_pending; void (*poll)(uv_loop_t* loop, DWORD timeout); if (pGetQueuedCompletionStatusEx) @@ -402,12 +403,12 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) { uv_update_time(loop); uv_process_timers(loop); - uv_process_reqs(loop); + ran_pending = uv_process_reqs(loop); uv_idle_invoke(loop); uv_prepare_invoke(loop); timeout = 0; - if (mode != UV_RUN_NOWAIT) + if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) timeout = uv_backend_timeout(loop); (*poll)(loop, timeout); diff --git a/src/win/req-inl.h b/src/win/req-inl.h index 97342e5c7..46c7d9b10 100644 --- a/src/win/req-inl.h +++ b/src/win/req-inl.h @@ -130,14 +130,13 @@ INLINE static void uv_insert_pending_req(uv_loop_t* loop, uv_req_t* req) { } while (0) -INLINE static void uv_process_reqs(uv_loop_t* loop) { +INLINE static int uv_process_reqs(uv_loop_t* loop) { uv_req_t* req; uv_req_t* first; uv_req_t* next; - if (loop->pending_reqs_tail == NULL) { - return; - } + if (loop->pending_reqs_tail == NULL) + return 0; first = loop->pending_reqs_tail->next_req; next = first; @@ -207,6 +206,8 @@ INLINE static void uv_process_reqs(uv_loop_t* loop) { assert(0); } } + + return 1; } #endif /* UV_WIN_REQ_INL_H_ */