1 4940b552 2006-02-12 devnull #include <u.h>
2 4940b552 2006-02-12 devnull #include <libc.h>
3 4940b552 2006-02-12 devnull #include <thread.h>
5 4940b552 2006-02-12 devnull typedef struct Waiter Waiter;
9 4940b552 2006-02-12 devnull Waitmsg **msg;
10 4940b552 2006-02-12 devnull int nmsg;
11 4940b552 2006-02-12 devnull int muxer;
12 4940b552 2006-02-12 devnull Waiter *head;
13 4940b552 2006-02-12 devnull } waiting;
15 4940b552 2006-02-12 devnull struct Waiter
17 4940b552 2006-02-12 devnull Rendez r;
18 4940b552 2006-02-12 devnull Waitmsg *msg;
20 4940b552 2006-02-12 devnull Waiter *next;
21 4940b552 2006-02-12 devnull Waiter *prev;
24 4940b552 2006-02-12 devnull /* see src/libmux/mux.c */
26 4940b552 2006-02-12 devnull procwait(int pid)
28 4940b552 2006-02-12 devnull Waiter *w;
29 4940b552 2006-02-12 devnull Waiter me;
30 4940b552 2006-02-12 devnull Waitmsg *msg;
33 4940b552 2006-02-12 devnull memset(&me, 0, sizeof me);
34 4940b552 2006-02-12 devnull me.pid = pid;
35 4940b552 2006-02-12 devnull me.r.l = &waiting.lk;
37 4940b552 2006-02-12 devnull qlock(&waiting.lk);
38 4940b552 2006-02-12 devnull for(i=0; i<waiting.nmsg; i++){
39 4940b552 2006-02-12 devnull if(waiting.msg[i]->pid == pid){
40 4940b552 2006-02-12 devnull msg = waiting.msg[i];
41 4940b552 2006-02-12 devnull waiting.msg[i] = waiting.msg[--waiting.nmsg];
42 4940b552 2006-02-12 devnull qunlock(&waiting.lk);
43 4940b552 2006-02-12 devnull return msg;
46 4940b552 2006-02-12 devnull me.next = waiting.head;
47 4940b552 2006-02-12 devnull me.prev = nil;
48 4940b552 2006-02-12 devnull if(me.next)
49 4940b552 2006-02-12 devnull me.next->prev = &me;
50 4940b552 2006-02-12 devnull waiting.head = &me;
51 4940b552 2006-02-12 devnull while(waiting.muxer && me.msg==nil)
52 4940b552 2006-02-12 devnull rsleep(&me.r);
54 4940b552 2006-02-12 devnull if(!me.msg){
55 4940b552 2006-02-12 devnull if(waiting.muxer)
57 4940b552 2006-02-12 devnull waiting.muxer = 1;
58 4940b552 2006-02-12 devnull while(!me.msg){
59 4940b552 2006-02-12 devnull qunlock(&waiting.lk);
60 4940b552 2006-02-12 devnull msg = recvp(threadwaitchan());
61 4940b552 2006-02-12 devnull qlock(&waiting.lk);
62 4940b552 2006-02-12 devnull if(msg == nil) /* shouldn't happen */
64 4940b552 2006-02-12 devnull for(w=waiting.head; w; w=w->next)
65 4940b552 2006-02-12 devnull if(w->pid == msg->pid)
68 4940b552 2006-02-12 devnull if(w->prev)
69 4940b552 2006-02-12 devnull w->prev->next = w->next;
71 4940b552 2006-02-12 devnull waiting.head = w->next;
72 4940b552 2006-02-12 devnull if(w->next)
73 4940b552 2006-02-12 devnull w->next->prev = w->prev;
74 4940b552 2006-02-12 devnull me.msg = msg;
75 4940b552 2006-02-12 devnull rwakeup(&w->r);
77 4940b552 2006-02-12 devnull waiting.msg = realloc(waiting.msg, (waiting.nmsg+1)*sizeof waiting.msg[0]);
78 4940b552 2006-02-12 devnull if(waiting.msg == nil)
79 4940b552 2006-02-12 devnull sysfatal("out of memory");
80 4940b552 2006-02-12 devnull waiting.msg[waiting.nmsg++] = msg;
83 4940b552 2006-02-12 devnull waiting.muxer = 0;
84 4940b552 2006-02-12 devnull if(waiting.head)
85 4940b552 2006-02-12 devnull rwakeup(&waiting.head->r);
87 4940b552 2006-02-12 devnull qunlock(&waiting.lk);
88 4940b552 2006-02-12 devnull if (me.msg->pid < 0) {
89 4940b552 2006-02-12 devnull free(me.msg);
90 4940b552 2006-02-12 devnull me.msg = 0;
92 4940b552 2006-02-12 devnull return me.msg;