unix, windows: fix UV_RUN_ONCE mode if progress was made
If pending I/O callbacks were ran before polling, do a zero timeout poll. PR-URL: https://github.com/libuv/libuv/pull/58 Reviewed-By: Bert Belder <bertbelder@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This commit is contained in:
parent
e37a2a0d53
commit
e58dc26968
@ -74,7 +74,7 @@
|
||||
#include <sys/ioctl.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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_ */
|
||||
|
||||
Loading…
Reference in New Issue
Block a user