fix: fix the fixes and add more error logging
This commit is contained in:
parent
eb42d23fc8
commit
f60f9e6a21
4 changed files with 30 additions and 8 deletions
|
|
@ -93,7 +93,7 @@ pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||||
self.file_watches.deinit(allocator);
|
self.file_watches.deinit(allocator);
|
||||||
var sit = self.snapshots.iterator();
|
var sit = self.snapshots.iterator();
|
||||||
while (sit.next()) |entry| {
|
while (sit.next()) |entry| {
|
||||||
// Keys are borrowed from self.watches and freed in the watches loop above.
|
allocator.free(entry.key_ptr.*); // independently owned; see take_snapshot/scan_dir
|
||||||
var names = entry.value_ptr.*;
|
var names = entry.value_ptr.*;
|
||||||
var nit = names.iterator();
|
var nit = names.iterator();
|
||||||
while (nit.next()) |ne| allocator.free(ne.key_ptr.*);
|
while (nit.next()) |ne| allocator.free(ne.key_ptr.*);
|
||||||
|
|
@ -436,7 +436,15 @@ fn take_snapshot(self: *@This(), allocator: std.mem.Allocator, dir_path: []const
|
||||||
self.snapshots_mutex.lock();
|
self.snapshots_mutex.lock();
|
||||||
errdefer self.snapshots_mutex.unlock();
|
errdefer self.snapshots_mutex.unlock();
|
||||||
const gop = try self.snapshots.getOrPut(allocator, dir_path);
|
const gop = try self.snapshots.getOrPut(allocator, dir_path);
|
||||||
if (!gop.found_existing) gop.value_ptr.* = .empty;
|
if (!gop.found_existing) {
|
||||||
|
// Snapshot outer keys are independently owned so they can be safely
|
||||||
|
// freed in deinit/remove_watch regardless of how the entry was created.
|
||||||
|
gop.key_ptr.* = allocator.dupe(u8, dir_path) catch |e| {
|
||||||
|
_ = self.snapshots.remove(dir_path);
|
||||||
|
return e;
|
||||||
|
};
|
||||||
|
gop.value_ptr.* = .empty;
|
||||||
|
}
|
||||||
var snapshot = gop.value_ptr;
|
var snapshot = gop.value_ptr;
|
||||||
for (names.items) |name| {
|
for (names.items) |name| {
|
||||||
if (snapshot.contains(name)) continue;
|
if (snapshot.contains(name)) continue;
|
||||||
|
|
@ -464,6 +472,7 @@ pub fn remove_watch(self: *@This(), allocator: std.mem.Allocator, path: []const
|
||||||
const snap_entry = self.snapshots.fetchRemove(path);
|
const snap_entry = self.snapshots.fetchRemove(path);
|
||||||
self.snapshots_mutex.unlock();
|
self.snapshots_mutex.unlock();
|
||||||
if (snap_entry) |entry| {
|
if (snap_entry) |entry| {
|
||||||
|
allocator.free(entry.key); // independently owned; see take_snapshot/scan_dir
|
||||||
var names = entry.value;
|
var names = entry.value;
|
||||||
var it = names.iterator();
|
var it = names.iterator();
|
||||||
while (it.next()) |ne| {
|
while (it.next()) |ne| {
|
||||||
|
|
|
||||||
|
|
@ -78,7 +78,7 @@ pub fn deinit(self: *@This(), allocator: std.mem.Allocator) void {
|
||||||
self.watches.deinit(allocator);
|
self.watches.deinit(allocator);
|
||||||
var sit = self.snapshots.iterator();
|
var sit = self.snapshots.iterator();
|
||||||
while (sit.next()) |entry| {
|
while (sit.next()) |entry| {
|
||||||
// Keys are borrowed from self.watches and freed in the watches loop above.
|
allocator.free(entry.key_ptr.*); // independently owned; see take_snapshot/scan_dir
|
||||||
var snap = entry.value_ptr.*;
|
var snap = entry.value_ptr.*;
|
||||||
var nit = snap.iterator();
|
var nit = snap.iterator();
|
||||||
while (nit.next()) |ne| allocator.free(ne.key_ptr.*);
|
while (nit.next()) |ne| allocator.free(ne.key_ptr.*);
|
||||||
|
|
@ -385,7 +385,15 @@ fn take_snapshot(self: *@This(), allocator: std.mem.Allocator, dir_path: []const
|
||||||
self.snapshots_mutex.lock();
|
self.snapshots_mutex.lock();
|
||||||
errdefer self.snapshots_mutex.unlock();
|
errdefer self.snapshots_mutex.unlock();
|
||||||
const gop = try self.snapshots.getOrPut(allocator, dir_path);
|
const gop = try self.snapshots.getOrPut(allocator, dir_path);
|
||||||
if (!gop.found_existing) gop.value_ptr.* = .empty;
|
if (!gop.found_existing) {
|
||||||
|
// Snapshot outer keys are independently owned so they can be safely
|
||||||
|
// freed in deinit/remove_watch regardless of how the entry was created.
|
||||||
|
gop.key_ptr.* = allocator.dupe(u8, dir_path) catch |e| {
|
||||||
|
_ = self.snapshots.remove(dir_path);
|
||||||
|
return e;
|
||||||
|
};
|
||||||
|
gop.value_ptr.* = .empty;
|
||||||
|
}
|
||||||
const snapshot = gop.value_ptr;
|
const snapshot = gop.value_ptr;
|
||||||
for (entries.items) |e| {
|
for (entries.items) |e| {
|
||||||
if (snapshot.contains(e.name)) continue;
|
if (snapshot.contains(e.name)) continue;
|
||||||
|
|
@ -407,6 +415,7 @@ pub fn remove_watch(self: *@This(), allocator: std.mem.Allocator, path: []const
|
||||||
const snap_entry = self.snapshots.fetchRemove(path);
|
const snap_entry = self.snapshots.fetchRemove(path);
|
||||||
self.snapshots_mutex.unlock();
|
self.snapshots_mutex.unlock();
|
||||||
if (snap_entry) |entry| {
|
if (snap_entry) |entry| {
|
||||||
|
allocator.free(entry.key); // independently owned; see take_snapshot/scan_dir
|
||||||
var snap = entry.value;
|
var snap = entry.value;
|
||||||
var it = snap.iterator();
|
var it = snap.iterator();
|
||||||
while (it.next()) |ne| allocator.free(ne.key_ptr.*);
|
while (it.next()) |ne| allocator.free(ne.key_ptr.*);
|
||||||
|
|
|
||||||
|
|
@ -210,7 +210,8 @@ fn thread_fn(
|
||||||
}
|
}
|
||||||
// Re-arm ReadDirectoryChangesW for the next batch.
|
// Re-arm ReadDirectoryChangesW for the next batch.
|
||||||
w.overlapped = std.mem.zeroes(windows.OVERLAPPED);
|
w.overlapped = std.mem.zeroes(windows.OVERLAPPED);
|
||||||
_ = win32.ReadDirectoryChangesW(w.handle, w.buf.ptr, buf_size, 1, notify_filter, null, &w.overlapped, null);
|
if (win32.ReadDirectoryChangesW(w.handle, w.buf.ptr, buf_size, 1, notify_filter, null, &w.overlapped, null) == 0)
|
||||||
|
std.log.err("nightwatch: ReadDirectoryChangesW re-arm failed for {s}, future events lost", .{entry.key_ptr.*});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
watches_mutex.unlock();
|
watches_mutex.unlock();
|
||||||
|
|
|
||||||
|
|
@ -225,7 +225,8 @@ pub fn Create(comptime variant: Variant) type {
|
||||||
fn change_cb(h: *Handler, path: []const u8, event_type: EventType, object_type: ObjectType) error{HandlerFailed}!void {
|
fn change_cb(h: *Handler, path: []const u8, event_type: EventType, object_type: ObjectType) error{HandlerFailed}!void {
|
||||||
const self: *Interceptor = @fieldParentPtr("handler", h);
|
const self: *Interceptor = @fieldParentPtr("handler", h);
|
||||||
if (event_type == .created and object_type == .dir and !Backend.watches_recursively) {
|
if (event_type == .created and object_type == .dir and !Backend.watches_recursively) {
|
||||||
self.backend.add_watch(self.allocator, path) catch {};
|
self.backend.add_watch(self.allocator, path) catch |e|
|
||||||
|
std.log.err("nightwatch: add_watch failed for {s}: {s}", .{ path, @errorName(e) });
|
||||||
recurse_watch(&self.backend, self.allocator, path);
|
recurse_watch(&self.backend, self.allocator, path);
|
||||||
}
|
}
|
||||||
return self.user_handler.change(path, event_type, object_type);
|
return self.user_handler.change(path, event_type, object_type);
|
||||||
|
|
@ -254,7 +255,8 @@ pub fn Create(comptime variant: Variant) type {
|
||||||
fn change_cb(h: *PollingHandler, path: []const u8, event_type: EventType, object_type: ObjectType) error{HandlerFailed}!void {
|
fn change_cb(h: *PollingHandler, path: []const u8, event_type: EventType, object_type: ObjectType) error{HandlerFailed}!void {
|
||||||
const self: *PollingInterceptor = @fieldParentPtr("handler", h);
|
const self: *PollingInterceptor = @fieldParentPtr("handler", h);
|
||||||
if (event_type == .created and object_type == .dir and !Backend.watches_recursively) {
|
if (event_type == .created and object_type == .dir and !Backend.watches_recursively) {
|
||||||
self.backend.add_watch(self.allocator, path) catch {};
|
self.backend.add_watch(self.allocator, path) catch |e|
|
||||||
|
std.log.err("nightwatch: add_watch failed for {s}: {s}", .{ path, @errorName(e) });
|
||||||
recurse_watch(&self.backend, self.allocator, path);
|
recurse_watch(&self.backend, self.allocator, path);
|
||||||
}
|
}
|
||||||
return self.user_handler.change(path, event_type, object_type);
|
return self.user_handler.change(path, event_type, object_type);
|
||||||
|
|
@ -280,7 +282,8 @@ pub fn Create(comptime variant: Variant) type {
|
||||||
if (entry.kind != .directory) continue;
|
if (entry.kind != .directory) continue;
|
||||||
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
var buf: [std.fs.max_path_bytes]u8 = undefined;
|
||||||
const sub = std.fmt.bufPrint(&buf, "{s}{c}{s}", .{ dir_path, std.fs.path.sep, entry.name }) catch continue;
|
const sub = std.fmt.bufPrint(&buf, "{s}{c}{s}", .{ dir_path, std.fs.path.sep, entry.name }) catch continue;
|
||||||
backend.add_watch(allocator, sub) catch {};
|
backend.add_watch(allocator, sub) catch |e|
|
||||||
|
std.log.err("nightwatch: add_watch failed for {s}: {s}", .{ sub, @errorName(e) });
|
||||||
recurse_watch(backend, allocator, sub);
|
recurse_watch(backend, allocator, sub);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue