From 77611280935dfbd7b976fd9340bf8593bf4320f1 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Sat, 7 Dec 2013 07:17:32 +0100 Subject: 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(). --- sys/src/9/port/devproc.c | 29 +++++++++++++++++++++-------- sys/src/9/port/portfns.h | 1 - sys/src/9/port/proc.c | 2 +- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/sys/src/9/port/devproc.c b/sys/src/9/port/devproc.c index e5fd24671..86e2ceba3 100644 --- a/sys/src/9/port/devproc.c +++ b/sys/src/9/port/devproc.c @@ -680,12 +680,23 @@ eventsavailable(void *) 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 @@ procread(Chan *c, void *va, long n, vlong off) } 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 @@ procstopwait(Proc *p, int ctl) 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()) { diff --git a/sys/src/9/port/portfns.h b/sys/src/9/port/portfns.h index ffeb7315a..6b27eaf2c 100644 --- a/sys/src/9/port/portfns.h +++ b/sys/src/9/port/portfns.h @@ -124,7 +124,6 @@ ulong getmalloctag(void*); ulong getrealloctag(void*); void gotolabel(Label*); char* getconfenv(void); -int haswaitq(void*); long hostdomainwrite(char*, int); long hostownerwrite(char*, int); void hzsched(void); diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c index 838ad49a1..ed549fb75 100644 --- a/sys/src/9/port/proc.c +++ b/sys/src/9/port/proc.c @@ -1205,7 +1205,7 @@ pexit(char *exitstr, int freemem) panic("pexit"); } -int +static int haswaitq(void *x) { Proc *p; -- cgit v1.2.3