From 7c709434eccd461a3f3c522df6224adf4e50a8da Mon Sep 17 00:00:00 2001 From: rsc Date: Fri, 18 Mar 2005 19:30:22 +0000 Subject: new files --- src/cmd/netfiles/wait.c | 120 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/cmd/netfiles/wait.c (limited to 'src/cmd/netfiles/wait.c') diff --git a/src/cmd/netfiles/wait.c b/src/cmd/netfiles/wait.c new file mode 100644 index 00000000..6f31a29b --- /dev/null +++ b/src/cmd/netfiles/wait.c @@ -0,0 +1,120 @@ +#include +#include +#include +#include <9pclient.h> +#include "acme.h" + +extern int debug; + +#define dprint if(debug)print + +typedef struct Waitreq Waitreq; +struct Waitreq +{ + int pid; + Channel *c; +}; + +/* + * watch the exiting children + */ +Channel *twaitchan; /* chan(Waitreq) */ +void +waitthread(void *v) +{ + Alt a[3]; + Waitmsg *w, **wq; + Waitreq *rq, r; + int i, nrq, nwq; + + threadsetname("waitthread"); + a[0].c = threadwaitchan(); + a[0].v = &w; + a[0].op = CHANRCV; + a[1].c = twaitchan; + a[1].v = &r; + a[1].op = CHANRCV; + a[2].op = CHANEND; + + nrq = 0; + nwq = 0; + rq = nil; + wq = nil; + dprint("wait: start\n"); + for(;;){ + cont2:; + dprint("wait: alt\n"); + switch(alt(a)){ + case 0: + dprint("wait: pid %d exited\n", w->pid); + for(i=0; ipid){ + dprint("wait: match with rq chan %p\n", rq[i].c); + sendp(rq[i].c, w); + rq[i] = rq[--nrq]; + goto cont2; + } + } + if(i == nrq){ + dprint("wait: queueing waitmsg\n"); + wq = erealloc(wq, (nwq+1)*sizeof(wq[0])); + wq[nwq++] = w; + } + break; + + case 1: + dprint("wait: req for pid %d chan %p\n", r.pid, r.c); + for(i=0; ipid == r.pid){ + dprint("wait: match with waitmsg\n"); + sendp(r.c, w); + wq[i] = wq[--nwq]; + goto cont2; + } + } + if(i == nwq){ + dprint("wait: queueing req\n"); + rq = erealloc(rq, (nrq+1)*sizeof(rq[0])); + rq[nrq] = r; + dprint("wait: queueing req pid %d chan %p\n", rq[nrq].pid, rq[nrq].c); + nrq++; + } + break; + } + } +} + +Waitmsg* +twaitfor(int pid) +{ + Waitreq r; + Waitmsg *w; + + r.pid = pid; + r.c = chancreate(sizeof(Waitmsg*), 1); + send(twaitchan, &r); + w = recvp(r.c); + chanfree(r.c); + return w; +} + +int +twait(int pid) +{ + int x; + Waitmsg *w; + + w = twaitfor(pid); + x = w->msg[0] != 0 ? -1 : 0; + free(w); + return x; +} + +void +twaitinit(void) +{ + threadwaitchan(); /* allocate it before returning */ + twaitchan = chancreate(sizeof(Waitreq), 10); + threadcreate(waitthread, nil, 128*1024); +} + -- cgit v1.2.3