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

1990/0629/port/stream.c (diff list | history)

1990/0513/sys/src/9/port/stream.c:258,2631990/0629/sys/src/9/port/stream.c:258,279 (short | long | prev | next)
1990/0227    
} 
 
/* 
1990/0629    
 *  flush a queue 
 */ 
static void 
flushq(Queue *q) 
{ 
	Block *bp; 
 
	q = RD(q); 
	while(bp = getq(q)) 
		freeb(bp); 
	q = WR(q); 
	while(bp = getq(q)) 
		freeb(bp); 
} 
 
/* 
1990/0227    
 *  free a queue 
 */ 
static void 
1990/0513/sys/src/9/port/stream.c:515,5221990/0629/sys/src/9/port/stream.c:531,542
1990/0227    
void 
nullput(Queue *q, Block *bp) 
{ 
	freeb(bp); 
	error(0, Ehungup); 
1990/0629    
	if(bp->type == M_HANGUP) 
		freeb(bp); 
	else { 
		freeb(bp); 
		error(0, Ehungup); 
	} 
1990/0227    
} 
 
/* 
1990/0513/sys/src/9/port/stream.c:658,6651990/0629/sys/src/9/port/stream.c:678,685
1990/0227    
 	 *  hang a device and process q off the stream 
	 */ 
	s->inuse = 1; 
1990/0629    
	s->opens = 1; 
1990/0331    
	s->hread = 0; 
1990/0227    
	s->tag[0] = 0; 
	q = allocq(&procinfo); 
	s->procq = WR(q); 
	q = allocq(qi); 
1990/0513/sys/src/9/port/stream.c:697,7021990/0629/sys/src/9/port/stream.c:717,723
1990/0227    
			&& s->dev == c->dev 
		 	&& s->id == STREAMID(c->qid)){ 
				s->inuse++; 
1990/0629    
				s->opens++; 
1990/0227    
				c->stream = s; 
				unlock(s); 
				return; 
1990/0513/sys/src/9/port/stream.c:712,7171990/0629/sys/src/9/port/stream.c:733,782
1990/0227    
} 
 
/* 
1990/0629    
 *  Enter a stream.  Increment the reference count so it can't disappear 
 *  under foot. 
 */ 
int 
streamenter(Stream *s) 
{ 
	lock(s); 
	if(s->opens == 0){ 
		unlock(s); 
		return -1; 
	} 
	s->inuse++; 
	unlock(s); 
	return 0; 
} 
 
/* 
 *  Decrement the reference count on a stream.  If the count is 
 *  zero, free the stream. 
 */ 
void 
streamexit(Stream *s, int locked) 
{ 
	Queue *q; 
	Queue *nq; 
 
	if(!locked) 
		lock(s); 
	if(s->inuse == 1){ 
		/* 
		 *  ascend the stream freeing the queues 
		 */ 
		for(q = s->devq; q; q = nq){ 
			nq = q->next; 
			freeq(q); 
		} 
		s->id = s->dev = s->type = 0; 
	} 
	s->inuse--; 
	if(!locked) 
		unlock(s); 
} 
 
/* 
1990/0227    
 *  On the last close of a stream, for each queue on the 
 *  stream release its blocks and call its close routine. 
 */ 
1990/0513/sys/src/9/port/stream.c:729,7611990/0629/sys/src/9/port/stream.c:794,828
1990/0227    
		return; 
 
	/* 
	 *  decrement the reference cound 
1990/0629    
	 *  decrement the reference count 
1990/0227    
	 */ 
1990/03013    
	lock(s); 
	if(s->inuse != 1){ 
		s->inuse--; 
1990/0227    
		unlock(c->stream); 
		return; 
1990/0629    
	if(s->opens == 1){ 
		/* 
		 *  descend the stream closing the queues 
		 */ 
		for(q = s->procq; q; q = q->next){ 
			if(q->info->close) 
				(*q->info->close)(q->other); 
			/* this may be 2 streams joined device end to device end */ 
			if(q == s->devq->other) 
				break; 
		} 
	 
		/* 
		 *  ascend the stream flushing the queues 
		 */ 
		for(q = s->devq; q; q = nq){ 
			nq = q->next; 
			flushq(q); 
		} 
1990/0227    
	} 
1990/0629    
	s->opens--; 
1990/0227    
 
	/* 
	 *  descend the stream closing the queues 
1990/0629    
	 *  leave it and free it 
1990/0227    
	 */ 
1990/03013    
	for(q = s->procq; q; q = q->next){ 
1990/0227    
		if(q->info->close) 
			(*q->info->close)(q->other); 
1990/03013    
		if(q == s->devq->other) 
1990/0227    
			break; 
	} 
	/* 
	 *  ascend the stream freeing the queues 
	 */ 
1990/03013    
	for(q = s->devq; q; q = nq){ 
1990/0227    
		nq = q->next; 
		freeq(q); 
	} 
1990/03013    
	s->id = s->dev = s->type = 0; 
	s->inuse--; 
1990/0629    
	streamexit(s, 1); 
1990/03013    
	unlock(s); 
1990/0227    
} 
 


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