Skip to content

Commit 24d1d08

Browse files
committed
src: don't run timers if loop is stopped/unref'd (#4048)
The initial run of timers shouldn't happen if uv_stop() has been run before uv_run() was called, and for backwards compatibility they also shouldn't run if they have been unref'd before calling uv_run().
1 parent 6a9e429 commit 24d1d08

5 files changed

Lines changed: 31 additions & 6 deletions

File tree

src/unix/core.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,9 +424,8 @@ int uv_run(uv_loop_t* loop, uv_run_mode mode) {
424424
* while loop for UV_RUN_DEFAULT. Otherwise timers only need to be executed
425425
* once, which should be done after polling in order to maintain proper
426426
* execution order of the conceptual event loop. */
427-
if (mode == UV_RUN_DEFAULT) {
428-
if (r)
429-
uv__update_time(loop);
427+
if (mode == UV_RUN_DEFAULT && r != 0 && loop->stop_flag == 0) {
428+
uv__update_time(loop);
430429
uv__run_timers(loop);
431430
}
432431

src/win/core.c

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -629,9 +629,8 @@ int uv_run(uv_loop_t *loop, uv_run_mode mode) {
629629
* while loop for UV_RUN_DEFAULT. Otherwise timers only need to be executed
630630
* once, which should be done after polling in order to maintain proper
631631
* execution order of the conceptual event loop. */
632-
if (mode == UV_RUN_DEFAULT) {
633-
if (r)
634-
uv_update_time(loop);
632+
if (mode == UV_RUN_DEFAULT && r != 0 && loop->stop_flag == 0) {
633+
uv_update_time(loop);
635634
uv__run_timers(loop);
636635
}
637636

test/test-list.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ TEST_DECLARE (loop_alive)
2929
TEST_DECLARE (loop_close)
3030
TEST_DECLARE (loop_instant_close)
3131
TEST_DECLARE (loop_stop)
32+
TEST_DECLARE (loop_stop_before_run)
3233
TEST_DECLARE (loop_update_time)
3334
TEST_DECLARE (loop_backend_timeout)
3435
TEST_DECLARE (loop_configure)
@@ -233,6 +234,7 @@ TEST_DECLARE (timer_null_callback)
233234
TEST_DECLARE (timer_early_check)
234235
TEST_DECLARE (timer_no_double_call_once)
235236
TEST_DECLARE (timer_no_double_call_nowait)
237+
TEST_DECLARE (timer_no_run_on_unref)
236238
TEST_DECLARE (idle_starvation)
237239
TEST_DECLARE (idle_check)
238240
TEST_DECLARE (loop_handles)
@@ -573,6 +575,7 @@ TASK_LIST_START
573575
TEST_ENTRY (loop_close)
574576
TEST_ENTRY (loop_instant_close)
575577
TEST_ENTRY (loop_stop)
578+
TEST_ENTRY (loop_stop_before_run)
576579
TEST_ENTRY (loop_update_time)
577580
TEST_ENTRY (loop_backend_timeout)
578581
TEST_ENTRY (loop_configure)
@@ -846,6 +849,7 @@ TASK_LIST_START
846849
TEST_ENTRY (timer_early_check)
847850
TEST_ENTRY (timer_no_double_call_once)
848851
TEST_ENTRY (timer_no_double_call_nowait)
852+
TEST_ENTRY (timer_no_run_on_unref)
849853

850854
TEST_ENTRY (idle_starvation)
851855
TEST_ENTRY (idle_check)

test/test-loop-stop.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,14 @@ TEST_IMPL(loop_stop) {
7070
MAKE_VALGRIND_HAPPY(uv_default_loop());
7171
return 0;
7272
}
73+
74+
75+
TEST_IMPL(loop_stop_before_run) {
76+
ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
77+
ASSERT_OK(uv_timer_start(&timer_handle, (uv_timer_cb) abort, 0, 0));
78+
uv_stop(uv_default_loop());
79+
ASSERT_NE(uv_run(uv_default_loop(), UV_RUN_DEFAULT), 0);
80+
81+
MAKE_VALGRIND_HAPPY(uv_default_loop());
82+
return 0;
83+
}

test/test-timer.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,3 +407,15 @@ TEST_IMPL(timer_no_double_call_nowait) {
407407
MAKE_VALGRIND_HAPPY(uv_default_loop());
408408
return 0;
409409
}
410+
411+
TEST_IMPL(timer_no_run_on_unref) {
412+
uv_timer_t timer_handle;
413+
414+
ASSERT_OK(uv_timer_init(uv_default_loop(), &timer_handle));
415+
ASSERT_OK(uv_timer_start(&timer_handle, (uv_timer_cb) abort, 0, 0));
416+
uv_unref((uv_handle_t*) &timer_handle);
417+
ASSERT_EQ(uv_run(uv_default_loop(), UV_RUN_DEFAULT), 0);
418+
419+
MAKE_VALGRIND_HAPPY(uv_default_loop());
420+
return 0;
421+
}

0 commit comments

Comments
 (0)