Skip to content

Commit

Permalink
win,fsevent: fix uv_fs_event_stop() assert
Browse files Browse the repository at this point in the history
Fix a logic error where calling uv_fs_event_stop() from the event
callback tripped on a `handle->dir_handle != INVALID_HANDLE_VALUE`
assert in uv_fs_event_queue_readdirchanges().

Fixes: libuv#3258
PR-URL: libuv#3259
Reviewed-By: Jameson Nash <vtjnash@gmail.com>
Reviewed-By: Santiago Gimeno <santiago.gimeno@gmail.com>
  • Loading branch information
bnoordhuis committed Sep 8, 2021
1 parent 7024f8b commit a39009a
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 4 deletions.
6 changes: 3 additions & 3 deletions src/win/fs-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -574,10 +574,10 @@ void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req,
handle->cb(handle, NULL, 0, uv_translate_sys_error(err));
}

if (!(handle->flags & UV_HANDLE_CLOSING)) {
uv_fs_event_queue_readdirchanges(loop, handle);
} else {
if (handle->flags & UV_HANDLE_CLOSING) {
uv_want_endgame(loop, (uv_handle_t*)handle);
} else if (uv__is_active(handle)) {
uv_fs_event_queue_readdirchanges(loop, handle);
}
}

Expand Down
49 changes: 48 additions & 1 deletion test/test-fs-event.c
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ static void timer_cb_file(uv_timer_t* handle) {

static void timer_cb_touch(uv_timer_t* timer) {
uv_close((uv_handle_t*)timer, NULL);
touch_file("watch_file");
touch_file((char*) timer->data);
timer_cb_touch_called++;
}

Expand Down Expand Up @@ -730,6 +730,7 @@ TEST_IMPL(fs_event_watch_file_current_dir) {
r = uv_timer_init(loop, &timer);
ASSERT(r == 0);

timer.data = "watch_file";
r = uv_timer_start(&timer, timer_cb_touch, 1100, 0);
ASSERT(r == 0);

Expand Down Expand Up @@ -1174,3 +1175,49 @@ TEST_IMPL(fs_event_watch_invalid_path) {
MAKE_VALGRIND_HAPPY();
return 0;
}

static int fs_event_cb_stop_calls;

static void fs_event_cb_stop(uv_fs_event_t* handle, const char* path,
int events, int status) {
uv_fs_event_stop(handle);
fs_event_cb_stop_calls++;
}

TEST_IMPL(fs_event_stop_in_cb) {
uv_fs_event_t fs;
uv_timer_t timer;
char path[] = "fs_event_stop_in_cb.txt";

#if defined(NO_FS_EVENTS)
RETURN_SKIP(NO_FS_EVENTS);
#endif

remove(path);
create_file(path);

ASSERT_EQ(0, uv_fs_event_init(uv_default_loop(), &fs));
ASSERT_EQ(0, uv_fs_event_start(&fs, fs_event_cb_stop, path, 0));

/* Note: timer_cb_touch() closes the handle. */
timer.data = path;
ASSERT_EQ(0, uv_timer_init(uv_default_loop(), &timer));
ASSERT_EQ(0, uv_timer_start(&timer, timer_cb_touch, 100, 0));

ASSERT_EQ(0, fs_event_cb_stop_calls);
ASSERT_EQ(0, timer_cb_touch_called);

ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT));

ASSERT_EQ(1, fs_event_cb_stop_calls);
ASSERT_EQ(1, timer_cb_touch_called);

uv_close((uv_handle_t*) &fs, NULL);
ASSERT_EQ(0, uv_run(uv_default_loop(), UV_RUN_DEFAULT));
ASSERT_EQ(1, fs_event_cb_stop_calls);

remove(path);

MAKE_VALGRIND_HAPPY();
return 0;
}
2 changes: 2 additions & 0 deletions test/test-list.h
Original file line number Diff line number Diff line change
Expand Up @@ -391,6 +391,7 @@ TEST_DECLARE (fs_event_close_in_callback)
TEST_DECLARE (fs_event_start_and_close)
TEST_DECLARE (fs_event_error_reporting)
TEST_DECLARE (fs_event_getpath)
TEST_DECLARE (fs_event_stop_in_cb)
TEST_DECLARE (fs_scandir_empty_dir)
TEST_DECLARE (fs_scandir_non_existent_dir)
TEST_DECLARE (fs_scandir_file)
Expand Down Expand Up @@ -1052,6 +1053,7 @@ TASK_LIST_START
TEST_ENTRY (fs_event_start_and_close)
TEST_ENTRY_CUSTOM (fs_event_error_reporting, 0, 0, 60000)
TEST_ENTRY (fs_event_getpath)
TEST_ENTRY (fs_event_stop_in_cb)
TEST_ENTRY (fs_scandir_empty_dir)
TEST_ENTRY (fs_scandir_non_existent_dir)
TEST_ENTRY (fs_scandir_file)
Expand Down

0 comments on commit a39009a

Please sign in to comment.