diff options
author | rsc <devnull@localhost> | 2005-03-18 19:30:22 +0000 |
---|---|---|
committer | rsc <devnull@localhost> | 2005-03-18 19:30:22 +0000 |
commit | 7c709434eccd461a3f3c522df6224adf4e50a8da (patch) | |
tree | 07824349dbc0e919ab411b254cca583e5f6feb7d /src/cmd/netfiles/wait.c | |
parent | 72fd2f881907db5e367ffee1fcecb737c44a0090 (diff) | |
download | plan9port-7c709434eccd461a3f3c522df6224adf4e50a8da.tar.gz plan9port-7c709434eccd461a3f3c522df6224adf4e50a8da.tar.bz2 plan9port-7c709434eccd461a3f3c522df6224adf4e50a8da.zip |
new files
Diffstat (limited to 'src/cmd/netfiles/wait.c')
-rw-r--r-- | src/cmd/netfiles/wait.c | 120 |
1 files changed, 120 insertions, 0 deletions
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 <u.h> +#include <libc.h> +#include <thread.h> +#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; i<nrq; i++){ + if(rq[i].pid == w->pid){ + 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; i<nwq; i++){ + if(w->pid == 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); +} + |