unix, windows: run expired timers in run-once mode
Before this commit, creating an event loop, starting a timer and calling uv_run(UV_RUN_ONCE) blocked in uv_run() until the timer expired - but didn't actually run the timer.
This commit is contained in:
parent
8ef9592a95
commit
f6d8ba3c9a
@ -317,8 +317,21 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
|
|||||||
uv__io_poll(loop, timeout);
|
uv__io_poll(loop, timeout);
|
||||||
uv__run_check(loop);
|
uv__run_check(loop);
|
||||||
uv__run_closing_handles(loop);
|
uv__run_closing_handles(loop);
|
||||||
r = uv__loop_alive(loop);
|
|
||||||
|
|
||||||
|
if (mode == UV_RUN_ONCE) {
|
||||||
|
/* UV_RUN_ONCE implies forward progess: at least one callback must have
|
||||||
|
* been invoked when it returns. uv__io_poll() can return without doing
|
||||||
|
* I/O (meaning: no callbacks) when its timeout expires - which means we
|
||||||
|
* have pending timers that satisfy the forward progress constraint.
|
||||||
|
*
|
||||||
|
* UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
|
||||||
|
* the check.
|
||||||
|
*/
|
||||||
|
uv__update_time(loop);
|
||||||
|
uv__run_timers(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
r = uv__loop_alive(loop);
|
||||||
UV_TICK_STOP(loop, mode);
|
UV_TICK_STOP(loop, mode);
|
||||||
|
|
||||||
if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
|
if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
|
||||||
|
|||||||
@ -298,6 +298,20 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
|
|||||||
!(mode & UV_RUN_NOWAIT));
|
!(mode & UV_RUN_NOWAIT));
|
||||||
|
|
||||||
uv_check_invoke(loop);
|
uv_check_invoke(loop);
|
||||||
|
|
||||||
|
if (mode == UV_RUN_ONCE) {
|
||||||
|
/* UV_RUN_ONCE implies forward progess: at least one callback must have
|
||||||
|
* been invoked when it returns. uv__io_poll() can return without doing
|
||||||
|
* I/O (meaning: no callbacks) when its timeout expires - which means we
|
||||||
|
* have pending timers that satisfy the forward progress constraint.
|
||||||
|
*
|
||||||
|
* UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from
|
||||||
|
* the check.
|
||||||
|
*/
|
||||||
|
uv_update_time(loop);
|
||||||
|
uv_process_timers(loop);
|
||||||
|
}
|
||||||
|
|
||||||
r = uv__loop_alive(loop);
|
r = uv__loop_alive(loop);
|
||||||
if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
|
if (mode & (UV_RUN_ONCE | UV_RUN_NOWAIT))
|
||||||
break;
|
break;
|
||||||
|
|||||||
@ -101,6 +101,7 @@ TEST_DECLARE (timer_start_twice)
|
|||||||
TEST_DECLARE (timer_order)
|
TEST_DECLARE (timer_order)
|
||||||
TEST_DECLARE (timer_huge_timeout)
|
TEST_DECLARE (timer_huge_timeout)
|
||||||
TEST_DECLARE (timer_huge_repeat)
|
TEST_DECLARE (timer_huge_repeat)
|
||||||
|
TEST_DECLARE (timer_run_once)
|
||||||
TEST_DECLARE (idle_starvation)
|
TEST_DECLARE (idle_starvation)
|
||||||
TEST_DECLARE (loop_handles)
|
TEST_DECLARE (loop_handles)
|
||||||
TEST_DECLARE (get_loadavg)
|
TEST_DECLARE (get_loadavg)
|
||||||
@ -350,6 +351,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (timer_order)
|
TEST_ENTRY (timer_order)
|
||||||
TEST_ENTRY (timer_huge_timeout)
|
TEST_ENTRY (timer_huge_timeout)
|
||||||
TEST_ENTRY (timer_huge_repeat)
|
TEST_ENTRY (timer_huge_repeat)
|
||||||
|
TEST_ENTRY (timer_run_once)
|
||||||
|
|
||||||
TEST_ENTRY (idle_starvation)
|
TEST_ENTRY (idle_starvation)
|
||||||
|
|
||||||
|
|||||||
@ -264,3 +264,31 @@ TEST_IMPL(timer_huge_repeat) {
|
|||||||
MAKE_VALGRIND_HAPPY();
|
MAKE_VALGRIND_HAPPY();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static unsigned int timer_run_once_timer_cb_called;
|
||||||
|
|
||||||
|
|
||||||
|
static void timer_run_once_timer_cb(uv_timer_t* handle, int status) {
|
||||||
|
timer_run_once_timer_cb_called++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_IMPL(timer_run_once) {
|
||||||
|
uv_timer_t timer_handle;
|
||||||
|
|
||||||
|
ASSERT(0 == uv_timer_init(uv_default_loop(), &timer_handle));
|
||||||
|
ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 0, 0));
|
||||||
|
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
||||||
|
ASSERT(1 == timer_run_once_timer_cb_called);
|
||||||
|
|
||||||
|
ASSERT(0 == uv_timer_start(&timer_handle, timer_run_once_timer_cb, 1, 0));
|
||||||
|
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
||||||
|
ASSERT(2 == timer_run_once_timer_cb_called);
|
||||||
|
|
||||||
|
uv_close((uv_handle_t*) &timer_handle, NULL);
|
||||||
|
ASSERT(0 == uv_run(uv_default_loop(), UV_RUN_ONCE));
|
||||||
|
|
||||||
|
MAKE_VALGRIND_HAPPY();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user