Blame


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>
4 4940b552 2006-02-12 devnull
5 4940b552 2006-02-12 devnull typedef struct Waiter Waiter;
6 4940b552 2006-02-12 devnull
7 4940b552 2006-02-12 devnull struct {
8 4940b552 2006-02-12 devnull QLock lk;
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;
14 4940b552 2006-02-12 devnull
15 4940b552 2006-02-12 devnull struct Waiter
16 4940b552 2006-02-12 devnull {
17 4940b552 2006-02-12 devnull Rendez r;
18 4940b552 2006-02-12 devnull Waitmsg *msg;
19 4940b552 2006-02-12 devnull int pid;
20 4940b552 2006-02-12 devnull Waiter *next;
21 4940b552 2006-02-12 devnull Waiter *prev;
22 4940b552 2006-02-12 devnull };
23 4940b552 2006-02-12 devnull
24 4940b552 2006-02-12 devnull /* see src/libmux/mux.c */
25 4940b552 2006-02-12 devnull Waitmsg*
26 4940b552 2006-02-12 devnull procwait(int pid)
27 4940b552 2006-02-12 devnull {
28 4940b552 2006-02-12 devnull Waiter *w;
29 4940b552 2006-02-12 devnull Waiter me;
30 4940b552 2006-02-12 devnull Waitmsg *msg;
31 4940b552 2006-02-12 devnull int i;
32 fa325e9b 2020-01-10 cross
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;
36 fa325e9b 2020-01-10 cross
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;
44 4940b552 2006-02-12 devnull }
45 4940b552 2006-02-12 devnull }
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);
53 4940b552 2006-02-12 devnull
54 4940b552 2006-02-12 devnull if(!me.msg){
55 4940b552 2006-02-12 devnull if(waiting.muxer)
56 4940b552 2006-02-12 devnull abort();
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 */
63 4940b552 2006-02-12 devnull break;
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)
66 4940b552 2006-02-12 devnull break;
67 4940b552 2006-02-12 devnull if(w){
68 4940b552 2006-02-12 devnull if(w->prev)
69 4940b552 2006-02-12 devnull w->prev->next = w->next;
70 4940b552 2006-02-12 devnull else
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);
76 4940b552 2006-02-12 devnull }else{
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;
81 4940b552 2006-02-12 devnull }
82 4940b552 2006-02-12 devnull }
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);
86 4940b552 2006-02-12 devnull }
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;
91 4940b552 2006-02-12 devnull }
92 4940b552 2006-02-12 devnull return me.msg;
93 4940b552 2006-02-12 devnull }