diff --git a/src/unix/internal.h b/src/unix/internal.h index 16be13b9..2dcc8b32 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -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 */ diff --git a/src/unix/kqueue.c b/src/unix/kqueue.c index efbc561d..857eb1d5 100644 --- a/src/unix/kqueue.c +++ b/src/unix/kqueue.c @@ -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; diff --git a/src/unix/process.c b/src/unix/process.c index c1f6bd4b..2920b942 100644 --- a/src/unix/process.c +++ b/src/unix/process.c @@ -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);