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

📄 eventlib.c

📁 bind 源码 最新实现 linux/unix/windows平台
💻 C
📖 第 1 页 / 共 2 页
字号:
		ctx->fdCount = 0;	}	/* We get here if the caller deselect()'s an FD. Gag me with a goto. */	goto again;}intevDispatch(evContext opaqueCtx, evEvent opaqueEv) {	evContext_p *ctx = opaqueCtx.opaque;	evEvent_p *ev = opaqueEv.opaque;#ifdef EVENTLIB_TIME_CHECKS	void *func;	struct timespec start_time;	struct timespec interval;#endif#ifdef EVENTLIB_TIME_CHECKS	if (ctx->debug > 0)		start_time = evNowTime();#endif	ctx->cur = ev;	switch (ev->type) {	    case Accept: {		evAccept *this = ev->u.accept.this;		evPrintf(ctx, 5,			"Dispatch.Accept: fd %d -> %d, func %p, uap %p\n",			 this->conn->fd, this->fd,			 this->conn->func, this->conn->uap);		errno = this->ioErrno;		(this->conn->func)(opaqueCtx, this->conn->uap, this->fd,				   &this->la, this->lalen,				   &this->ra, this->ralen);#ifdef EVENTLIB_TIME_CHECKS		func = this->conn->func;#endif		break;	    }	    case File: {		evFile *this = ev->u.file.this;		int eventmask = ev->u.file.eventmask;		evPrintf(ctx, 5,			"Dispatch.File: fd %d, mask 0x%x, func %p, uap %p\n",			 this->fd, this->eventmask, this->func, this->uap);		(this->func)(opaqueCtx, this->uap, this->fd, eventmask);#ifdef EVENTLIB_TIME_CHECKS		func = this->func;#endif		break;	    }	    case Stream: {		evStream *this = ev->u.stream.this;		evPrintf(ctx, 5,			 "Dispatch.Stream: fd %d, func %p, uap %p\n",			 this->fd, this->func, this->uap);		errno = this->ioErrno;		(this->func)(opaqueCtx, this->uap, this->fd, this->ioDone);#ifdef EVENTLIB_TIME_CHECKS		func = this->func;#endif		break;	    }	    case Timer: {		evTimer *this = ev->u.timer.this;		evPrintf(ctx, 5, "Dispatch.Timer: func %p, uap %p\n",			 this->func, this->uap);		(this->func)(opaqueCtx, this->uap, this->due, this->inter);#ifdef EVENTLIB_TIME_CHECKS		func = this->func;#endif		break;	    }	    case Wait: {		evWait *this = ev->u.wait.this;		evPrintf(ctx, 5,			 "Dispatch.Wait: tag %p, func %p, uap %p\n",			 this->tag, this->func, this->uap);		(this->func)(opaqueCtx, this->uap, this->tag);#ifdef EVENTLIB_TIME_CHECKS		func = this->func;#endif		break;	    }	    case Null: {		/* No work. */#ifdef EVENTLIB_TIME_CHECKS		func = NULL;#endif		break;	    }	    default: {		abort();	    }	}#ifdef EVENTLIB_TIME_CHECKS	if (ctx->debug > 0) {		interval = evSubTime(evNowTime(), start_time);		/* 		 * Complain if it took longer than 50 milliseconds.		 *		 * We call getuid() to make an easy to find mark in a kernel		 * trace.		 */		if (interval.tv_sec > 0 || interval.tv_nsec > 50000000)			evPrintf(ctx, 1,			 "dispatch interval %u.%09u uid %d type %d func %p\n",				 interval.tv_sec, interval.tv_nsec,				 getuid(), ev->type, func);	}#endif	ctx->cur = NULL;	evDrop(opaqueCtx, opaqueEv);	return (0);}voidevDrop(evContext opaqueCtx, evEvent opaqueEv) {	evContext_p *ctx = opaqueCtx.opaque;	evEvent_p *ev = opaqueEv.opaque;	switch (ev->type) {	    case Accept: {		FREE(ev->u.accept.this);		break;	    }	    case File: {		/* No work. */		break;	    }	    case Stream: {		evStreamID id;		id.opaque = ev->u.stream.this;		(void) evCancelRW(opaqueCtx, id);		break;	    }	    case Timer: {		evTimer *this = ev->u.timer.this;		evTimerID opaque;		/* Check to see whether the user func cleared the timer. */		if (heap_element(ctx->timers, this->index) != this) {			evPrintf(ctx, 5, "Dispatch.Timer: timer rm'd?\n");			break;		}		/*		 * Timer is still there.  Delete it if it has expired,		 * otherwise set it according to its next interval.		 */		if (this->inter.tv_sec == (time_t)0 &&		    this->inter.tv_nsec == 0L) {			opaque.opaque = this;						(void) evClearTimer(opaqueCtx, opaque);		} else {			opaque.opaque = this;			(void) evResetTimer(opaqueCtx, opaque, this->func,					    this->uap,					    evAddTime((this->mode & EV_TMR_RATE) ?						      this->due :						      ctx->lastEventTime,						      this->inter),					    this->inter);		}		break;	    }	    case Wait: {		FREE(ev->u.wait.this);		break;	    }	    case Null: {		/* No work. */		break;	    }	    default: {		abort();	    }	}	FREE(ev);}intevMainLoop(evContext opaqueCtx) {	evEvent event;	int x;	while ((x = evGetNext(opaqueCtx, &event, EV_WAIT)) == 0)		if ((x = evDispatch(opaqueCtx, event)) < 0)			break;	return (x);}intevHighestFD(evContext opaqueCtx) {	evContext_p *ctx = opaqueCtx.opaque;	return (ctx->highestFD);}voidevPrintf(const evContext_p *ctx, int level, const char *fmt, ...) {	va_list ap;	va_start(ap, fmt);	if (ctx->output != NULL && ctx->debug >= level) {		vfprintf(ctx->output, fmt, ap);		fflush(ctx->output);	}	va_end(ap);}intevSetOption(evContext *opaqueCtx, const char *option, int value) {	/* evContext_p *ctx = opaqueCtx->opaque; */	UNUSED(opaqueCtx);	UNUSED(value);#ifndef CLOCK_MONOTONIC	UNUSED(option);#endif #ifdef CLOCK_MONOTONIC	if (strcmp(option, "monotime") == 0) {		if (opaqueCtx  != NULL)			errno = EINVAL;		if (value == 0 || value == 1) {			__evOptMonoTime = value;			return (0);		} else {			errno = EINVAL;			return (-1);		}	} #endif	errno = ENOENT;	return (-1);}intevGetOption(evContext *opaqueCtx, const char *option, int *value) {	/* evContext_p *ctx = opaqueCtx->opaque; */	UNUSED(opaqueCtx);#ifndef CLOCK_MONOTONIC	UNUSED(value);	UNUSED(option);#endif #ifdef CLOCK_MONOTONIC	if (strcmp(option, "monotime") == 0) {		if (opaqueCtx  != NULL)			errno = EINVAL;		*value = __evOptMonoTime;		return (0);	}#endif	errno = ENOENT;	return (-1);}#if defined(NEED_PSELECT) || defined(USE_POLL)/* XXX needs to move to the porting library. */static intpselect(int nfds, void *rfds, void *wfds, void *efds,	struct timespec *tsp,	const sigset_t *sigmask){	struct timeval tv, *tvp;	sigset_t sigs;	int n;#ifdef USE_POLL	int polltimeout = INFTIM;	evContext_p *ctx;	struct pollfd *fds;	nfds_t pnfds;	UNUSED(nfds);#endif /* USE_POLL */	if (tsp) {		tvp = &tv;		tv = evTimeVal(*tsp);#ifdef USE_POLL		polltimeout = 1000 * tv.tv_sec + tv.tv_usec / 1000;#endif /* USE_POLL */	} else		tvp = NULL;	if (sigmask)		sigprocmask(SIG_SETMASK, sigmask, &sigs);#ifndef USE_POLL	n = select(nfds, rfds, wfds, efds, tvp);#else	/*	 * rfds, wfds, and efds should all be from the same evContext_p,	 * so any of them will do. If they're all NULL, the caller is	 * presumably calling us to block.	 */	if (rfds != NULL)		ctx = ((__evEmulMask *)rfds)->ctx;	else if (wfds != NULL)		ctx = ((__evEmulMask *)wfds)->ctx;	else if (efds != NULL)		ctx = ((__evEmulMask *)efds)->ctx;	else		ctx = NULL;	if (ctx != NULL && ctx->fdMax != -1) {		fds = &(ctx->pollfds[ctx->firstfd]);		pnfds = ctx->fdMax - ctx->firstfd + 1;	} else {		fds = NULL;		pnfds = 0;	}	n = poll(fds, pnfds, polltimeout);	/*	 * pselect() should return the total number of events on the file	 * desriptors, not just the count of fd:s with activity. Hence,	 * traverse the pollfds array and count the events.	 */	if (n > 0) {		int     i, e;		for (e = 0, i = ctx->firstfd; i <= ctx->fdMax; i++) {			if (ctx->pollfds[i].fd < 0)				continue;			if (FD_ISSET(i, &ctx->rdLast))				e++;			if (FD_ISSET(i, &ctx->wrLast))				e++;			if (FD_ISSET(i, &ctx->exLast))				e++;			}		n = e;	}#endif /* USE_POLL */	if (sigmask)		sigprocmask(SIG_SETMASK, &sigs, NULL);	if (tsp)		*tsp = evTimeSpec(tv);	return (n);}#endif#ifdef USE_POLLintevPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd) { 	int     i, maxnfds;	void	*pollfds, *fdTable; 	if (fd < ctx->maxnfds)		return (0); 	/* Don't allow ridiculously small values for pollfd_chunk_size */	if (pollfd_chunk_size < 20)		pollfd_chunk_size = 20; 	maxnfds = (1 + (fd/pollfd_chunk_size)) * pollfd_chunk_size; 	pollfds = realloc(ctx->pollfds, maxnfds * sizeof(*ctx->pollfds));	if (pollfds != NULL)		ctx->pollfds = pollfds;	fdTable = realloc(ctx->fdTable, maxnfds * sizeof(*ctx->fdTable));	if (fdTable != NULL)		ctx->fdTable = fdTable; 	if (pollfds == NULL || fdTable == NULL) {		evPrintf(ctx, 2, "pollfd() realloc (%ld) failed\n",			 (long)maxnfds*sizeof(struct pollfd));		return (-1);	} 	for (i = ctx->maxnfds; i < maxnfds; i++) {		ctx->pollfds[i].fd = -1;		ctx->pollfds[i].events = 0;		ctx->fdTable[i] = 0;	}	ctx->maxnfds = maxnfds;	return (0);} /* Find the appropriate 'events' or 'revents' field in the pollfds array */short *__fd_eventfield(int fd, __evEmulMask *maskp) { 	evContext_p     *ctx = (evContext_p *)maskp->ctx; 	if (!maskp->result || maskp->type == EV_WASNONBLOCKING)		return (&(ctx->pollfds[fd].events));	else		return (&(ctx->pollfds[fd].revents));} /* Translate to poll(2) event */short__poll_event(__evEmulMask *maskp) { 	switch ((maskp)->type) {	case EV_READ:		return (POLLRDNORM);	case EV_WRITE:		return (POLLWRNORM);	case EV_EXCEPT:		return (POLLRDBAND | POLLPRI | POLLWRBAND);	case EV_WASNONBLOCKING:		return (POLLHUP);	default:		return (0);	}} /* * Clear the events corresponding to the specified mask. If this leaves * the events mask empty (apart from the POLLHUP bit), set the fd field * to -1 so that poll(2) will ignore this fd. */void__fd_clr(int fd, __evEmulMask *maskp) { 	evContext_p     *ctx = maskp->ctx; 	*__fd_eventfield(fd, maskp) &= ~__poll_event(maskp);	if ((ctx->pollfds[fd].events & ~POLLHUP) == 0) {		ctx->pollfds[fd].fd = -1;		if (fd == ctx->fdMax)			while (ctx->fdMax > ctx->firstfd &&			       ctx->pollfds[ctx->fdMax].fd < 0)				ctx->fdMax--;		if (fd == ctx->firstfd)			while (ctx->firstfd <= ctx->fdMax &&			       ctx->pollfds[ctx->firstfd].fd < 0)				ctx->firstfd++;		/*		 * Do we have a empty set of descriptors?		 */		if (ctx->firstfd > ctx->fdMax) {			ctx->fdMax = -1;			ctx->firstfd = 0;		}	}} /* * Set the events bit(s) corresponding to the specified mask. If the events * field has any other bits than POLLHUP set, also set the fd field so that * poll(2) will watch this fd. */void__fd_set(int fd, __evEmulMask *maskp) { 	evContext_p     *ctx = maskp->ctx;	*__fd_eventfield(fd, maskp) |= __poll_event(maskp);	if ((ctx->pollfds[fd].events & ~POLLHUP) != 0) {		ctx->pollfds[fd].fd = fd;		if (fd < ctx->firstfd || ctx->fdMax == -1)			ctx->firstfd = fd;		if (fd > ctx->fdMax)			ctx->fdMax = fd;	}}#endif /* USE_POLL *//*! \file */

⌨️ 快捷键说明

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