Skip to content

Commit

Permalink
Fix child_process.spawn slowness on macOS
Browse files Browse the repository at this point in the history
  • Loading branch information
rogerwang committed Sep 21, 2022
1 parent f08c285 commit 625b355
Show file tree
Hide file tree
Showing 7 changed files with 725 additions and 157 deletions.
32 changes: 3 additions & 29 deletions deps/uv/src/unix/core.c
Expand Up @@ -597,20 +597,6 @@ int uv__nonblock_ioctl(int fd, int set) {

return 0;
}


int uv__cloexec_ioctl(int fd, int set) {
int r;

do
r = ioctl(fd, set ? FIOCLEX : FIONCLEX);
while (r == -1 && errno == EINTR);

if (r)
return UV__ERR(errno);

return 0;
}
#endif


Expand Down Expand Up @@ -645,25 +631,13 @@ int uv__nonblock_fcntl(int fd, int set) {
}


int uv__cloexec_fcntl(int fd, int set) {
int uv__cloexec(int fd, int set) {
int flags;
int r;

do
r = fcntl(fd, F_GETFD);
while (r == -1 && errno == EINTR);

if (r == -1)
return UV__ERR(errno);

/* Bail out now if already set/clear. */
if (!!(r & FD_CLOEXEC) == !!set)
return 0;

flags = 0;
if (set)
flags = r | FD_CLOEXEC;
else
flags = r & ~FD_CLOEXEC;
flags = FD_CLOEXEC;

do
r = fcntl(fd, F_SETFD, flags);
Expand Down
9 changes: 4 additions & 5 deletions deps/uv/src/unix/internal.h
Expand Up @@ -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 */
Expand Down Expand Up @@ -174,11 +175,9 @@ struct uv__stream_queued_fds_s {
defined(__linux__) || \
defined(__OpenBSD__) || \
defined(__NetBSD__)
#define uv__cloexec uv__cloexec_ioctl
#define uv__nonblock uv__nonblock_ioctl
#define UV__NONBLOCK_IS_IOCTL 1
#else
#define uv__cloexec uv__cloexec_fcntl
#define uv__nonblock uv__nonblock_fcntl
#define UV__NONBLOCK_IS_IOCTL 0
#endif
Expand All @@ -196,8 +195,7 @@ struct uv__stream_queued_fds_s {
#endif

/* core */
int uv__cloexec_ioctl(int fd, int set);
int uv__cloexec_fcntl(int fd, int set);
int uv__cloexec(int fd, int set);
int uv__nonblock_ioctl(int fd, int set);
int uv__nonblock_fcntl(int fd, int set);
int uv__close(int fd); /* preserves errno */
Expand Down Expand Up @@ -282,6 +280,7 @@ uv_handle_type uv__handle_type(int fd);
FILE* uv__open_file(const char* path);
int uv__getpwuid_r(uv_passwd_t* pwd);
int uv__search_path(const char* prog, char* buf, size_t* buflen);
void uv__wait_children(uv_loop_t* loop);

/* random */
int uv__random_devurandom(void* buf, size_t buflen);
Expand Down
21 changes: 21 additions & 0 deletions deps/uv/src/unix/kqueue.c
Expand Up @@ -119,6 +119,7 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
unsigned int revents;
QUEUE* q;
uv__io_t* w;
uv_process_t* process;
sigset_t* pset;
sigset_t set;
uint64_t base;
Expand Down Expand Up @@ -289,6 +290,21 @@ void uv__io_poll(uv_loop_t* loop, int timeout) {
for (i = 0; i < nfds; i++) {
ev = events + i;
fd = ev->ident;

/* Handle kevent NOTE_EXIT results */
if (ev->filter == EVFILT_PROC) {
QUEUE_FOREACH(q, &loop->process_handles) {
process = QUEUE_DATA(q, uv_process_t, queue);
if (process->pid == fd) {
process->flags |= UV_HANDLE_REAP;
loop->flags |= UV_LOOP_REAP_CHILDREN;
break;
}
}
nevents++;
continue;
}

/* Skip invalidated events, see uv__platform_invalidate_fd */
if (fd == -1)
continue;
Expand Down Expand Up @@ -381,6 +397,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;
Expand Down

0 comments on commit 625b355

Please sign in to comment.