vx32

Local 9vx git repository for patches.
git clone git://r-36.net/vx32
Log | Files | Refs

loopbackmedium.c (1665B)


      1 #include "u.h"
      2 #include "lib.h"
      3 #include "mem.h"
      4 #include "dat.h"
      5 #include "fns.h"
      6 #include "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 }