Blame


1 056fe1ba 2003-11-23 devnull /*
2 fa325e9b 2020-01-10 cross * Multiplexed Venti client. It would be nice if we
3 056fe1ba 2003-11-23 devnull * could turn this into a generic library routine rather
4 056fe1ba 2003-11-23 devnull * than keep it Venti specific. A user-level 9P client
5 056fe1ba 2003-11-23 devnull * could use something like this too.
6 fa325e9b 2020-01-10 cross *
7 a09e80f9 2004-05-23 devnull * (Actually it does - this should be replaced with libmux,
8 a09e80f9 2004-05-23 devnull * which should be renamed librpcmux.)
9 056fe1ba 2003-11-23 devnull *
10 056fe1ba 2003-11-23 devnull * This is a little more complicated than it might be
11 056fe1ba 2003-11-23 devnull * because we want it to work well within and without libthread.
12 056fe1ba 2003-11-23 devnull *
13 056fe1ba 2003-11-23 devnull * The mux code is inspired by tra's, which is inspired by the Plan 9 kernel.
14 056fe1ba 2003-11-23 devnull */
15 056fe1ba 2003-11-23 devnull
16 056fe1ba 2003-11-23 devnull #include <u.h>
17 056fe1ba 2003-11-23 devnull #include <libc.h>
18 056fe1ba 2003-11-23 devnull #include <venti.h>
19 056fe1ba 2003-11-23 devnull
20 056fe1ba 2003-11-23 devnull typedef struct Rwait Rwait;
21 056fe1ba 2003-11-23 devnull struct Rwait
22 056fe1ba 2003-11-23 devnull {
23 056fe1ba 2003-11-23 devnull Rendez r;
24 056fe1ba 2003-11-23 devnull Packet *p;
25 056fe1ba 2003-11-23 devnull int done;
26 056fe1ba 2003-11-23 devnull int sleeping;
27 056fe1ba 2003-11-23 devnull };
28 056fe1ba 2003-11-23 devnull
29 056fe1ba 2003-11-23 devnull static int gettag(VtConn*, Rwait*);
30 056fe1ba 2003-11-23 devnull static void puttag(VtConn*, Rwait*, int);
31 056fe1ba 2003-11-23 devnull static void muxrpc(VtConn*, Packet*);
32 056fe1ba 2003-11-23 devnull
33 056fe1ba 2003-11-23 devnull Packet*
34 7252036f 2005-11-02 devnull _vtrpc(VtConn *z, Packet *p, VtFcall *tx)
35 056fe1ba 2003-11-23 devnull {
36 056fe1ba 2003-11-23 devnull int i;
37 056fe1ba 2003-11-23 devnull uchar tag, buf[2], *top;
38 5ddc97fc 2005-02-14 devnull Rwait *r, *rr;
39 056fe1ba 2003-11-23 devnull
40 fc638f7b 2012-01-16 rsc if(z == nil){
41 fc638f7b 2012-01-16 rsc werrstr("not connected");
42 fc638f7b 2012-01-16 rsc packetfree(p);
43 fc638f7b 2012-01-16 rsc return nil;
44 fc638f7b 2012-01-16 rsc }
45 fc638f7b 2012-01-16 rsc
46 056fe1ba 2003-11-23 devnull /* must malloc because stack could be private */
47 056fe1ba 2003-11-23 devnull r = vtmallocz(sizeof(Rwait));
48 056fe1ba 2003-11-23 devnull
49 056fe1ba 2003-11-23 devnull qlock(&z->lk);
50 056fe1ba 2003-11-23 devnull r->r.l = &z->lk;
51 056fe1ba 2003-11-23 devnull tag = gettag(z, r);
52 7252036f 2005-11-02 devnull if(tx){
53 7252036f 2005-11-02 devnull /* vtfcallrpc can't print packet because it doesn't have tag */
54 7252036f 2005-11-02 devnull tx->tag = tag;
55 7252036f 2005-11-02 devnull if(chattyventi)
56 7252036f 2005-11-02 devnull fprint(2, "%s -> %F\n", argv0, tx);
57 7252036f 2005-11-02 devnull }
58 056fe1ba 2003-11-23 devnull
59 056fe1ba 2003-11-23 devnull /* slam tag into packet */
60 056fe1ba 2003-11-23 devnull top = packetpeek(p, buf, 0, 2);
61 056fe1ba 2003-11-23 devnull if(top == nil){
62 056fe1ba 2003-11-23 devnull packetfree(p);
63 056fe1ba 2003-11-23 devnull return nil;
64 056fe1ba 2003-11-23 devnull }
65 056fe1ba 2003-11-23 devnull if(top == buf){
66 056fe1ba 2003-11-23 devnull werrstr("first two bytes must be in same packet fragment");
67 056fe1ba 2003-11-23 devnull packetfree(p);
68 6fc7da3c 2006-10-19 devnull vtfree(r);
69 056fe1ba 2003-11-23 devnull return nil;
70 056fe1ba 2003-11-23 devnull }
71 056fe1ba 2003-11-23 devnull top[1] = tag;
72 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
73 6fc7da3c 2006-10-19 devnull if(vtsend(z, p) < 0){
74 6fc7da3c 2006-10-19 devnull vtfree(r);
75 056fe1ba 2003-11-23 devnull return nil;
76 6fc7da3c 2006-10-19 devnull }
77 056fe1ba 2003-11-23 devnull
78 056fe1ba 2003-11-23 devnull qlock(&z->lk);
79 056fe1ba 2003-11-23 devnull /* wait for the muxer to give us our packet */
80 056fe1ba 2003-11-23 devnull r->sleeping = 1;
81 056fe1ba 2003-11-23 devnull z->nsleep++;
82 056fe1ba 2003-11-23 devnull while(z->muxer && !r->done)
83 056fe1ba 2003-11-23 devnull rsleep(&r->r);
84 056fe1ba 2003-11-23 devnull z->nsleep--;
85 056fe1ba 2003-11-23 devnull r->sleeping = 0;
86 056fe1ba 2003-11-23 devnull
87 056fe1ba 2003-11-23 devnull /* if not done, there's no muxer: start muxing */
88 056fe1ba 2003-11-23 devnull if(!r->done){
89 056fe1ba 2003-11-23 devnull if(z->muxer)
90 056fe1ba 2003-11-23 devnull abort();
91 056fe1ba 2003-11-23 devnull z->muxer = 1;
92 056fe1ba 2003-11-23 devnull while(!r->done){
93 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
94 056fe1ba 2003-11-23 devnull if((p = vtrecv(z)) == nil){
95 2e965b33 2004-05-05 devnull werrstr("unexpected eof on venti connection");
96 056fe1ba 2003-11-23 devnull z->muxer = 0;
97 6fc7da3c 2006-10-19 devnull vtfree(r);
98 056fe1ba 2003-11-23 devnull return nil;
99 056fe1ba 2003-11-23 devnull }
100 056fe1ba 2003-11-23 devnull qlock(&z->lk);
101 056fe1ba 2003-11-23 devnull muxrpc(z, p);
102 056fe1ba 2003-11-23 devnull }
103 056fe1ba 2003-11-23 devnull z->muxer = 0;
104 5ddc97fc 2005-02-14 devnull /* if there is anyone else sleeping, wake first unfinished to mux */
105 5ddc97fc 2005-02-14 devnull if(z->nsleep)
106 5ddc97fc 2005-02-14 devnull for(i=0; i<256; i++){
107 5ddc97fc 2005-02-14 devnull rr = z->wait[i];
108 5ddc97fc 2005-02-14 devnull if(rr && rr->sleeping && !rr->done){
109 5ddc97fc 2005-02-14 devnull rwakeup(&rr->r);
110 5ddc97fc 2005-02-14 devnull break;
111 5ddc97fc 2005-02-14 devnull }
112 5ddc97fc 2005-02-14 devnull }
113 056fe1ba 2003-11-23 devnull }
114 056fe1ba 2003-11-23 devnull
115 056fe1ba 2003-11-23 devnull p = r->p;
116 056fe1ba 2003-11-23 devnull puttag(z, r, tag);
117 056fe1ba 2003-11-23 devnull vtfree(r);
118 056fe1ba 2003-11-23 devnull qunlock(&z->lk);
119 056fe1ba 2003-11-23 devnull return p;
120 056fe1ba 2003-11-23 devnull }
121 056fe1ba 2003-11-23 devnull
122 7252036f 2005-11-02 devnull Packet*
123 7252036f 2005-11-02 devnull vtrpc(VtConn *z, Packet *p)
124 7252036f 2005-11-02 devnull {
125 7252036f 2005-11-02 devnull return _vtrpc(z, p, nil);
126 7252036f 2005-11-02 devnull }
127 7252036f 2005-11-02 devnull
128 fa325e9b 2020-01-10 cross static int
129 056fe1ba 2003-11-23 devnull gettag(VtConn *z, Rwait *r)
130 056fe1ba 2003-11-23 devnull {
131 056fe1ba 2003-11-23 devnull int i;
132 056fe1ba 2003-11-23 devnull
133 056fe1ba 2003-11-23 devnull Again:
134 056fe1ba 2003-11-23 devnull while(z->ntag == 256)
135 056fe1ba 2003-11-23 devnull rsleep(&z->tagrend);
136 056fe1ba 2003-11-23 devnull for(i=0; i<256; i++)
137 056fe1ba 2003-11-23 devnull if(z->wait[i] == 0){
138 056fe1ba 2003-11-23 devnull z->ntag++;
139 056fe1ba 2003-11-23 devnull z->wait[i] = r;
140 056fe1ba 2003-11-23 devnull return i;
141 056fe1ba 2003-11-23 devnull }
142 056fe1ba 2003-11-23 devnull fprint(2, "libventi: ntag botch\n");
143 056fe1ba 2003-11-23 devnull goto Again;
144 056fe1ba 2003-11-23 devnull }
145 056fe1ba 2003-11-23 devnull
146 056fe1ba 2003-11-23 devnull static void
147 056fe1ba 2003-11-23 devnull puttag(VtConn *z, Rwait *r, int tag)
148 056fe1ba 2003-11-23 devnull {
149 056fe1ba 2003-11-23 devnull assert(z->wait[tag] == r);
150 056fe1ba 2003-11-23 devnull z->wait[tag] = nil;
151 056fe1ba 2003-11-23 devnull z->ntag--;
152 056fe1ba 2003-11-23 devnull rwakeup(&z->tagrend);
153 056fe1ba 2003-11-23 devnull }
154 056fe1ba 2003-11-23 devnull
155 056fe1ba 2003-11-23 devnull static void
156 056fe1ba 2003-11-23 devnull muxrpc(VtConn *z, Packet *p)
157 056fe1ba 2003-11-23 devnull {
158 056fe1ba 2003-11-23 devnull uchar tag, buf[2], *top;
159 056fe1ba 2003-11-23 devnull Rwait *r;
160 056fe1ba 2003-11-23 devnull
161 056fe1ba 2003-11-23 devnull if((top = packetpeek(p, buf, 0, 2)) == nil){
162 056fe1ba 2003-11-23 devnull fprint(2, "libventi: short packet in vtrpc\n");
163 056fe1ba 2003-11-23 devnull packetfree(p);
164 056fe1ba 2003-11-23 devnull return;
165 056fe1ba 2003-11-23 devnull }
166 056fe1ba 2003-11-23 devnull
167 056fe1ba 2003-11-23 devnull tag = top[1];
168 056fe1ba 2003-11-23 devnull if((r = z->wait[tag]) == nil){
169 056fe1ba 2003-11-23 devnull fprint(2, "libventi: unexpected packet tag %d in vtrpc\n", tag);
170 056fe1ba 2003-11-23 devnull abort();
171 056fe1ba 2003-11-23 devnull packetfree(p);
172 056fe1ba 2003-11-23 devnull return;
173 056fe1ba 2003-11-23 devnull }
174 056fe1ba 2003-11-23 devnull
175 056fe1ba 2003-11-23 devnull r->p = p;
176 056fe1ba 2003-11-23 devnull r->done = 1;
177 056fe1ba 2003-11-23 devnull rwakeup(&r->r);
178 056fe1ba 2003-11-23 devnull }