⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sfpoll.c

📁 su 的源代码库
💻 C
字号:
/* Copyright (c) Colorado School of Mines, 2006.*//* All rights reserved.                       */#include	"sfhdr.h"/*	Poll a set of streams to see if any is available for I/O.**	Ready streams are moved to front of array but retain the**	same relative order.****	Written by Kiem-Phong Vo.*/#if __STD_Cint sfpoll(Sfio_t** fa, reg int n, int tm)#elseint sfpoll(fa, n, tm)Sfio_t**	fa;	/* array of streams to poll		*/reg int		n;	/* number of streams in array		*/int		tm;	/* time in millisecs for select/poll	*/#endif{	reg int		r, c, m, np;	reg Sfio_t*	f;	reg int		*status, *check;	if(n <= 0 || !fa)		return -1;	if(!(status = (int*)malloc(2*n*sizeof(int))) )		return -1;	check = status+n; /* streams that need polling */	/* a SF_READ stream is ready if there is buffered read data */#define RDREADY(f)	(((f->mode&SF_READ) && f->next < f->endb) || \			 ((f->mode&SF_WRITE) && f->proc && f->proc->ndata > 0) )	/* a SF_WRITE stream is ready if there is no write data */#define WRREADY(f)	(!(f->mode&SF_WRITE) || f->next == f->data)#define HASAUXFD(f)	(f->proc && f->proc->file >= 0 && f->proc->file != f->file)	for(r = c = 0; r < n; ++r) /* compute streams that must be checked */	{	f = fa[r];		status[r] = 0;		/* check accessibility */		m = f->mode&SF_RDWR;		if((int)f->mode != m && _sfmode(f,m,0) < 0)			continue;		if((f->flags&SF_READ) && RDREADY(f))			status[r] |= SF_READ;		if((f->flags&SF_WRITE) && WRREADY(f))			status[r] |= SF_WRITE;		if((f->flags&SF_RDWR) == status[r])			continue;		/* has discipline, ask its opinion */		if(f->disc && f->disc->exceptf)		{	if((m = (*f->disc->exceptf)(f,SF_DPOLL,&tm,f->disc)) < 0)				continue;			else if(m > 0)			{	status[r] = m&SF_RDWR;				continue;			}		}		if(f->extent < 0) /* unseekable stream, must poll/select */			check[c++] = r;		else /* seekable streams are always ready */		{	if(f->flags&SF_READ)				status[r] |= SF_READ;			if(f->flags&SF_WRITE)				status[r] |= SF_WRITE;		}	}	np = -1;#if _lib_poll	if(c > 0)	{	struct pollfd*	fds;		/* construct the poll array */		for(m = 0, r = 0; r < c; ++r, ++m)		{	f = fa[check[r]];			if(HASAUXFD(f))				m += 1;		}		if(!(fds = (struct pollfd*)malloc(m*sizeof(struct pollfd))) )			return -1;		for(m = 0, r = 0; r < c; ++r, ++m)		{	f = fa[check[r]];			fds[m].fd = f->file;			fds[m].events = fds[m].revents = 0;			if((f->flags&SF_WRITE) && !WRREADY(f) )				fds[m].events |= POLLOUT;			if((f->flags&SF_READ)  && !RDREADY(f) )			{	/* a sfpopen situation with two file descriptors */				if((f->mode&SF_WRITE) && HASAUXFD(f))				{	m += 1;					fds[m].fd = f->proc->file;					fds[m].revents = 0;				}				fds[m].events |= POLLIN;			}		}		while((np = SFPOLL(fds,m,tm)) < 0 )		{	if(errno == EINTR || errno == EAGAIN)				errno = 0;			else	break;		}		if(np > 0) /* poll succeeded */			np = c;		for(m = 0, r = 0; r < np; ++r, ++m)		{	f = fa[check[r]];			if((f->flags&SF_WRITE) && !WRREADY(f) )			{	if(fds[m].revents&POLLOUT)					status[check[r]] |= SF_WRITE;			}			if((f->flags&SF_READ)  && !RDREADY(f))			{	if((f->mode&SF_WRITE) && HASAUXFD(f))					m += 1;				if(fds[m].revents&POLLIN)					status[check[r]] |= SF_READ;			}		}		free((Void_t*)fds);	}#endif /*_lib_poll*/#if _lib_select	if(np < 0 && c > 0)	{	fd_set		rd, wr;		struct timeval	tmb, *tmp;		FD_ZERO(&rd);		FD_ZERO(&wr);		m = 0;		for(r = 0; r < c; ++r)		{	f = fa[check[r]];			if(f->file > m)				m = f->file;			if((f->flags&SF_WRITE) && !WRREADY(f))				FD_SET(f->file,&wr);			if((f->flags&SF_READ)  && !RDREADY(f))			{	if((f->mode&SF_WRITE) && HASAUXFD(f))				{	if(f->proc->file > m)						m = f->proc->file;					FD_SET(f->proc->file, &rd);				}				else	FD_SET(f->file,&rd);			}		}		if(tm < 0)			tmp = NIL(struct timeval*);		else		{	tmp = &tmb;			tmb.tv_sec = tm/SECOND;			tmb.tv_usec = (tm%SECOND)*SECOND;		}		while((np = select(m+1,&rd,&wr,NIL(fd_set*),tmp)) < 0 )		{	if(errno == EINTR)				errno = 0;			else	break;		}		if(np > 0)			np = c;		for(r = 0; r < np; ++r)		{	f = fa[check[r]];			if((f->flags&SF_WRITE) && !WRREADY(f) )			{	if(FD_ISSET(f->file,&wr) )					status[check[r]] |= SF_WRITE;			}			if((f->flags&SF_READ) && !RDREADY(f) )			{	if((f->mode&SF_WRITE) && HASAUXFD(f) )				{	if(FD_ISSET(f->proc->file, &rd) )						status[check[r]] |= SF_READ;				}				else				{	if(FD_ISSET(f->file,&rd) )						status[check[r]] |= SF_READ;				}			}		}	}#endif /*_lib_select*/	for(r = c = 0; c < n; ++c)	{	if(status[c] == 0)			continue;		f = fa[c];		f->val = (ssize_t)status[c];		/* announce status */		if(f->disc && f->disc->exceptf)			(*f->disc->exceptf)(f,SF_READY,(Void_t*)status[c],f->disc);		if(c > r) /* move to front of list */		{	fa[c] = fa[r];			fa[r] = f;		}		r += 1;	}	free((Void_t*)status);	return r;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -