summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@gmx.de>2012-08-24 13:11:04 +0200
committercinap_lenrek <cinap_lenrek@gmx.de>2012-08-24 13:11:04 +0200
commit86f323290c9f99b72e359ff2c37eed528f5b3976 (patch)
treefdac2c5cfdcc0136a827fb1e86bb950cfcba4237
parentd404e9e9f8250f740bacb0b30d586ea1ad808015 (diff)
wait: always check up->nchild before going to sleep
always make sure that there are child processes we can wait for before sleeping. put pwait() sleep into a loop and recheck. this is not strictly neccesary but prevents accidents if there are spurious wakeups or a bug.
-rw-r--r--sys/src/9/port/devproc.c8
-rw-r--r--sys/src/9/port/proc.c14
2 files changed, 11 insertions, 11 deletions
diff --git a/sys/src/9/port/devproc.c b/sys/src/9/port/devproc.c
index d11937c17..5f777d864 100644
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -908,12 +908,12 @@ procread(Chan *c, void *va, long n, vlong off)
}
lock(&p->exl);
- if(up == p && p->nchild == 0 && p->waitq == 0) {
- unlock(&p->exl);
- error(Enochild);
- }
pid = p->pid;
while(p->waitq == 0) {
+ if(up == p && p->nchild == 0) {
+ unlock(&p->exl);
+ error(Enochild);
+ }
unlock(&p->exl);
sleep(&p->waitr, haswaitq, p);
if(p->pid != pid)
diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c
index a13164d8d..76aa3d0dd 100644
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -1229,15 +1229,15 @@ pwait(Waitmsg *w)
}
lock(&up->exl);
- if(up->nchild == 0 && up->waitq == 0) {
+ while(up->waitq == 0) {
+ if(up->nchild == 0) {
+ unlock(&up->exl);
+ error(Enochild);
+ }
unlock(&up->exl);
- error(Enochild);
+ sleep(&up->waitr, haswaitq, up);
+ lock(&up->exl);
}
- unlock(&up->exl);
-
- sleep(&up->waitr, haswaitq, up);
-
- lock(&up->exl);
wq = up->waitq;
up->waitq = wq->next;
up->nwait--;