ref: 77611280935dfbd7b976fd9340bf8593bf4320f1
parent: 4fd55abb8e6dc11b257699cbd095fa5ef60e1ece
author: cinap_lenrek <[email protected]>
date: Sat Dec 7 02:17:32 EST 2013
devproc: make sure /proc/n/wait waits for the right process children theres a race when we wait for a process children and that process exits before we sleep().
--- a/sys/src/9/port/devproc.c
+++ b/sys/src/9/port/devproc.c
@@ -680,12 +680,23 @@
return tproduced > tconsumed;
}
+static int
+prochaswaitq(void *x)
+{
+ Chan *c;
+ Proc *p;
+
+ c = (Chan *)x;
+ p = proctab(SLOT(c->qid));
+ return p->pid != PID(c->qid) || p->waitq != 0;
+}
+
static long
procread(Chan *c, void *va, long n, vlong off)
{
/* NSEG*32 was too small for worst cases */
char *a, flag[10], *sps, *srv, statbuf[NSEG*64];
- int i, j, m, navail, ne, pid, rsize;
+ int i, j, m, navail, ne, rsize;
long l;
uchar *rptr;
ulong offset;
@@ -924,18 +935,19 @@
}
lock(&p->exl);
- pid = p->pid;
- while(p->waitq == 0) {
+ while(p->waitq == 0 && p->pid == PID(c->qid)) {
if(up == p && p->nchild == 0) {
unlock(&p->exl);
error(Enochild);
}
unlock(&p->exl);
- sleep(&p->waitr, haswaitq, p);
- if(p->pid != pid)
- error(Eprocdied);
+ sleep(&p->waitr, prochaswaitq, c);
lock(&p->exl);
}
+ if(p->pid != PID(c->qid)){
+ unlock(&p->exl);
+ error(Eprocdied);
+ }
wq = p->waitq;
p->waitq = wq->next;
p->nwait--;
@@ -1229,11 +1241,12 @@
error(Einuse);
if(procstopped(p) || p->state == Broken)
return;
-
+ pid = p->pid;
+ if(pid == 0)
+ error(Eprocdied);
if(ctl != 0)
p->procctl = ctl;
p->pdbg = up;
- pid = p->pid;
qunlock(&p->debug);
up->psstate = "Stopwait";
if(waserror()) {
--- a/sys/src/9/port/portfns.h
+++ b/sys/src/9/port/portfns.h
@@ -124,7 +124,6 @@
ulong getrealloctag(void*);
void gotolabel(Label*);
char* getconfenv(void);
-int haswaitq(void*);
long hostdomainwrite(char*, int);
long hostownerwrite(char*, int);
void hzsched(void);
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -1205,7 +1205,7 @@
panic("pexit");
}
-int
+static int
haswaitq(void *x)
{
Proc *p;