loop: add pending work to loop-alive check (#3466)
Pending work may be either (on any platform) pending_queue callbacks or (on unix) watcher_queue handles to add to the io poll object. Previously, we might have gotten somewhat stuck if the user caused an event to be added to one of these in the idle or prepare callbacks, or was embedding libuv. Refs: https://github.com/libuv/libuv/pull/3234 Refs: https://github.com/libuv/libuv/issues/3101 Refs: https://github.com/libuv/libuv/pull/3308
This commit is contained in:
parent
7a68f5ab4b
commit
939a05633f
@ -334,35 +334,36 @@ int uv_backend_fd(const uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
int uv_backend_timeout(const uv_loop_t* loop) {
|
||||
if (loop->stop_flag != 0)
|
||||
return 0;
|
||||
|
||||
if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
|
||||
return 0;
|
||||
|
||||
if (!QUEUE_EMPTY(&loop->idle_handles))
|
||||
return 0;
|
||||
|
||||
if (!QUEUE_EMPTY(&loop->pending_queue))
|
||||
return 0;
|
||||
|
||||
if (loop->closing_handles)
|
||||
return 0;
|
||||
|
||||
return uv__next_timeout(loop);
|
||||
}
|
||||
|
||||
|
||||
static int uv__loop_alive(const uv_loop_t* loop) {
|
||||
return uv__has_active_handles(loop) ||
|
||||
uv__has_active_reqs(loop) ||
|
||||
!QUEUE_EMPTY(&loop->pending_queue) ||
|
||||
loop->closing_handles != NULL;
|
||||
}
|
||||
|
||||
|
||||
static int uv__backend_timeout(const uv_loop_t* loop) {
|
||||
if (loop->stop_flag == 0 &&
|
||||
/* uv__loop_alive(loop) && */
|
||||
(uv__has_active_handles(loop) || uv__has_active_reqs(loop)) &&
|
||||
QUEUE_EMPTY(&loop->pending_queue) &&
|
||||
QUEUE_EMPTY(&loop->idle_handles) &&
|
||||
loop->closing_handles == NULL)
|
||||
return uv__next_timeout(loop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_backend_timeout(const uv_loop_t* loop) {
|
||||
if (QUEUE_EMPTY(&loop->watcher_queue))
|
||||
return uv__backend_timeout(loop);
|
||||
/* Need to call uv_run to update the backend fd state. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_loop_alive(const uv_loop_t* loop) {
|
||||
return uv__loop_alive(loop);
|
||||
return uv__loop_alive(loop);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -395,23 +395,28 @@ int uv_loop_fork(uv_loop_t* loop) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__loop_alive(const uv_loop_t* loop) {
|
||||
return uv__has_active_handles(loop) ||
|
||||
uv__has_active_reqs(loop) ||
|
||||
loop->pending_reqs_tail != NULL ||
|
||||
loop->endgame_handles != NULL;
|
||||
}
|
||||
|
||||
|
||||
int uv_loop_alive(const uv_loop_t* loop) {
|
||||
return uv__loop_alive(loop);
|
||||
}
|
||||
|
||||
|
||||
int uv_backend_timeout(const uv_loop_t* loop) {
|
||||
if (loop->stop_flag != 0)
|
||||
return 0;
|
||||
|
||||
if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop))
|
||||
return 0;
|
||||
|
||||
if (loop->pending_reqs_tail)
|
||||
return 0;
|
||||
|
||||
if (loop->endgame_handles)
|
||||
return 0;
|
||||
|
||||
if (loop->idle_handles)
|
||||
return 0;
|
||||
|
||||
return uv__next_timeout(loop);
|
||||
if (loop->stop_flag == 0 &&
|
||||
/* uv__loop_alive(loop) && */
|
||||
(uv__has_active_handles(loop) || uv__has_active_reqs(loop)) &&
|
||||
loop->pending_reqs_tail == NULL &&
|
||||
loop->idle_handles == NULL &&
|
||||
loop->endgame_handles == NULL)
|
||||
return uv__next_timeout(loop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -581,18 +586,6 @@ static void uv__poll(uv_loop_t* loop, DWORD timeout) {
|
||||
}
|
||||
|
||||
|
||||
static int uv__loop_alive(const uv_loop_t* loop) {
|
||||
return uv__has_active_handles(loop) ||
|
||||
uv__has_active_reqs(loop) ||
|
||||
loop->endgame_handles != NULL;
|
||||
}
|
||||
|
||||
|
||||
int uv_loop_alive(const uv_loop_t* loop) {
|
||||
return uv__loop_alive(loop);
|
||||
}
|
||||
|
||||
|
||||
int uv_run(uv_loop_t *loop, uv_run_mode mode) {
|
||||
DWORD timeout;
|
||||
int r;
|
||||
|
||||
@ -28,7 +28,7 @@ TEST_IMPL(loop_update_time) {
|
||||
|
||||
start = uv_now(uv_default_loop());
|
||||
while (uv_now(uv_default_loop()) - start < 1000)
|
||||
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_NOWAIT));
|
||||
ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_NOWAIT));
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
@ -43,20 +43,26 @@ TEST_IMPL(loop_backend_timeout) {
|
||||
uv_timer_t timer;
|
||||
int r;
|
||||
|
||||
r = uv_timer_init(loop, &timer);
|
||||
ASSERT(r == 0);
|
||||
/* The default loop has some internal watchers to initialize. */
|
||||
loop->active_handles++;
|
||||
r = uv_run(loop, UV_RUN_NOWAIT);
|
||||
ASSERT_EQ(r, 1);
|
||||
loop->active_handles--;
|
||||
ASSERT_EQ(uv_loop_alive(loop), 0);
|
||||
|
||||
ASSERT(!uv_loop_alive(loop));
|
||||
ASSERT(uv_backend_timeout(loop) == 0);
|
||||
r = uv_timer_init(loop, &timer);
|
||||
ASSERT_EQ(r, 0);
|
||||
|
||||
ASSERT_EQ(uv_loop_alive(loop), 0);
|
||||
ASSERT_EQ(uv_backend_timeout(loop), 0);
|
||||
|
||||
r = uv_timer_start(&timer, cb, 1000, 0); /* 1 sec */
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_backend_timeout(loop) > 100); /* 0.1 sec */
|
||||
ASSERT(uv_backend_timeout(loop) <= 1000); /* 1 sec */
|
||||
ASSERT_EQ(r, 0);
|
||||
ASSERT_EQ(uv_backend_timeout(loop), 1000);
|
||||
|
||||
r = uv_run(loop, UV_RUN_DEFAULT);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_backend_timeout(loop) == 0);
|
||||
ASSERT_EQ(r, 0);
|
||||
ASSERT_EQ(uv_backend_timeout(loop), 0);
|
||||
|
||||
MAKE_VALGRIND_HAPPY();
|
||||
return 0;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user