plan 9 kernel history: overview | file list | diff list

1992/0621/port/devpipe.c (diff list | history)

1992/0619/sys/src/9/port/devpipe.c:8,311992/0621/sys/src/9/port/devpipe.c:8,33 (short | long | prev | next)
1990/0227    
#include	"devtab.h" 
 
1990/1009    
typedef struct Pipe	Pipe; 
                 
struct Pipe 
{ 
	Ref; 
1991/1227    
	QLock; 
1990/1009    
	Pipe	*next; 
1992/0621    
	ulong	path; 
1990/1009    
}; 
 
struct Pipealloc 
1992/0621    
struct 
1990/1009    
{ 
	Lock; 
	Pipe *pipe; 
	Pipe *free; 
1992/0621    
	Pipe	*pipe; 
	ulong	path; 
1990/1009    
} pipealloc; 
 
1992/0621    
static Pipe *getpipe(ulong); 
1990/0227    
static void pipeiput(Queue*, Block*); 
static void pipeoput(Queue*, Block*); 
static void pipestclose(Queue *); 
1992/0621    
 
1990/1113    
Qinfo pipeinfo = 
{ 
	pipeiput, 
1992/0619/sys/src/9/port/devpipe.c:35,411992/0621/sys/src/9/port/devpipe.c:37,44
1990/1113    
	"pipe" 
}; 
1990/0227    
 
1990/1009    
Dirtab pipedir[]={ 
1992/0621    
Dirtab pipedir[] = 
{ 
1990/11211    
	"data",		{Sdataqid},	0,			0600, 
	"ctl",		{Sctlqid},	0,			0600, 
	"data1",	{Sdataqid},	0,			0600, 
1992/0619/sys/src/9/port/devpipe.c:48,661992/0621/sys/src/9/port/devpipe.c:51,59
1990/0227    
{ 
} 
 
1990/1009    
/* 
 *  allocate structures for conf.npipe pipes 
 */ 
1990/0227    
void 
pipereset(void) 
{ 
1990/1009    
	Pipe *p, *ep; 
                 
	pipealloc.pipe = ialloc(conf.npipe * sizeof(Pipe), 0); 
	ep = &pipealloc.pipe[conf.npipe-1]; 
	for(p = pipealloc.pipe; p < ep; p++) 
		p->next = p+1; 
	pipealloc.free = pipealloc.pipe; 
1990/0227    
} 
 
/* 
1992/0619/sys/src/9/port/devpipe.c:73,921992/0621/sys/src/9/port/devpipe.c:66,81
1990/0227    
	Chan *c; 
1990/0629    
 
1990/0227    
	c = devattach('|', spec); 
1992/0621    
	p = smalloc(sizeof(Pipe)); 
	p->ref = 1; 
1990/1009    
 
	lock(&pipealloc); 
	if(pipealloc.free == 0){ 
		unlock(&pipealloc); 
1991/0125    
		close(c); 
1992/0114    
		exhausted("pipes"); 
1990/1009    
	} 
	p = pipealloc.free; 
	pipealloc.free = p->next; 
1990/1115    
	if(incref(p) != 1) 
1990/1013    
		panic("pipeattach"); 
1992/0621    
	p->path = ++pipealloc.path; 
	p->next = pipealloc.pipe; 
	pipealloc.pipe = p; 
1990/1009    
	unlock(&pipealloc); 
 
1990/11211    
	c->qid = (Qid){CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0), 0}; 
1992/0621    
	c->qid = (Qid){CHDIR|STREAMQID(2*p->path, 0), 0}; 
1991/1227    
	c->dev = 0; 
1990/0227    
	return c; 
} 
1992/0619/sys/src/9/port/devpipe.c:96,1021992/0621/sys/src/9/port/devpipe.c:85,91
1990/0227    
{ 
1990/1009    
	Pipe *p; 
 
1990/11211    
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2]; 
1992/0621    
	p = getpipe(STREAMID(c->qid.path)/2); 
1990/0227    
	nc = devclone(c, nc); 
1990/1013    
	if(incref(p) <= 1) 
		panic("pipeclone"); 
1992/0619/sys/src/9/port/devpipe.c:138,1431992/0621/sys/src/9/port/devpipe.c:127,133
1990/0227    
pipeopen(Chan *c, int omode) 
{ 
1990/1009    
	Pipe *p; 
1992/0621    
	int other; 
1990/1009    
	Stream *local, *remote; 
 
1990/11211    
	if(c->qid.path & CHDIR){ 
1992/0619/sys/src/9/port/devpipe.c:149,1551992/0621/sys/src/9/port/devpipe.c:139,145
1990/1009    
		return c; 
	} 
 
1990/11211    
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2]; 
1992/0621    
	p = getpipe(STREAMID(c->qid.path)/2); 
1990/1009    
	if(waserror()){ 
1991/1227    
		qunlock(p); 
1990/1009    
		nexterror(); 
1992/0619/sys/src/9/port/devpipe.c:161,1671992/0621/sys/src/9/port/devpipe.c:151,158
1990/1009    
		/* 
1991/1227    
		 *  first open, create the other end also 
1990/1009    
		 */ 
1991/1227    
		remote = streamnew(c->type, c->dev, STREAMID(c->qid.path)^1, &pipeinfo,1); 
1992/0621    
		other = STREAMID(c->qid.path)^1; 
		remote = streamnew(c->type, c->dev, other, &pipeinfo,1); 
1990/1009    
 
		/* 
		 *  connect the device ends of both streams 
1992/0619/sys/src/9/port/devpipe.c:170,1761992/0621/sys/src/9/port/devpipe.c:161,169
1990/1009    
		remote->devq->ptr = local; 
		local->devq->other->next = remote->devq; 
		remote->devq->other->next = local->devq; 
1991/1227    
	} else if(local->opens == 1){ 
1992/0621    
	} 
	else 
	if(local->opens == 1){ 
1990/1009    
		/* 
1991/1227    
		 *  keep other side around till last close of this side 
1990/1009    
		 */ 
1992/0619/sys/src/9/port/devpipe.c:209,2181992/0621/sys/src/9/port/devpipe.c:202,211
1990/0227    
void 
pipeclose(Chan *c) 
{ 
1990/1009    
	Pipe *p; 
1992/0621    
	Pipe *p, *f, **l; 
1990/11211    
	Stream *remote; 
1990/0629    
 
1990/11211    
	p = &pipealloc.pipe[STREAMID(c->qid.path)/2]; 
1992/0621    
	p = getpipe(STREAMID(c->qid.path)/2); 
1990/0629    
 
1990/1009    
	/* 
1991/1227    
	 *  take care of local and remote streams 
1992/0619/sys/src/9/port/devpipe.c:232,2431992/0621/sys/src/9/port/devpipe.c:225,241
1990/11161    
	 */ 
	if(decref(p) == 0){ 
		lock(&pipealloc); 
		p->next = pipealloc.free; 
		pipealloc.free = p; 
1992/0621    
		l = &pipealloc.pipe; 
		for(f = *l; f; f = f->next) { 
			if(f == p) { 
				*l = p->next; 
				break; 
			} 
			l = &p->next; 
		} 
1990/11161    
		unlock(&pipealloc); 
1992/0621    
		free(p); 
1990/11161    
	} 
	if(p->ref < 0) 
		panic("pipeexit"); 
1990/0227    
} 
 
long 
1992/0619/sys/src/9/port/devpipe.c:245,2521992/0621/sys/src/9/port/devpipe.c:243,250
1990/0227    
{ 
1990/11211    
	if(c->qid.path & CHDIR) 
1990/1009    
		return devdirread(c, va, n, pipedir, NPIPEDIR, pipegen); 
	else 
		return streamread(c, va, n); 
1992/0621    
 
	return streamread(c, va, n); 
1990/0227    
} 
 
1990/1009    
/* 
1992/0619/sys/src/9/port/devpipe.c:256,2621992/0621/sys/src/9/port/devpipe.c:254,260
1990/0227    
long 
1991/0411    
pipewrite(Chan *c, void *va, long n, ulong offset) 
1990/0227    
{ 
	if(waserror()){ 
1992/0621    
	if(waserror()) { 
1990/0227    
		postnote(u->p, 1, "sys: write on closed pipe", NExit); 
1990/11211    
		error(Egreg); 
1990/0227    
	} 
1992/0619/sys/src/9/port/devpipe.c:266,2741992/0621/sys/src/9/port/devpipe.c:264,269
1990/0227    
} 
 
/* 
 *  stream stuff 
 */ 
/* 
 *  send a block up stream to the process. 
 *  sleep untill there's room upstream. 
 */ 
1992/0619/sys/src/9/port/devpipe.c:311,3141992/0621/sys/src/9/port/devpipe.c:306,326
1990/0629    
	bp = allocb(0); 
	bp->type = M_HANGUP; 
	PUTNEXT(q, bp); 
1992/0621    
} 
 
Pipe* 
getpipe(ulong path) 
{ 
	Pipe *p; 
 
	lock(&pipealloc); 
	for(p = pipealloc.pipe; p; p = p->next) { 
		if(path == p->path) { 
			unlock(&pipealloc); 
			return p; 
		} 
	} 
	unlock(&pipealloc); 
	panic("getpipe"); 
	return 0; 
1990/0227    
} 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)