From 6c760b62073b50a7de284111c6b1c57f73e6d370 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 3 May 2019 18:33:13 +0200 Subject: [PATCH] unix,win: fix `uv_fs_poll_stop()` when active MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fix `uv_fs_poll_stop()` for active handles by not attempting to mark the `uv_fs_poll_t` handle as closing when `uv_close()` hasn’t been called on it. Fixes: https://github.com/libuv/libuv/issues/2287 PR-URL: https://github.com/libuv/libuv/pull/2288 Refs: https://github.com/libuv/libuv/pull/1875 Reviewed-By: Ben Noordhuis Reviewed-By: Colin Ihrig Reviewed-By: Santiago Gimeno --- src/fs-poll.c | 2 +- test/test-fs-poll.c | 39 +++++++++++++++++++++++++++++++++++++++ test/test-list.h | 2 ++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/src/fs-poll.c b/src/fs-poll.c index 40cb147e..89864e23 100644 --- a/src/fs-poll.c +++ b/src/fs-poll.c @@ -241,7 +241,7 @@ static void timer_close_cb(uv_handle_t* timer) { handle = ctx->parent_handle; if (ctx == handle->poll_ctx) { handle->poll_ctx = ctx->previous; - if (handle->poll_ctx == NULL) + if (handle->poll_ctx == NULL && uv__is_closing(handle)) uv__make_close_pending((uv_handle_t*)handle); } else { for (last = handle->poll_ctx, it = last->previous; diff --git a/test/test-fs-poll.c b/test/test-fs-poll.c index e19a6878..9dfd5fdd 100644 --- a/test/test-fs-poll.c +++ b/test/test-fs-poll.c @@ -37,6 +37,10 @@ static void poll_cb_fail(uv_fs_poll_t* handle, int status, const uv_stat_t* prev, const uv_stat_t* curr); +static void poll_cb_noop(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr); static uv_fs_poll_t poll_handle; static uv_timer_t timer_handle; @@ -84,6 +88,12 @@ static void poll_cb_fail(uv_fs_poll_t* handle, ASSERT(0 && "fail_cb called"); } +static void poll_cb_noop(uv_fs_poll_t* handle, + int status, + const uv_stat_t* prev, + const uv_stat_t* curr) { +} + static void poll_cb(uv_fs_poll_t* handle, int status, @@ -259,3 +269,32 @@ TEST_IMPL(fs_poll_close_request_multi_stop_start) { MAKE_VALGRIND_HAPPY(); return 0; } + +TEST_IMPL(fs_poll_close_request_stop_when_active) { + /* Regression test for https://github.com/libuv/libuv/issues/2287. */ + uv_loop_t loop; + uv_fs_poll_t poll_handle; + + remove(FIXTURE); + + ASSERT(0 == uv_loop_init(&loop)); + + /* Set up all handles. */ + ASSERT(0 == uv_fs_poll_init(&loop, &poll_handle)); + ASSERT(0 == uv_fs_poll_start(&poll_handle, poll_cb_noop, FIXTURE, 100)); + uv_run(&loop, UV_RUN_ONCE); + + /* Close the timer handle, and do not crash. */ + ASSERT(0 == uv_fs_poll_stop(&poll_handle)); + uv_run(&loop, UV_RUN_ONCE); + + /* Clean up after the test. */ + uv_close((uv_handle_t*) &poll_handle, close_cb); + uv_run(&loop, UV_RUN_ONCE); + ASSERT(close_cb_called == 1); + + ASSERT(0 == uv_loop_close(&loop)); + + MAKE_VALGRIND_HAPPY(); + return 0; +} diff --git a/test/test-list.h b/test/test-list.h index cf5420ad..c090854b 100644 --- a/test/test-list.h +++ b/test/test-list.h @@ -290,6 +290,7 @@ TEST_DECLARE (fs_poll_getpath) TEST_DECLARE (fs_poll_close_request) TEST_DECLARE (fs_poll_close_request_multi_start_stop) TEST_DECLARE (fs_poll_close_request_multi_stop_start) +TEST_DECLARE (fs_poll_close_request_stop_when_active) TEST_DECLARE (kill) TEST_DECLARE (kill_invalid_signum) TEST_DECLARE (fs_file_noent) @@ -844,6 +845,7 @@ TASK_LIST_START TEST_ENTRY (fs_poll_close_request) TEST_ENTRY (fs_poll_close_request_multi_start_stop) TEST_ENTRY (fs_poll_close_request_multi_stop_start) + TEST_ENTRY (fs_poll_close_request_stop_when_active) TEST_ENTRY (kill) TEST_ENTRY (kill_invalid_signum)