]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/ip/loopbackmedium.c
Import sources from 2011-03-30 iso image
[plan9front.git] / sys / src / 9 / ip / loopbackmedium.c
1 #include "u.h"
2 #include "../port/lib.h"
3 #include "mem.h"
4 #include "dat.h"
5 #include "fns.h"
6 #include "../port/error.h"
7
8 #include "ip.h"
9
10 enum
11 {
12         Maxtu=  16*1024,
13 };
14
15 typedef struct LB LB;
16 struct LB
17 {
18         Proc    *readp;
19         Queue   *q;
20         Fs      *f;
21 };
22
23 static void loopbackread(void *a);
24
25 static void
26 loopbackbind(Ipifc *ifc, int, char**)
27 {
28         LB *lb;
29
30         lb = smalloc(sizeof(*lb));
31         lb->f = ifc->conv->p->f;
32         lb->q = qopen(1024*1024, Qmsg, nil, nil);
33         ifc->arg = lb;
34         ifc->mbps = 1000;
35
36         kproc("loopbackread", loopbackread, ifc);
37
38 }
39
40 static void
41 loopbackunbind(Ipifc *ifc)
42 {
43         LB *lb = ifc->arg;
44
45         if(lb->readp)
46                 postnote(lb->readp, 1, "unbind", 0);
47
48         /* wait for reader to die */
49         while(lb->readp != 0)
50                 tsleep(&up->sleep, return0, 0, 300);
51
52         /* clean up */
53         qfree(lb->q);
54         free(lb);
55 }
56
57 static void
58 loopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*)
59 {
60         LB *lb;
61
62         lb = ifc->arg;
63         if(qpass(lb->q, bp) < 0)
64                 ifc->outerr++;
65         ifc->out++;
66 }
67
68 static void
69 loopbackread(void *a)
70 {
71         Ipifc *ifc;
72         Block *bp;
73         LB *lb;
74
75         ifc = a;
76         lb = ifc->arg;
77         lb->readp = up; /* hide identity under a rock for unbind */
78         if(waserror()){
79                 lb->readp = 0;
80                 pexit("hangup", 1);
81         }
82         for(;;){
83                 bp = qbread(lb->q, Maxtu);
84                 if(bp == nil)
85                         continue;
86                 ifc->in++;
87                 if(!canrlock(ifc)){
88                         freeb(bp);
89                         continue;
90                 }
91                 if(waserror()){
92                         runlock(ifc);
93                         nexterror();
94                 }
95                 if(ifc->lifc == nil)
96                         freeb(bp);
97                 else
98                         ipiput4(lb->f, ifc, bp);
99                 runlock(ifc);
100                 poperror();
101         }
102 }
103
104 Medium loopbackmedium =
105 {
106 .hsize=         0,
107 .mintu=         0,
108 .maxtu=         Maxtu,
109 .maclen=        0,
110 .name=          "loopback",
111 .bind=          loopbackbind,
112 .unbind=        loopbackunbind,
113 .bwrite=        loopbackbwrite,
114 };
115
116 void
117 loopbackmediumlink(void)
118 {
119         addipmedium(&loopbackmedium);
120 }