From 459dd7b4bc6225e712b25359785558cb61283113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bert=20M=C3=BCnnich?= Date: Sun, 24 Mar 2019 14:32:23 +0100 Subject: Report children as soon as possible when waiting for all The following example demonstrates the problem: ; false & sleep 300 & wait 2317 # pid of false 2318 # pid of sleep # blocking for 300s 2318: done (0) 2817: done (1) With this commit the status for false is reported instantly: ; false & sleep 300 & wait 4205 # pid of false 4206 # pid of sleep 4205: done (1) # blocking for 300s 4206: done (0) --- wait.c | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) (limited to 'wait.c') diff --git a/wait.c b/wait.c index 1ab8533..c997985 100644 --- a/wait.c +++ b/wait.c @@ -48,15 +48,15 @@ extern pid_t rc_fork() { } extern pid_t rc_wait4(pid_t pid, int *stat, bool nointr) { - Pid *r, *prev; + Pid **p, *r; /* Find the child on the list. */ - for (r = plist, prev = NULL; r != NULL; prev = r, r = r->n) - if (r->pid == pid) + for (p = &plist; *p; p = &(*p)->n) + if ((*p)->pid == pid || (pid == -1 && !(*p)->alive)) break; /* Uh-oh, not there. */ - if (r == NULL) { + if (pid != -1 && *p == NULL) { errno = ECHILD; /* no children */ uerror("wait"); *stat = 0x100; /* exit(1) */ @@ -64,9 +64,9 @@ extern pid_t rc_wait4(pid_t pid, int *stat, bool nointr) { } /* If it's still alive, wait() for it. */ - while (r->alive) { + while (*p == NULL || (*p)->alive) { int ret; - Pid *q; + Pid **q; ret = rc_wait(stat); @@ -79,18 +79,19 @@ extern pid_t rc_wait4(pid_t pid, int *stat, bool nointr) { return ret; } - for (q = plist; q != NULL; q = q->n) - if (q->pid == ret) { - q->alive = FALSE; - q->stat = *stat; + for (q = &plist; *q; q = &(*q)->n) + if ((*q)->pid == ret) { + if (pid == -1) + p = q; + (*q)->alive = FALSE; + (*q)->stat = *stat; break; } } + r = *p; + pid = r->pid; *stat = r->stat; - if (prev == NULL) - plist = r->n; /* remove element from head of list */ - else - prev->n = r->n; + *p = r->n; /* remove element from list */ efree(r); return pid; } @@ -115,7 +116,7 @@ extern void waitforall() { int stat; while (plist != NULL) { - pid_t pid = rc_wait4(plist->pid, &stat, FALSE); + pid_t pid = rc_wait4(-1, &stat, FALSE); if (pid > 0) setstatus(pid, stat); else { -- cgit v1.2.3