henesyinit from p9f0ed2a895 years agoHistory
119 lines · 1.6 KB · C
RawDownload
#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "../port/error.h" #include "ip.h" enum{	Maxtu=	16*1024,}; typedef struct LB LB;struct LB{	Proc	*readp;	Queue	*q;	Fs	*f;}; static void loopbackread(void *a); static voidloopbackbind(Ipifc *ifc, int, char**){	LB *lb; 	lb = smalloc(sizeof(*lb));	lb->f = ifc->conv->p->f;	lb->q = qopen(128*1024, 1, nil, nil);	ifc->arg = lb; 	kproc("loopbackread", loopbackread, ifc); } static voidloopbackunbind(Ipifc *ifc){	LB *lb = ifc->arg; 	if(lb->readp)		postnote(lb->readp, 1, "unbind", 0); 	/* wait for reader to die */	while(lb->readp != 0)		tsleep(&up->sleep, return0, 0, 300); 	/* clean up */	qfree(lb->q);	free(lb);} static voidloopbackbwrite(Ipifc *ifc, Block *bp, int, uchar*){	LB *lb; 	lb = ifc->arg;	if(qpass(lb->q, bp) < 0)		ifc->outerr++;	ifc->out++;} static voidloopbackread(void *a){	Ipifc *ifc;	Block *bp;	LB *lb; 	ifc = a;	lb = ifc->arg;	lb->readp = up;	/* hide identity under a rock for unbind */	if(waserror()){		lb->readp = 0;		pexit("hangup", 1);	}	for(;;){		bp = qbread(lb->q, Maxtu);		if(bp == nil)			continue;		ifc->in++;		if(!canrlock(ifc)){			freeb(bp);			continue;		}		if(waserror()){			runlock(ifc);			nexterror();		}		if(ifc->lifc == nil)			freeb(bp);		else			ipiput(lb->f, ifc->lifc->local, bp);		runlock(ifc);		poperror();	}} Medium loopbackmedium ={.hsize=		0,.minmtu=	0,.maxmtu=	Maxtu,.maclen=	0,.name=		"loopback",.bind=		loopbackbind,.unbind=	loopbackunbind,.bwrite=	loopbackbwrite,}; voidloopbackmediumlink(void){	addipmedium(&loopbackmedium);}