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

📄 select.c

📁 minix3的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#endif		}		selecttab[s].nfds = fd+1;		selecttab[s].filps[fd]->filp_selectors++;#if DEBUG_SELECT		printf("[fd %d ops: %d] ", fd, ops);#endif	}	if (selecttab[s].nreadyfds > 0 || !block) {		/* fd's were found that were ready to go right away, and/or		 * we were instructed not to block at all. Must return		 * immediately.		 */		copy_fdsets(&selecttab[s]);		select_cancel_all(&selecttab[s]);		selecttab[s].requestor = NULL;		/* Open Group:		 * "Upon successful completion, the pselect() and select()		 * functions shall return the total number of bits		 * set in the bit masks."		 */#if DEBUG_SELECT		printf("returning\n");#endif		return selecttab[s].nreadyfds;	}#if DEBUG_SELECT		printf("not returning (%d, %d)\n", selecttab[s].nreadyfds, block);#endif 	/* Convert timeval to ticks and set the timer. If it fails, undo	 * all, return error.	 */	if (is_timeout) {		int ticks;		/* Open Group:		 * "If the requested timeout interval requires a finer		 * granularity than the implementation supports, the		 * actual timeout interval shall be rounded up to the next		 * supported value."		 */#define USECPERSEC 1000000		while(timeout.tv_usec >= USECPERSEC) {			/* this is to avoid overflow with *HZ below */			timeout.tv_usec -= USECPERSEC;			timeout.tv_sec++;		}		ticks = timeout.tv_sec * HZ +			(timeout.tv_usec * HZ + USECPERSEC-1) / USECPERSEC;		selecttab[s].expiry = ticks;		fs_set_timer(&selecttab[s].timer, ticks, select_timeout_check, s);#if DEBUG_SELECT		printf("%d: blocking %d ticks\n", s, ticks);#endif	}	/* if we're blocking, the table entry is now valid. */	selecttab[s].requestor = fp;	/* process now blocked */	suspend(XSELECT);	return SUSPEND;}/*===========================================================================* *				select_cancel_all			     * *===========================================================================*/PRIVATE void select_cancel_all(struct selectentry *e){	int fd;	for(fd = 0; fd < e->nfds; fd++) {		struct filp *fp;		fp = e->filps[fd];		if (!fp) {#if DEBUG_SELECT			printf("[ fd %d/%d NULL ] ", fd, e->nfds);#endif			continue;		}		if (fp->filp_selectors < 1) {#if DEBUG_SELECT			printf("select: %d selectors?!\n", fp->filp_selectors);#endif			continue;		}		fp->filp_selectors--;		e->filps[fd] = NULL;		select_reevaluate(fp);	}	if (e->expiry > 0) {#if DEBUG_SELECT		printf("cancelling timer %d\n", e - selecttab);#endif		fs_cancel_timer(&e->timer); 		e->expiry = 0;	}	return;}/*===========================================================================* *				select_wakeup				     * *===========================================================================*/PRIVATE void select_wakeup(struct selectentry *e, int r){	revive(e->req_procnr, r);}/*===========================================================================* *				select_reevaluate			     * *===========================================================================*/PRIVATE int select_reevaluate(struct filp *fp){	int s, remain_ops = 0, fd, type = -1;	if (!fp) {		printf("fs: select: reevalute NULL fp\n");		return 0;	}	for(s = 0; s < MAXSELECTS; s++) {		if (!selecttab[s].requestor)			continue;		for(fd = 0; fd < selecttab[s].nfds; fd++)			if (fp == selecttab[s].filps[fd]) {				remain_ops |= tab2ops(fd, &selecttab[s]);				type = selecttab[s].type[fd];			}	}	/* If there are any select()s open that want any operations on	 * this fd that haven't been satisfied by this callback, then we're	 * still in the market for it.	 */	fp->filp_select_ops = remain_ops;#if DEBUG_SELECT	printf("remaining operations on fp are %d\n", fp->filp_select_ops);#endif	return remain_ops;}/*===========================================================================* *				select_return				     * *===========================================================================*/PRIVATE void select_return(struct selectentry *s, int r){	select_cancel_all(s);	copy_fdsets(s);	select_wakeup(s, r ? r : s->nreadyfds);	s->requestor = NULL;}/*===========================================================================* *				select_callback			             * *===========================================================================*/PUBLIC int select_callback(struct filp *fp, int ops){	int s, fd, want_ops, type;	/* We are being notified that file pointer fp is available for	 * operations 'ops'. We must re-register the select for	 * operations that we are still interested in, if any.	 */	want_ops = 0;	type = -1;	for(s = 0; s < MAXSELECTS; s++) {		int wakehim = 0;		if (!selecttab[s].requestor)			continue;		for(fd = 0; fd < selecttab[s].nfds; fd++) {			if (!selecttab[s].filps[fd])				continue;			if (selecttab[s].filps[fd] == fp) {				int this_want_ops;				this_want_ops = tab2ops(fd, &selecttab[s]);				want_ops |= this_want_ops;				if (this_want_ops & ops) {					/* this select() has been satisfied. */					ops2tab(ops, fd, &selecttab[s]);					wakehim = 1;				}				type = selecttab[s].type[fd];			}		}		if (wakehim)			select_return(&selecttab[s], 0);	}	return 0;}/*===========================================================================* *				select_notified			             * *===========================================================================*/PUBLIC int select_notified(int major, int minor, int selected_ops){	int s, f, t;#if DEBUG_SELECT	printf("select callback: %d, %d: %d\n", major, minor, selected_ops);#endif	for(t = 0; t < SEL_FDS; t++)		if (!fdtypes[t].select_match && fdtypes[t].select_major == major)		    	break;	if (t >= SEL_FDS) {#if DEBUG_SELECT		printf("select callback: no fdtype found for device %d\n", major);#endif		return OK;	}	/* We have a select callback from major device no.	 * d, which corresponds to our select type t.	 */	for(s = 0; s < MAXSELECTS; s++) {		int s_minor, ops;		if (!selecttab[s].requestor)			continue;		for(f = 0; f < selecttab[s].nfds; f++) {			if (!selecttab[s].filps[f] ||			   !select_major_match(major, selecttab[s].filps[f]))			   	continue;			ops = tab2ops(f, &selecttab[s]);			s_minor =			(selecttab[s].filps[f]->filp_ino->i_zone[0] >> MINOR)				& BYTE;			if ((s_minor == minor) &&				(selected_ops & ops)) {				select_callback(selecttab[s].filps[f], (selected_ops & ops));			}		}	}	return OK;}/*===========================================================================* *				init_select  				     * *===========================================================================*/PUBLIC void init_select(void){	int s;	for(s = 0; s < MAXSELECTS; s++)		fs_init_timer(&selecttab[s].timer);}/*===========================================================================* *				select_forget			             * *===========================================================================*/PUBLIC void select_forget(int proc){	/* something has happened (e.g. signal delivered that interrupts	 * select()). totally forget about the select().	 */	int s;	for(s = 0; s < MAXSELECTS; s++) {		if (selecttab[s].requestor &&			selecttab[s].req_procnr == proc) {			break;		}	}	if (s >= MAXSELECTS) {#if DEBUG_SELECT		printf("select: cancelled select() not found");#endif		return;	}	select_cancel_all(&selecttab[s]);	selecttab[s].requestor = NULL;	return;}/*===========================================================================* *				select_timeout_check	  	     	     * *===========================================================================*/PUBLIC void select_timeout_check(timer_t *timer){	int s;	s = tmr_arg(timer)->ta_int;	if (s < 0 || s >= MAXSELECTS) {#if DEBUG_SELECT		printf("select: bogus slot arg to watchdog %d\n", s);#endif		return;	}	if (!selecttab[s].requestor) {#if DEBUG_SELECT		printf("select: no requestor in watchdog\n");#endif		return;	}	if (selecttab[s].expiry <= 0) {#if DEBUG_SELECT		printf("select: strange expiry value in watchdog\n", s);#endif		return;	}	selecttab[s].expiry = 0;	select_return(&selecttab[s], 0);	return;}/*===========================================================================* *				select_unsuspend_by_proc  	     	     * *===========================================================================*/PUBLIC void select_unsuspend_by_proc(int proc){	struct filp *fp;	int fd, s;	for(s = 0; s < MAXSELECTS; s++) {	  if (!selecttab[s].requestor)		  continue;	  for(fd = 0; fd < selecttab[s].nfds; fd++) {	    int maj;	    if (!selecttab[s].filps[fd] || !selecttab[s].filps[fd]->filp_ino)		continue;	    maj = (selecttab[s].filps[fd]->filp_ino->i_zone[0] >> MAJOR)&BYTE;	    if(dmap_driver_match(proc, maj)) {			select_return(&selecttab[s], EAGAIN);	    }	  }	}	return;}

⌨️ 快捷键说明

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