1 d3df3087 2003-12-06 devnull /* Copyright (C) 2003 Russ Cox, Massachusetts Institute of Technology */
2 d3df3087 2003-12-06 devnull /* See COPYRIGHT */
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>
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.
14 d3df3087 2003-12-06 devnull _muxrecvproc(void *v)
17 d3df3087 2003-12-06 devnull Mux *mux;
18 d3df3087 2003-12-06 devnull Muxqueue *q;
21 d3df3087 2003-12-06 devnull q = _muxqalloc();
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);
29 d3df3087 2003-12-06 devnull while((p = mux->recv(mux)) != nil)
30 d3df3087 2003-12-06 devnull if(_muxqsend(q, p) < 0){
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);
38 454ae2ad 2008-05-06 rsc while(_muxnbqrecv(q, &p) && p != nil){
43 d3df3087 2003-12-06 devnull mux->readq = nil;
44 d3df3087 2003-12-06 devnull rwakeup(&mux->rpcfork);
45 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
49 d3df3087 2003-12-06 devnull _muxsendproc(void *v)
51 d3df3087 2003-12-06 devnull Muxqueue *q;
53 d3df3087 2003-12-06 devnull Mux *mux;
56 d3df3087 2003-12-06 devnull q = _muxqalloc();
58 d3df3087 2003-12-06 devnull qlock(&mux->lk);
59 d3df3087 2003-12-06 devnull mux->writeq = q;
60 d3df3087 2003-12-06 devnull qlock(&mux->outlk);
61 d3df3087 2003-12-06 devnull rwakeup(&mux->rpcfork);
62 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
64 d3df3087 2003-12-06 devnull while((p = _muxqrecv(q)) != nil)
65 d3df3087 2003-12-06 devnull if(mux->send(mux, p) < 0)
67 d3df3087 2003-12-06 devnull qunlock(&mux->outlk);
68 d3df3087 2003-12-06 devnull qlock(&mux->lk);
69 d3df3087 2003-12-06 devnull _muxqhangup(q);
70 3a194702 2006-11-04 devnull while(_muxnbqrecv(q, &p))
73 d3df3087 2003-12-06 devnull mux->writeq = nil;
74 d3df3087 2003-12-06 devnull rwakeup(&mux->rpcfork);
75 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
80 3a194702 2006-11-04 devnull _muxrecv(Mux *mux, int canblock, void **vp)
85 d3df3087 2003-12-06 devnull qlock(&mux->lk);
86 d3df3087 2003-12-06 devnull if(mux->readq){
87 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
88 3a194702 2006-11-04 devnull if(canblock){
89 3a194702 2006-11-04 devnull *vp = _muxqrecv(mux->readq);
90 3a194702 2006-11-04 devnull return 1;
92 3a194702 2006-11-04 devnull return _muxnbqrecv(mux->readq, vp);
95 d3df3087 2003-12-06 devnull qlock(&mux->inlk);
96 d3df3087 2003-12-06 devnull qunlock(&mux->lk);
97 3a194702 2006-11-04 devnull if(canblock){
98 2d2e5c71 2006-06-25 devnull p = mux->recv(mux);
101 2d2e5c71 2006-06-25 devnull if(mux->nbrecv)
102 3a194702 2006-11-04 devnull ret = mux->nbrecv(mux, &p);
104 3a194702 2006-11-04 devnull /* send eof, not "no packet ready" */
105 2d2e5c71 2006-06-25 devnull p = nil;
106 3a194702 2006-11-04 devnull ret = 1;
109 d3df3087 2003-12-06 devnull qunlock(&mux->inlk);
110 3a194702 2006-11-04 devnull *vp = p;
111 3a194702 2006-11-04 devnull return ret;
115 d3df3087 2003-12-06 devnull _muxsend(Mux *mux, void *p)
117 d3df3087 2003-12-06 devnull qlock(&mux->lk);
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;
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;
132 d3df3087 2003-12-06 devnull return 0;
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;
142 d3df3087 2003-12-06 devnull qunlock(&mux->outlk);
143 d3df3087 2003-12-06 devnull return 0;