diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2024-07-09 23:15:22 -0700 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2024-07-12 00:14:08 -0700 |
| commit | 7bccef3e4e4d48c2e1d34ec28754d8c33902f2bb (patch) | |
| tree | cc708ebeb8f8885c3ca4cfaa273a1eaee5101f87 /lib/std/Build/Watch.zig | |
| parent | 26bdc836d2d9b2654f7f95fec34c6276070f2a59 (diff) | |
| download | zig-7bccef3e4e4d48c2e1d34ec28754d8c33902f2bb.tar.gz zig-7bccef3e4e4d48c2e1d34ec28754d8c33902f2bb.zip | |
std.Build.Watch: introduce special file "." to watch entire dir
And use it to implement InstallDir Step watch integration.
I'm not seeing any events triggered when I run `mkdir` in the watched
directory, however, and I have not yet figured out why.
Diffstat (limited to 'lib/std/Build/Watch.zig')
| -rw-r--r-- | lib/std/Build/Watch.zig | 29 |
1 files changed, 20 insertions, 9 deletions
diff --git a/lib/std/Build/Watch.zig b/lib/std/Build/Watch.zig index 2ffcd27ca7..e9b4449748 100644 --- a/lib/std/Build/Watch.zig +++ b/lib/std/Build/Watch.zig @@ -12,10 +12,13 @@ generation: Generation, pub const fan_mask: std.os.linux.fanotify.MarkMask = .{ .CLOSE_WRITE = true, + .CREATE = true, .DELETE = true, + .DELETE_SELF = true, + .EVENT_ON_CHILD = true, .MOVED_FROM = true, .MOVED_TO = true, - .EVENT_ON_CHILD = true, + .MOVE_SELF = true, }; pub const init: Watch = .{ @@ -32,6 +35,7 @@ pub const init: Watch = .{ const DirTable = std.ArrayHashMapUnmanaged(Cache.Path, void, Cache.Path.TableAdapter, false); const HandleTable = std.ArrayHashMapUnmanaged(LinuxFileHandle, ReactionSet, LinuxFileHandle.Adapter, false); +/// Special key of "." means any changes in this directory trigger the steps. const ReactionSet = std.StringArrayHashMapUnmanaged(StepSet); const StepSet = std.AutoArrayHashMapUnmanaged(*Step, Generation); @@ -149,14 +153,10 @@ pub fn markDirtySteps(w: *Watch, gpa: Allocator) !bool { const file_name = std.mem.span(file_name_z); const lfh: Watch.LinuxFileHandle = .{ .handle = file_handle }; if (w.handle_table.getPtr(lfh)) |reaction_set| { - if (reaction_set.getPtr(file_name)) |step_set| { - for (step_set.keys()) |step| { - if (step.state != .precheck_done) { - step.recursiveReset(gpa); - any_dirty = true; - } - } - } + if (reaction_set.getPtr(".")) |glob_set| + any_dirty = markStepSetDirty(gpa, glob_set, any_dirty); + if (reaction_set.getPtr(file_name)) |step_set| + any_dirty = markStepSetDirty(gpa, step_set, any_dirty); } }, else => |t| std.log.warn("unexpected fanotify event '{s}'", .{@tagName(t)}), @@ -187,3 +187,14 @@ fn markAllFilesDirty(w: *Watch, gpa: Allocator) void { } } } + +fn markStepSetDirty(gpa: Allocator, step_set: *StepSet, any_dirty: bool) bool { + var this_any_dirty = false; + for (step_set.keys()) |step| { + if (step.state != .precheck_done) { + step.recursiveReset(gpa); + this_any_dirty = true; + } + } + return any_dirty or this_any_dirty; +} |
