From 2d5eaea1cd6a6d1f83f7771d55288ad1dc2b3547 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sa=C3=BAl=20Ibarra=20Corretg=C3=A9?= Date: Mon, 5 May 2014 17:15:15 -0300 Subject: [PATCH] unix: simplify how process handle queue is managed --- include/uv-unix.h | 2 +- src/unix/loop.c | 5 +-- src/unix/process.c | 92 ++++++++++++++++++++-------------------------- 3 files changed, 41 insertions(+), 58 deletions(-) diff --git a/include/uv-unix.h b/include/uv-unix.h index fe74f327..e7249256 100644 --- a/include/uv-unix.h +++ b/include/uv-unix.h @@ -219,7 +219,7 @@ typedef struct { uv_async_t wq_async; \ uv_rwlock_t cloexec_lock; \ uv_handle_t* closing_handles; \ - void* process_handles[1][2]; \ + void* process_handles[2]; \ void* prepare_handles[2]; \ void* check_handles[2]; \ void* idle_handles[2]; \ diff --git a/src/unix/loop.c b/src/unix/loop.c index aa74be64..00222485 100644 --- a/src/unix/loop.c +++ b/src/unix/loop.c @@ -99,7 +99,6 @@ void uv_loop_delete(uv_loop_t* loop) { static int uv__loop_init(uv_loop_t* loop, int default_loop) { - unsigned int i; int err; uv__signal_global_once_init(); @@ -138,9 +137,7 @@ static int uv__loop_init(uv_loop_t* loop, int default_loop) { uv_signal_init(loop, &loop->child_watcher); uv__handle_unref(&loop->child_watcher); loop->child_watcher.flags |= UV__HANDLE_INTERNAL; - - for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) - QUEUE_INIT(loop->process_handles + i); + QUEUE_INIT(&loop->process_handles); if (uv_rwlock_init(&loop->cloexec_lock)) abort(); diff --git a/src/unix/process.c b/src/unix/process.c index 52e4eb28..9d13721e 100644 --- a/src/unix/process.c +++ b/src/unix/process.c @@ -45,77 +45,65 @@ extern char **environ; #endif -static QUEUE* uv__process_queue(uv_loop_t* loop, int pid) { - assert(pid > 0); - return loop->process_handles + pid % ARRAY_SIZE(loop->process_handles); -} - - static void uv__chld(uv_signal_t* handle, int signum) { uv_process_t* process; uv_loop_t* loop; int exit_status; int term_signal; - unsigned int i; int status; pid_t pid; QUEUE pending; - QUEUE* h; QUEUE* q; + QUEUE* h; assert(signum == SIGCHLD); QUEUE_INIT(&pending); loop = handle->loop; - for (i = 0; i < ARRAY_SIZE(loop->process_handles); i++) { - h = loop->process_handles + i; - q = QUEUE_HEAD(h); + h = &loop->process_handles; + q = QUEUE_HEAD(h); + while (q != h) { + process = QUEUE_DATA(q, uv_process_t, queue); + q = QUEUE_NEXT(q); - while (q != h) { - process = QUEUE_DATA(q, uv_process_t, queue); - q = QUEUE_NEXT(q); + do + pid = waitpid(process->pid, &status, WNOHANG); + while (pid == -1 && errno == EINTR); - do - pid = waitpid(process->pid, &status, WNOHANG); - while (pid == -1 && errno == EINTR); + if (pid == 0) + continue; - if (pid == 0) - continue; - - if (pid == -1) { - if (errno != ECHILD) - abort(); - continue; - } - - process->status = status; - QUEUE_REMOVE(&process->queue); - QUEUE_INSERT_TAIL(&pending, &process->queue); + if (pid == -1) { + if (errno != ECHILD) + abort(); + continue; } - while (!QUEUE_EMPTY(&pending)) { - q = QUEUE_HEAD(&pending); - QUEUE_REMOVE(q); - QUEUE_INIT(q); - - process = QUEUE_DATA(q, uv_process_t, queue); - uv__handle_stop(process); - - if (process->exit_cb == NULL) - continue; - - exit_status = 0; - if (WIFEXITED(process->status)) - exit_status = WEXITSTATUS(process->status); - - term_signal = 0; - if (WIFSIGNALED(process->status)) - term_signal = WTERMSIG(process->status); - - process->exit_cb(process, exit_status, term_signal); - } + process->status = status; + QUEUE_REMOVE(&process->queue); + QUEUE_INSERT_TAIL(&pending, &process->queue); } + + QUEUE_FOREACH(q, &pending) { + process = QUEUE_DATA(q, uv_process_t, queue); + QUEUE_REMOVE(q); + uv__handle_stop(process); + + if (process->exit_cb == NULL) + continue; + + exit_status = 0; + if (WIFEXITED(process->status)) + exit_status = WEXITSTATUS(process->status); + + term_signal = 0; + if (WIFSIGNALED(process->status)) + term_signal = WTERMSIG(process->status); + + process->exit_cb(process, exit_status, term_signal); + } + assert(QUEUE_EMPTY(&pending)); } @@ -369,7 +357,6 @@ int uv_spawn(uv_loop_t* loop, int signal_pipe[2] = { -1, -1 }; int (*pipes)[2]; int stdio_count; - QUEUE* q; ssize_t r; pid_t pid; int err; @@ -483,8 +470,7 @@ int uv_spawn(uv_loop_t* loop, /* Only activate this handle if exec() happened successfully */ if (exec_errorno == 0) { - q = uv__process_queue(loop, pid); - QUEUE_INSERT_TAIL(q, &process->queue); + QUEUE_INSERT_TAIL(&loop->process_handles, &process->queue); uv__handle_start(process); }