kqueue: don't immediately remove watches for all files in a directory on Delete event #526
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The problem was that that on Delete events for directories it would call Watcher.Remove() for all files in that directory too. This is fine if you call w.Remove() from the application, but if you rm -rf a directory the directory itself tends to be the first remove event (on FreeBSD at least):
So what would happen is that the internal state for /tmp/xxx/a etc. would get removed, and when the event gets processed we no longer have access to it.
Move Remove() to remove() with a flag to control removing files. If a watched directory is removed then the files will emit their own delete event, so we don't really need to do this.
Fixes #514
Also:
Don't send Remove|Write events; that's never really useful: if it's gone, then it's gone. No other backends do this.
Save a stat call by checking the readdir error instead.
Don't stat every directory; this isn't really needed, and getting a write event before a delete is fine (and this didn't suppress the write even anyway).
Add test/kqueue.c; just a simple implementation to test things.