process,bsd: handle kevent NOTE_EXIT failure (#3451)
The kernel may return ESRCH if the child has already exited here. This is rather annoying, and means we must indirectly handle notification to our event loop of the process exit. Refs: https://github.com/libuv/libuv/pull/3441 Refs: https://github.com/libuv/libuv/pull/3257
This commit is contained in:
parent
870828c8af
commit
953f901dd2
@ -145,7 +145,8 @@ typedef struct uv__stream_queued_fds_s uv__stream_queued_fds_t;
|
||||
|
||||
/* loop flags */
|
||||
enum {
|
||||
UV_LOOP_BLOCK_SIGPROF = 1
|
||||
UV_LOOP_BLOCK_SIGPROF = 0x1,
|
||||
UV_LOOP_REAP_CHILDREN = 0x2
|
||||
};
|
||||
|
||||
/* flags of excluding ifaddr */
|
||||
|
||||
@ -285,7 +285,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
for (i = 0; i < nfds; i++) {
|
||||
ev = events + i;
|
||||
if (ev->filter == EVFILT_PROC) {
|
||||
uv__wait_children(loop);
|
||||
loop->flags |= UV_LOOP_REAP_CHILDREN;
|
||||
nevents++;
|
||||
continue;
|
||||
}
|
||||
@ -382,6 +382,11 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
|
||||
nevents++;
|
||||
}
|
||||
|
||||
if (loop->flags & UV_LOOP_REAP_CHILDREN) {
|
||||
loop->flags &= ~UV_LOOP_REAP_CHILDREN;
|
||||
uv__wait_children(loop);
|
||||
}
|
||||
|
||||
if (reset_timeout != 0) {
|
||||
timeout = user_timeout;
|
||||
reset_timeout = 0;
|
||||
|
||||
@ -507,8 +507,12 @@ int uv_spawn(uv_loop_t* loop,
|
||||
#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
struct kevent event;
|
||||
EV_SET(&event, pid, EVFILT_PROC, EV_ADD | EV_ONESHOT, NOTE_EXIT, 0, 0);
|
||||
if (kevent(loop->backend_fd, &event, 1, NULL, 0, NULL))
|
||||
abort();
|
||||
if (kevent(loop->backend_fd, &event, 1, NULL, 0, NULL)) {
|
||||
if (errno != ESRCH)
|
||||
abort();
|
||||
/* Process already exited. Call waitpid on the next loop iteration. */
|
||||
loop->flags |= UV_LOOP_REAP_CHILDREN;
|
||||
}
|
||||
#endif
|
||||
|
||||
QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue);
|
||||
|
||||
Loading…
Reference in New Issue
Block a user