From face6af0da1d9cd2ef56ebd65a94d13bc4730222 Mon Sep 17 00:00:00 2001 From: Guldoman Date: Sat, 22 Jun 2024 22:36:27 +0200 Subject: [PATCH] fix(dirmonitor): avoid calling the change callback multiple times in the same notification (#1824) --- src/api/dirmonitor.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/api/dirmonitor.c b/src/api/dirmonitor.c index 320235a0..bb3911ec 100644 --- a/src/api/dirmonitor.c +++ b/src/api/dirmonitor.c @@ -26,7 +26,19 @@ int get_mode_dirmonitor(); static int f_check_dir_callback(int watch_id, const char* path, void* L) { - // using absolute indices from f_dirmonitor_check (2: callback, 3: error_callback) + // using absolute indices from f_dirmonitor_check (2: callback, 3: error_callback, 4: watch_id notified table) + + // Check if we already notified about this watch + lua_rawgeti(L, 4, watch_id); + bool skip = !lua_isnoneornil(L, -1); + lua_pop(L, 1); + if (skip) return 0; + + // Set watch as notified + lua_pushboolean(L, true); + lua_rawseti(L, 4, watch_id); + + // Prepare callback call lua_pushvalue(L, 2); if (path) lua_pushlstring(L, path, watch_id); @@ -117,6 +129,9 @@ static int f_dirmonitor_check(lua_State* L) { if (monitor->length < 0) lua_pushnil(L); else if (monitor->length > 0) { + // Create a table for keeping track of what watch ids were notified in this check, + // so that we avoid notifying multiple times. + lua_newtable(L); if (translate_changes_dirmonitor(monitor->internal, monitor->buffer, monitor->length, f_check_dir_callback, L) == 0) monitor->length = 0; lua_pushboolean(L, 1);