commit 459dd7b4bc6225e712b25359785558cb61283113
parent 041360f4f34aad297b173e64e0a72956bd86415f
Author: Bert Münnich <ber.t@posteo.de>
Date: Sun, 24 Mar 2019 14:32:23 +0100
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)
Diffstat:
M | wait.c | | | 31 | ++++++++++++++++--------------- |
1 file changed, 16 insertions(+), 15 deletions(-)
diff --git 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 {