kqueue: skip EVFILT_PROC when invalidating fds (#3629)

On NetBSD with libuv 1.44.1 we see that cmake occasionally hangs
waiting for a child process to exit, with libuv waiting forever for
`kevent` to deliver more events that never come. The child process has
already exited and is waiting to be collected with `waitpid`.

The hang occurs when the batch of events returned by one call to
`kevent` contains both a EVFILT_READ event for an fd and a later
EVFILT_PROC record for the PID with the same value as the earlier fd.
What happens is that `uv__platform_invalidate_fd` is called to
invalidate events later in the same batch for the fd, but
`uv__platform_invalidate_fd` invalidates the later EVFILT_PROC event
too because it sees the same "ident" value and does not check the
"filter" value to differentiate "ident" values that refer to fds vs.
"ident" values that refer to PIDs.

Add a check for the "filter" value to avoid confusing these two
different kinds of event "ident" values.
This commit is contained in:
chucksilvers 2022-05-17 04:43:52 -07:00 committed by GitHub
parent 1b8cc56194
commit 730e07e2f7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -456,7 +456,7 @@ void uv__platform_invalidate_fd(uv_loop_t* loop, int fd) {
/* Invalidate events with same file descriptor */
for (i = 0; i < nfds; i++)
if ((int) events[i].ident == fd)
if ((int) events[i].ident == fd && events[i].filter != EVFILT_PROC)
events[i].ident = -1;
}