Blame


1 d3df3087 2003-12-06 devnull /* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
2 d3df3087 2003-12-06 devnull /* See COPYRIGHT */
3 d3df3087 2003-12-06 devnull
4 d3df3087 2003-12-06 devnull #include <u.h>
5 d3df3087 2003-12-06 devnull #include <libc.h>
6 d3df3087 2003-12-06 devnull #include <mux.h>
7 d3df3087 2003-12-06 devnull
8 d3df3087 2003-12-06 devnull /*
9 d3df3087 2003-12-06 devnull * If you fork off two procs running muxrecvproc and muxsendproc,
10 d3df3087 2003-12-06 devnull * then muxrecv/muxsend (and thus muxrpc) will never block except on
11 d3df3087 2003-12-06 devnull * rendevouses, which is nice when it's running in one thread of many.
12 d3df3087 2003-12-06 devnull */
13 d3df3087 2003-12-06 devnull void
14 d3df3087 2003-12-06 devnull _muxrecvproc(void *v)
15 d3df3087 2003-12-06 devnull {
16 d3df3087 2003-12-06 devnull void *p;
17 d3df3087 2003-12-06 devnull Mux *mux;
18 d3df3087 2003-12-06 devnull Muxqueue *q;
19 d3df3087 2003-12-06 devnull
20 d3df3087 2003-12-06 devnull mux = v;
21 d3df3087 2003-12-06 devnull q = _muxqalloc();
22 d3df3087 2003-12-06 devnull
23 d3df3087 2003-12-06 devnull qlock(&mux->lk);
24 d3df3087 2003-12-06 devnull mux->readq = q;
25 d3df3087 2003-12-06 devnull qlock(&mux->inlk);
26 d3df3087 2003-12-06 devnull rwakeup(&mux->rpcfork);
27 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
28 d3df3087 2003-12-06 devnull
29 d3df3087 2003-12-06 devnull while((p = mux->recv(mux)) != nil)
30 d3df3087 2003-12-06 devnull if(_muxqsend(q, p) < 0){
31 d3df3087 2003-12-06 devnull free(p);
32 d3df3087 2003-12-06 devnull break;
33 d3df3087 2003-12-06 devnull }
34 d3df3087 2003-12-06 devnull qunlock(&mux->inlk);
35 d3df3087 2003-12-06 devnull qlock(&mux->lk);
36 d3df3087 2003-12-06 devnull _muxqhangup(q);
37 d3df3087 2003-12-06 devnull while((p = _muxnbqrecv(q)) != nil)
38 d3df3087 2003-12-06 devnull free(p);
39 d3df3087 2003-12-06 devnull free(q);
40 d3df3087 2003-12-06 devnull mux->readq = nil;
41 d3df3087 2003-12-06 devnull rwakeup(&mux->rpcfork);
42 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
43 d3df3087 2003-12-06 devnull }
44 d3df3087 2003-12-06 devnull
45 d3df3087 2003-12-06 devnull void
46 d3df3087 2003-12-06 devnull _muxsendproc(void *v)
47 d3df3087 2003-12-06 devnull {
48 d3df3087 2003-12-06 devnull Muxqueue *q;
49 d3df3087 2003-12-06 devnull void *p;
50 d3df3087 2003-12-06 devnull Mux *mux;
51 d3df3087 2003-12-06 devnull
52 d3df3087 2003-12-06 devnull mux = v;
53 d3df3087 2003-12-06 devnull q = _muxqalloc();
54 d3df3087 2003-12-06 devnull
55 d3df3087 2003-12-06 devnull qlock(&mux->lk);
56 d3df3087 2003-12-06 devnull mux->writeq = q;
57 d3df3087 2003-12-06 devnull qlock(&mux->outlk);
58 d3df3087 2003-12-06 devnull rwakeup(&mux->rpcfork);
59 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
60 d3df3087 2003-12-06 devnull
61 d3df3087 2003-12-06 devnull while((p = _muxqrecv(q)) != nil)
62 d3df3087 2003-12-06 devnull if(mux->send(mux, p) < 0)
63 d3df3087 2003-12-06 devnull break;
64 d3df3087 2003-12-06 devnull qunlock(&mux->outlk);
65 d3df3087 2003-12-06 devnull qlock(&mux->lk);
66 d3df3087 2003-12-06 devnull _muxqhangup(q);
67 d3df3087 2003-12-06 devnull while((p = _muxnbqrecv(q)) != nil)
68 d3df3087 2003-12-06 devnull free(p);
69 d3df3087 2003-12-06 devnull free(q);
70 d3df3087 2003-12-06 devnull mux->writeq = nil;
71 d3df3087 2003-12-06 devnull rwakeup(&mux->rpcfork);
72 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
73 d3df3087 2003-12-06 devnull return;
74 d3df3087 2003-12-06 devnull }
75 d3df3087 2003-12-06 devnull
76 d3df3087 2003-12-06 devnull void*
77 2d2e5c71 2006-06-25 devnull _muxrecv(Mux *mux, int canblock)
78 d3df3087 2003-12-06 devnull {
79 d3df3087 2003-12-06 devnull void *p;
80 d3df3087 2003-12-06 devnull
81 d3df3087 2003-12-06 devnull qlock(&mux->lk);
82 d3df3087 2003-12-06 devnull /*
83 d3df3087 2003-12-06 devnull if(mux->state != VtStateConnected){
84 d3df3087 2003-12-06 devnull werrstr("not connected");
85 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
86 d3df3087 2003-12-06 devnull return nil;
87 d3df3087 2003-12-06 devnull }
88 d3df3087 2003-12-06 devnull */
89 d3df3087 2003-12-06 devnull if(mux->readq){
90 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
91 2d2e5c71 2006-06-25 devnull if(canblock)
92 2d2e5c71 2006-06-25 devnull return _muxqrecv(mux->readq);
93 2d2e5c71 2006-06-25 devnull return _muxnbqrecv(mux->readq);
94 d3df3087 2003-12-06 devnull }
95 d3df3087 2003-12-06 devnull
96 d3df3087 2003-12-06 devnull qlock(&mux->inlk);
97 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
98 2d2e5c71 2006-06-25 devnull if(canblock)
99 2d2e5c71 2006-06-25 devnull p = mux->recv(mux);
100 2d2e5c71 2006-06-25 devnull else{
101 2d2e5c71 2006-06-25 devnull if(mux->nbrecv)
102 2d2e5c71 2006-06-25 devnull p = mux->nbrecv(mux);
103 2d2e5c71 2006-06-25 devnull else
104 2d2e5c71 2006-06-25 devnull p = nil;
105 2d2e5c71 2006-06-25 devnull }
106 d3df3087 2003-12-06 devnull qunlock(&mux->inlk);
107 d3df3087 2003-12-06 devnull /*
108 2d2e5c71 2006-06-25 devnull if(!p && canblock)
109 d3df3087 2003-12-06 devnull vthangup(mux);
110 d3df3087 2003-12-06 devnull */
111 d3df3087 2003-12-06 devnull return p;
112 d3df3087 2003-12-06 devnull }
113 d3df3087 2003-12-06 devnull
114 d3df3087 2003-12-06 devnull int
115 d3df3087 2003-12-06 devnull _muxsend(Mux *mux, void *p)
116 d3df3087 2003-12-06 devnull {
117 d3df3087 2003-12-06 devnull qlock(&mux->lk);
118 d3df3087 2003-12-06 devnull /*
119 d3df3087 2003-12-06 devnull if(mux->state != VtStateConnected){
120 d3df3087 2003-12-06 devnull packetfree(p);
121 d3df3087 2003-12-06 devnull werrstr("not connected");
122 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
123 d3df3087 2003-12-06 devnull return -1;
124 d3df3087 2003-12-06 devnull }
125 d3df3087 2003-12-06 devnull */
126 d3df3087 2003-12-06 devnull if(mux->writeq){
127 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
128 d3df3087 2003-12-06 devnull if(_muxqsend(mux->writeq, p) < 0){
129 d3df3087 2003-12-06 devnull free(p);
130 d3df3087 2003-12-06 devnull return -1;
131 d3df3087 2003-12-06 devnull }
132 d3df3087 2003-12-06 devnull return 0;
133 d3df3087 2003-12-06 devnull }
134 d3df3087 2003-12-06 devnull
135 d3df3087 2003-12-06 devnull qlock(&mux->outlk);
136 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
137 d3df3087 2003-12-06 devnull if(mux->send(mux, p) < 0){
138 d3df3087 2003-12-06 devnull qunlock(&mux->outlk);
139 d3df3087 2003-12-06 devnull /* vthangup(mux); */
140 d3df3087 2003-12-06 devnull return -1;
141 d3df3087 2003-12-06 devnull }
142 d3df3087 2003-12-06 devnull qunlock(&mux->outlk);
143 d3df3087 2003-12-06 devnull return 0;
144 d3df3087 2003-12-06 devnull }
145 d3df3087 2003-12-06 devnull