aboutsummaryrefslogtreecommitdiff
path: root/lib/std/Build/Watch.zig
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2024-07-09 23:15:22 -0700
committerAndrew Kelley <andrew@ziglang.org>2024-07-12 00:14:08 -0700
commit7bccef3e4e4d48c2e1d34ec28754d8c33902f2bb (patch)
treecc708ebeb8f8885c3ca4cfaa273a1eaee5101f87 /lib/std/Build/Watch.zig
parent26bdc836d2d9b2654f7f95fec34c6276070f2a59 (diff)
downloadzig-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.zig29
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;
+}