fix(windows): cache renamed-to path
This commit is contained in:
parent
ef01e2590e
commit
6927431726
2 changed files with 23 additions and 8 deletions
|
|
@ -183,8 +183,19 @@ fn thread_fn(
|
||||||
if (info.Action == FILE_ACTION_RENAMED_NEW_NAME) {
|
if (info.Action == FILE_ACTION_RENAMED_NEW_NAME) {
|
||||||
if (pending_rename) |pr| {
|
if (pending_rename) |pr| {
|
||||||
const src = pr.path_buf[0..pr.path_len];
|
const src = pr.path_buf[0..pr.path_len];
|
||||||
// Re-scan renamed directory contents into cache so
|
// Cache the new path so future delete/rename events can
|
||||||
// subsequent delete events for children resolve correctly.
|
// resolve its type (OLD_NAME removed it from the cache).
|
||||||
|
if (pr.object_type != .unknown) cache_new: {
|
||||||
|
const gop = path_types.getOrPut(allocator, full_path) catch break :cache_new;
|
||||||
|
if (!gop.found_existing) {
|
||||||
|
gop.key_ptr.* = allocator.dupe(u8, full_path) catch {
|
||||||
|
_ = path_types.remove(full_path);
|
||||||
|
break :cache_new;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
gop.value_ptr.* = pr.object_type;
|
||||||
|
}
|
||||||
|
// For dirs, also scan children into cache.
|
||||||
if (pr.object_type == .dir)
|
if (pr.object_type == .dir)
|
||||||
scan_path_types_into(allocator, path_types, full_path);
|
scan_path_types_into(allocator, path_types, full_path);
|
||||||
const next_entry_offset = info.NextEntryOffset;
|
const next_entry_offset = info.NextEntryOffset;
|
||||||
|
|
|
||||||
|
|
@ -550,8 +550,6 @@ fn testMultipleFiles(comptime Watcher: type, allocator: std.mem.Allocator) !void
|
||||||
}
|
}
|
||||||
|
|
||||||
fn testRenameOrder(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
fn testRenameOrder(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
||||||
// inotify pairs MOVED_FROM + MOVED_TO into a single rename event; nothing to order.
|
|
||||||
if (builtin.os.tag == .linux) return error.SkipZigTest;
|
|
||||||
|
|
||||||
const TH = MakeTestHandler(Watcher);
|
const TH = MakeTestHandler(Watcher);
|
||||||
|
|
||||||
|
|
@ -581,6 +579,10 @@ fn testRenameOrder(comptime Watcher: type, allocator: std.mem.Allocator) !void {
|
||||||
try std.fs.renameAbsolute(src_path, dst_path);
|
try std.fs.renameAbsolute(src_path, dst_path);
|
||||||
try drainEvents(Watcher, &watcher);
|
try drainEvents(Watcher, &watcher);
|
||||||
|
|
||||||
|
// Backends that deliver a paired rename() callback (INotify, Windows) have
|
||||||
|
// no two-event ordering to verify - the pair is a single atomic event.
|
||||||
|
if (th.hasRename(src_path, dst_path)) return;
|
||||||
|
|
||||||
const src_idx = th.indexOfAnyPath(src_path) orelse
|
const src_idx = th.indexOfAnyPath(src_path) orelse
|
||||||
return error.MissingSrcEvent;
|
return error.MissingSrcEvent;
|
||||||
const dst_idx = th.indexOfChange(dst_path, .renamed, .file) orelse
|
const dst_idx = th.indexOfChange(dst_path, .renamed, .file) orelse
|
||||||
|
|
@ -628,10 +630,12 @@ fn testRenameThenModify(comptime Watcher: type, allocator: std.mem.Allocator) !v
|
||||||
}
|
}
|
||||||
try drainEvents(Watcher, &watcher);
|
try drainEvents(Watcher, &watcher);
|
||||||
|
|
||||||
const rename_idx: usize = if (builtin.os.tag == .linux)
|
// Prefer the paired rename event (INotify, Windows); fall back to any
|
||||||
th.indexOfRename(src_path, dst_path) orelse return error.MissingRenameEvent
|
// event touching src_path for backends that emit separate events.
|
||||||
else
|
const rename_idx: usize =
|
||||||
th.indexOfAnyPath(src_path) orelse return error.MissingSrcEvent;
|
th.indexOfRename(src_path, dst_path) orelse
|
||||||
|
th.indexOfAnyPath(src_path) orelse
|
||||||
|
return error.MissingSrcEvent;
|
||||||
|
|
||||||
const modify_idx = th.indexOfChange(dst_path, .modified, .file) orelse
|
const modify_idx = th.indexOfChange(dst_path, .modified, .file) orelse
|
||||||
return error.MissingModifyEvent;
|
return error.MissingModifyEvent;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue