git: 9front

Download patch

ref: 5394183be76afba9d039055abd605df8e58daeb5
parent: dd2b536491fd56e9296df648d0fcb101cde24995
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Fri Aug 24 09:11:04 EDT 2012

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.

--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -908,12 +908,12 @@
 		}
 
 		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)
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -1229,15 +1229,15 @@
 	}
 
 	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--;
--