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

📄 event.c

📁 开源备份软件源码 AMANDA, the Advanced Maryland Automatic Network Disk Archiver, is a backup system that a
💻 C
📖 第 1 页 / 共 2 页
字号:
	 */	FD_ZERO(&readfds);	FD_ZERO(&writefds);	FD_ZERO(&errfds);	maxfd = 0;	see_event = (wait_eh == (event_handle_t *)NULL);	/*	 * Run through each event handle and setup the events.	 * We save our next pointer early in case we GC some dead	 * events.	 */	for (eh = eventq_first(eventq); eh != NULL; eh = nexteh) {	    nexteh = eventq_next(eh);	    switch (eh->type) {	    /*	     * Read fds just get set into the select bitmask	     */	    case EV_READFD:		FD_SET((int)eh->data, &readfds);		FD_SET((int)eh->data, &errfds);		maxfd = max(maxfd, (int)eh->data);		see_event |= (eh == wait_eh);		break;	    /*	     * Likewise with write fds	     */	    case EV_WRITEFD:		FD_SET((int)eh->data, &writefds);		FD_SET((int)eh->data, &errfds);		maxfd = max(maxfd, (int)eh->data);		see_event |= (eh == wait_eh);		break;	    /*	     * Only set signals that aren't already set to avoid unnecessary	     * syscall overhead.	     */	    case EV_SIG:		se = &sigtable[eh->data];		see_event |= (eh == wait_eh);		if (se->handle == eh)		    break;		/* no previous handle */		assert(se->handle == NULL);		se->handle = eh;		se->score = 0;		/*@ignore@*/		se->oldhandler = signal((int)eh->data, signal_handler);		/*@end@*/		break;	    /*	     * Compute the timeout for this select	     */	    case EV_TIME:		/* if we're not supposed to block, then leave it at 0 */		if (dontblock)		    break;		if (eh->lastfired == -1)		    eh->lastfired = curtime;		interval = (long)(eh->data - (curtime - eh->lastfired));		if (interval < 0)		    interval = 0;		if (tvptr != NULL)		    timeout.tv_sec = min(timeout.tv_sec, interval);		else {		    /* this is the first timeout */		    tvptr = &timeout;		    timeout.tv_sec = interval;		}		see_event |= (eh == wait_eh);		break;	    /*	     * Wait events are processed immediately by event_wakeup()	     */	    case EV_WAIT:		see_event |= (eh == wait_eh);		break;	    /*	     * Prune dead events	     */	    case EV_DEAD:		eventq_remove(eh);		puthandle(eh);		break;	    default:		assert(0);		break;	    }	}	if(!see_event) {	    assert(--entry == 0);	    return 0;	}	/*	 * Let 'er rip	 */	event_debug(1,		    _("event: select: dontblock=%d, maxfd=%d, timeout=%ld\n"),		     dontblock, maxfd,		     tvptr != NULL ? timeout.tv_sec : -1);	rc = select(maxfd + 1, &readfds, &writefds, &errfds, tvptr);	event_debug(1, _("event: select returns %d\n"), rc);	/*	 * Select errors can mean many things.  Interrupted events should	 * not be fatal, since they could be delivered signals which still	 * need to have their events fired.	 */	if (rc < 0) {	    if (errno != EINTR) {		if (++ntries > 5) {		    error(_("select failed: %s"), strerror(errno));		    /*NOTREACHED*/		}		continue;	    }	    /* proceed if errno == EINTR, we may have caught a signal */	    /* contents cannot be trusted */	    FD_ZERO(&readfds);	    FD_ZERO(&writefds);	    FD_ZERO(&errfds);	}	/*	 * Grab the current time again for use in timed events.	 */	curtime = time(NULL);	/*	 * We need to copy the errfds into werrfds, so file descriptors	 * that are being polled for both reading and writing have	 * both of their poll events 'see' the error.	 */	memcpy(&werrfds, &errfds, SIZEOF(werrfds));	/*	 * Now run through the events and fire the ones that are ready.	 * Don't handle file descriptor events if the select failed.	 */	for (eh = eventq_first(eventq); eh != NULL; eh = eventq_next(eh)) {	    switch (eh->type) {	    /*	     * Read fds: just fire the event if set in the bitmask	     */	    case EV_READFD:		if (FD_ISSET((int)eh->data, &readfds) ||		    FD_ISSET((int)eh->data, &errfds)) {		    FD_CLR((int)eh->data, &readfds);		    FD_CLR((int)eh->data, &errfds);		    fire(eh);		    if(eh == wait_eh) event_wait_fired = 1;		}		break;	    /*	     * Write fds: same as Read fds	     */	    case EV_WRITEFD:		if (FD_ISSET((int)eh->data, &writefds) ||		    FD_ISSET((int)eh->data, &werrfds)) {		    FD_CLR((int)eh->data, &writefds);		    FD_CLR((int)eh->data, &werrfds);		    fire(eh);		    if(eh == wait_eh) event_wait_fired = 1;		}		break;	    /*	     * Signal events: check the score for fires, and run the	     * event if we got one.	     */	    case EV_SIG:		se = &sigtable[eh->data];		if (se->score > 0) {		    assert(se->handle == eh);		    se->score = 0;		    fire(eh);		    if(eh == wait_eh) event_wait_fired = 1;		}		break;	    /*	     * Timed events: check the interval elapsed since last fired,	     * and set it off if greater or equal to requested interval.	     */	    case EV_TIME:		if (eh->lastfired == -1)		    eh->lastfired = curtime;		if ((curtime - eh->lastfired) >= (time_t)eh->data) {		    eh->lastfired = curtime;		    fire(eh);		    if(eh == wait_eh) event_wait_fired = 1;		}		break;	    /*	     * Wait events are handled immediately by event_wakeup()	     * Dead events are handled by the pre-select loop.	     */	    case EV_WAIT:	    case EV_DEAD:		break;	    default:		assert(0);		break;	    }	}    } while (!dontblock && eventq.qlength > 0 && event_wait_fired == 0);    assert(--entry == 0);        return (event_wait_fired == 1);}/* * Generic signal handler.  Used to count caught signals for the event * loop. */static voidsignal_handler(    int	signo){    assert((signo >= 0) && ((size_t)signo < (size_t)(sizeof(sigtable) / sizeof(sigtable[0]))));    sigtable[signo].score++;}/* * Return a new handle.  Take from the handle cache if not empty.  Otherwise, * alloc a new one. */static event_handle_t *gethandle(void){    event_handle_t *eh;    if ((eh = eventq_first(cache)) != NULL) {	assert(cache.qlength > 0);	eventq_remove(eh);	cache.qlength--;	return (eh);    }    assert(cache.qlength == 0);    return (alloc(SIZEOF(*eh)));}/* * Free a handle.  If there's space in the handle cache, put it there. * Otherwise, free it. */static voidputhandle(    event_handle_t *eh){    if (cache.qlength > CACHEDEPTH) {	amfree(eh);	return;    }    eventq_add(cache, eh);    cache.qlength++;}/* * Convert an event type into a string */static const char *event_type2str(    event_type_t type){    static const struct {	event_type_t type;	const char name[12];    } event_types[] = {#define	X(s)	{ s, stringize(s) }	X(EV_READFD),	X(EV_WRITEFD),	X(EV_SIG),	X(EV_TIME),	X(EV_WAIT),	X(EV_DEAD),#undef X    };    size_t i;    for (i = 0; i < (size_t)(sizeof(event_types) / sizeof(event_types[0])); i++)	if (type == event_types[i].type)	    return (event_types[i].name);    return (_("BOGUS EVENT TYPE"));}

⌨️ 快捷键说明

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