URI:
       twait.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       twait.c (1988B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <thread.h>
            4 #include <9pclient.h>
            5 #include "acme.h"
            6 
            7 extern int debug;
            8 
            9 #define dprint if(debug>1)print
           10 
           11 typedef struct Waitreq Waitreq;
           12 struct Waitreq
           13 {
           14         int pid;
           15         Channel *c;
           16 };
           17 
           18 /*
           19  * watch the exiting children
           20  */
           21 Channel *twaitchan;        /* chan(Waitreq) */
           22 void
           23 waitthread(void *v)
           24 {
           25         Alt a[3];
           26         Waitmsg *w, **wq;
           27         Waitreq *rq, r;
           28         int i, nrq, nwq;
           29 
           30         threadsetname("waitthread");
           31         a[0].c = threadwaitchan();
           32         a[0].v = &w;
           33         a[0].op = CHANRCV;
           34         a[1].c = twaitchan;
           35         a[1].v = &r;
           36         a[1].op = CHANRCV;
           37         a[2].op = CHANEND;
           38 
           39         nrq = 0;
           40         nwq = 0;
           41         rq = nil;
           42         wq = nil;
           43         dprint("wait: start\n");
           44         for(;;){
           45         cont2:;
           46                 dprint("wait: alt\n");
           47                 switch(alt(a)){
           48                 case 0:
           49                         dprint("wait: pid %d exited\n", w->pid);
           50                         for(i=0; i<nrq; i++){
           51                                 if(rq[i].pid == w->pid){
           52                                         dprint("wait: match with rq chan %p\n", rq[i].c);
           53                                         sendp(rq[i].c, w);
           54                                         rq[i] = rq[--nrq];
           55                                         goto cont2;
           56                                 }
           57                         }
           58                         if(i == nrq){
           59                                 dprint("wait: queueing waitmsg\n");
           60                                 wq = erealloc(wq, (nwq+1)*sizeof(wq[0]));
           61                                 wq[nwq++] = w;
           62                         }
           63                         break;
           64 
           65                 case 1:
           66                         dprint("wait: req for pid %d chan %p\n", r.pid, r.c);
           67                         for(i=0; i<nwq; i++){
           68                                 if(w->pid == r.pid){
           69                                         dprint("wait: match with waitmsg\n");
           70                                         sendp(r.c, w);
           71                                         wq[i] = wq[--nwq];
           72                                         goto cont2;
           73                                 }
           74                         }
           75                         if(i == nwq){
           76                                 dprint("wait: queueing req\n");
           77                                 rq = erealloc(rq, (nrq+1)*sizeof(rq[0]));
           78                                 rq[nrq] = r;
           79                                 dprint("wait: queueing req pid %d chan %p\n", rq[nrq].pid, rq[nrq].c);
           80                                 nrq++;
           81                         }
           82                         break;
           83                 }
           84         }
           85 }
           86 
           87 Waitmsg*
           88 twaitfor(int pid)
           89 {
           90         Waitreq r;
           91         Waitmsg *w;
           92 
           93         r.pid = pid;
           94         r.c = chancreate(sizeof(Waitmsg*), 1);
           95         send(twaitchan, &r);
           96         w = recvp(r.c);
           97         chanfree(r.c);
           98         return w;
           99 }
          100 
          101 int
          102 twait(int pid)
          103 {
          104         int x;
          105         Waitmsg *w;
          106 
          107         w = twaitfor(pid);
          108         x = w->msg[0] != 0 ? -1 : 0;
          109         free(w);
          110         return x;
          111 }
          112 
          113 void
          114 twaitinit(void)
          115 {
          116         threadwaitchan();        /* allocate it before returning */
          117         twaitchan = chancreate(sizeof(Waitreq), 10);
          118         threadcreate(waitthread, nil, 128*1024);
          119 }