unix: simplify how process handle queue is managed

This commit is contained in:
Saúl Ibarra Corretgé 2014-05-05 17:15:15 -03:00
parent ae6197d730
commit 2d5eaea1cd
3 changed files with 41 additions and 58 deletions

View File

@ -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]; \

View File

@ -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();

View File

@ -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);
}