fix: remove inotify_rm_watch that caused infinite config-reload loop
inotify_rm_watch() generates IN_IGNORED events into the inotify queue, which immediately triggers another watch_dispatch() call, which calls inotify_rm_watch() again, generating another IN_IGNORED ad infinitum. This pegs the CPU and makes input laggy on every config reload. Fix by removing inotify_rm_watch() entirely. inotify_add_watch() alone handles both cases: - Same inode: modifies the existing watch (no event generated) - New inode (delete-and-recreate): creates a new watch; old watch on the unlinked inode generates a single IN_IGNORED (one-shot, not a loop)
This commit is contained in:
+5
-3
@@ -996,11 +996,13 @@ watch_dispatch(int fd, uint32_t mask, void *data)
|
||||
|
||||
/*
|
||||
* Some editors (vim, nano) delete-and-recreate files on save,
|
||||
* which removes our watch (which is a pain in the ass.
|
||||
* Hence, re-add it defensively. It's good for the soul)
|
||||
* which replaces the inode and invalidates the existing watch.
|
||||
* inotify_add_watch() on the path creates a new watch on the
|
||||
* new inode (or is a no-op on the same inode). We do NOT call
|
||||
* inotify_rm_watch() first — that would generate IN_IGNORED
|
||||
* events into our own queue, causing an infinite reload loop.
|
||||
*/
|
||||
|
||||
inotify_rm_watch(ws->inotify_fd, ws->watch_fd);
|
||||
ws->watch_fd = inotify_add_watch(ws->inotify_fd, ws->path,
|
||||
IN_CLOSE_WRITE | IN_MOVED_TO | IN_CREATE);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user