diff --git a/src/backend/Windows.zig b/src/backend/Windows.zig index 029f5d2..ddec850 100644 --- a/src/backend/Windows.zig +++ b/src/backend/Windows.zig @@ -197,20 +197,8 @@ fn thread_fn( } gop.value_ptr.* = ot; } - // When a directory is renamed, scan its children so that - // subsequent delete events for contents can resolve their type. - if (ot == .dir and info.Action == FILE_ACTION_RENAMED_NEW_NAME) - scan_path_types_into(allocator, path_types, full_path); break :blk ot; }; - // Suppress FILE_ACTION_MODIFIED on directories: these are - // parent-directory mtime side-effects of child operations - // (delete, rename) and are not emitted by any other backend. - if (event_type == .modified and object_type == .dir) { - if (info.NextEntryOffset == 0) break; - offset += info.NextEntryOffset; - continue; - } // Capture next_entry_offset before releasing the mutex: after unlock, // the main thread may call remove_watch() which frees w.buf, making // the `info` pointer (which points into w.buf) a dangling reference. @@ -272,14 +260,9 @@ pub fn add_watch(self: *@This(), allocator: std.mem.Allocator, path: []const u8) } // Walk root recursively and seed path_types with the type of every entry. -// Called from add_watch and from thread_fn on directory renames so that -// FILE_ACTION_REMOVED events for children of a renamed directory can -// resolve their ObjectType from cache. +// Called from add_watch (mutex already held) so pre-existing paths are +// known before any FILE_ACTION_REMOVED or FILE_ACTION_RENAMED_OLD_NAME fires. fn scan_path_types(self: *@This(), allocator: std.mem.Allocator, root: []const u8) void { - scan_path_types_into(allocator, &self.path_types, root); -} - -fn scan_path_types_into(allocator: std.mem.Allocator, path_types: *std.StringHashMapUnmanaged(ObjectType), root: []const u8) void { var dir = std.fs.openDirAbsolute(root, .{ .iterate = true }) catch return; defer dir.close(); var iter = dir.iterate(); @@ -291,15 +274,15 @@ fn scan_path_types_into(allocator: std.mem.Allocator, path_types: *std.StringHas }; var path_buf: [std.fs.max_path_bytes]u8 = undefined; const full_path = std.fmt.bufPrint(&path_buf, "{s}\\{s}", .{ root, entry.name }) catch continue; - const gop = path_types.getOrPut(allocator, full_path) catch continue; + const gop = self.path_types.getOrPut(allocator, full_path) catch continue; if (!gop.found_existing) { gop.key_ptr.* = allocator.dupe(u8, full_path) catch { - _ = path_types.remove(full_path); + _ = self.path_types.remove(full_path); continue; }; } gop.value_ptr.* = ot; - if (ot == .dir) scan_path_types_into(allocator, path_types, gop.key_ptr.*); + if (ot == .dir) self.scan_path_types(allocator, gop.key_ptr.*); } }