From 466d614d75111b99998b3fc39781f9d5554279b6 Mon Sep 17 00:00:00 2001 From: David Allemang Date: Sun, 20 Jul 2025 21:10:25 -0400 Subject: [PATCH] inotify reloading works --- src/main.zig | 68 +++++++++++++++------------------------------------- 1 file changed, 19 insertions(+), 49 deletions(-) diff --git a/src/main.zig b/src/main.zig index df0589a..a031efd 100644 --- a/src/main.zig +++ b/src/main.zig @@ -136,9 +136,10 @@ pub fn main() !void { }; defer alloc.free(mods_path); - var mods: std.ArrayListUnmanaged(DynamicModule) = .{}; + var mods: std.StringHashMapUnmanaged(DynamicModule) = .{}; defer { - for (mods.items) |*mod| { + var it = mods.valueIterator(); + while (it.next()) |mod| { mod.deinit(alloc); } mods.deinit(alloc); @@ -159,7 +160,8 @@ pub fn main() !void { var mod = try DynamicModule.init(mod_path, alloc); errdefer mod.deinit(alloc); - try mods.append(alloc, mod); + + try mods.putNoClobber(alloc, entry.name, mod); } } @@ -173,7 +175,11 @@ pub fn main() !void { const wd: i32 = blk: { const pathz = try alloc.dupeZ(u8, mods_path); defer alloc.free(pathz); - const ret: isize = @bitCast(linux.inotify_add_watch(fd, pathz, linux.IN.ALL_EVENTS)); + const ret: isize = @bitCast(linux.inotify_add_watch( + fd, + pathz, + linux.IN.MOVED_TO, + )); if (ret < 0) return error.inotify_add_watch_error; break :blk @intCast(ret); }; @@ -186,11 +192,8 @@ pub fn main() !void { const eventbuf = try alloc.alloc(u8, 5 * (@sizeOf(linux.inotify_event) + linux.NAME_MAX)); defer alloc.free(eventbuf); - for (0..100) |_| { - std.time.sleep(std.time.ns_per_s); - + for (0..300) |_| { const n = linux.poll(&fds, fds.len, std.time.ms_per_s); - std.log.debug("polled {d}", .{n}); if (n > 0) { const c = linux.read(fd, eventbuf.ptr, eventbuf.len); @@ -198,33 +201,16 @@ pub fn main() !void { var i: usize = 0; while (i < c) { const event: *linux.inotify_event = @alignCast(@ptrCast(eventbuf.ptr + i)); + const name = event.getName().?; // Impossible as IN.MOVE_TO includes a name. - std.log.info("event: {any} {?s}", .{ event, event.getName() }); - - const names = .{ - "ACCESS", - "MODIFY", - "ATTRIB", - "CLOSE_WRITE", - "CLOSE_NOWRITE", - "OPEN", - "MOVED_FROM", - "MOVED_TO", - "CREATE", - "DELETE", - "DELETE_SELF", - "MOVE_SELF", - }; - - // Zig builds the lib in a temp file and then moves that into the destination. - // Think i need to handle "MOVE_TO" on the inode... but that might not work right because that inode - // is not what gets modified. - // Probably want a hashmap keyed by each mod's realpath basename. - - inline for (names) |name| { - if (@field(linux.IN, name) & event.mask != 0) { - std.log.debug(" {s}", .{name}); + if (mods.getPtr(name)) |mod| { + if (mod.reload(alloc)) |_| { + std.log.info("Reloaded {s}.", .{name}); + } else |_| { + std.log.err("Failed to reload {s}. Rolled back.", .{mod.realpath}); } + } else { + // Ignore unloaded module. } i += @sizeOf(linux.inotify_event) + event.len; @@ -232,21 +218,5 @@ pub fn main() !void { } } - // std.log.debug("-" ** 80, .{}); - // for (0..10) |x| { - // std.log.debug("{d}...", .{x}); - // std.time.sleep(std.time.ns_per_s); - // } - // std.log.debug("reloading.", .{}); - // std.time.sleep(std.time.ns_per_s); - // - // for (mods.items) |*mod| { - // if (mod.reload(alloc)) |_| { - // std.log.debug("loaded {s}", .{mod.curr.path}); - // } else |_| { - // std.log.debug("rolled back to {s}", .{mod.curr.path}); - // } - // } - std.log.debug("-" ** 80, .{}); }