New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
kqueue: synchronously close fd in Close() #334
Conversation
This makes it possible to run and destroy watchers quickly on macOS (e.g. in unit tests). Closes #333
Tests breakage is pre-existing: #264 |
Ping? |
We use a resource checker in our code that counts total process goroutines before and after, and we are seeing occasionally a goroutine left on macOS after Close is called. This PR is a great improvement. Thanks. (One thing I would consider adding would be to make Close wait for the readEvents goroutine to complete so we can ensure all resources are cleaned up before it completes, but regardless this PR makes things better.) |
@crawshaw Hi! Since you think this PR is an improvement despite occasional pre-existing test failures, may we ask you to merge it? |
@feldgendler this isn't my repository |
@nathany May I ask you for a review? |
The tests for FreeBSD and OpenBSD fail: FreeBSD: https://github.com/fsnotify/fsnotify/runs/7619130055?check_suite_focus=true
OpenBSD: https://github.com/fsnotify/fsnotify/runs/7619131191?check_suite_focus=true
If I run it locally, the results are somewhat inconsistent: it doesn't always fail and doesn't always fail in the same way. I've also seen it fail locally with NetBSD:
The first run was fine, but in the second there were no events at all(!) Same on macOS:
I didn't investigate why this is happening yet, but I my guess is that it's returning before its finished reading(?) Also note the OpenBSD test takes forever; mostly due to that TestOpenCloseQuickly test that was added, but that's a minor (fixable) issue. |
Note that the above is after I rebased the branch on main, which is over here: https://github.com/fsnotify/fsnotify/tree/333-macos-wait-kqueue-fd-close |
#124 seems to fix the same problem, and all tests pass on that one. Updated branch here, but needs some more work as it's a pretty old branch: https://github.com/fsnotify/fsnotify/tree/kqueue-no-timeout |
The timeout for unix.Kevent() is causing issues; every 100ms it will do a new unix.Kevent() syscall, which isn't too efficient: even if you have just one change an hour, you will still keep calling kevent() ten times per second, resulting in a needlessly high CPU usage. Without a timeout, kevent() will block indefinitely until there are some events, which is much more efficient. We can't just remove the timout however, since we can't interrupt the kevent() call on FreeBSD and NetBSD, and it will hang forever. This issue is described in more detail here: #262 (comment) To solve this we register a new kevent() with the file descriptor set to the closepipe; when this pipe is closed an event is sent and kevent() will stop blocking. This is a rebased version of #124. Fixes #89 Fixes #237 Fixes #333 Supersedes and closes #124 Supersedes and closes #262 Supersedes and closes #334
I created #480, which should solve this issue better. |
The timeout for unix.Kevent() is causing issues; every 100ms it will do a new unix.Kevent() syscall, which isn't too efficient: even if you have just one change an hour, you will still keep calling kevent() ten times per second, resulting in a needlessly high CPU usage. Without a timeout, kevent() will block indefinitely until there are some events, which is much more efficient. We can't just remove the timout however, since we can't interrupt the kevent() call on FreeBSD and NetBSD, and it will hang forever. This issue is described in more detail here: #262 (comment) To solve this we register a new kevent() with the file descriptor set to the closepipe; when this pipe is closed an event is sent and kevent() will stop blocking. This is a rebased version of #124. Fixes #89 Fixes #237 Fixes #333 Supersedes and closes #124 Supersedes and closes #262 Supersedes and closes #334 Co-authored-by: Felix Lange <fjl@twurst.com>
This makes it possible to create and destroy watchers quickly on macOS (e.g. in
unit tests).
Closes #333