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

📄 eventlib.c

📁 bind 9.3结合mysql数据库
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1995-1999 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. *//* eventlib.c - implement glue for the eventlib * vix 09sep95 [initial] */#if !defined(LINT) && !defined(CODECENTER)static const char rcsid[] = "$Id: eventlib.c,v 1.2.2.1.4.2 2004/03/17 01:49:41 marka Exp $";#endif#include "port_before.h"#include "fd_setsize.h"#include <sys/types.h>#include <sys/time.h>#include <sys/stat.h>#include <errno.h>#include <signal.h>#include <stdarg.h>#include <stdlib.h>#include <unistd.h>#include <isc/eventlib.h>#include <isc/assertions.h>#include "eventlib_p.h"#include "port_after.h"/* Forward. */#ifdef NEED_PSELECTstatic int		pselect(int, void *, void *, void *,				struct timespec *,				const sigset_t *);#endif/* Public. */intevCreate(evContext *opaqueCtx) {	evContext_p *ctx;	/* Make sure the memory heap is initialized. */	if (meminit(0, 0) < 0 && errno != EEXIST)		return (-1);	OKNEW(ctx);	/* Global. */	ctx->cur = NULL;	/* Debugging. */	ctx->debug = 0;	ctx->output = NULL;	/* Connections. */	ctx->conns = NULL;	INIT_LIST(ctx->accepts);	/* Files. */	ctx->files = NULL;	FD_ZERO(&ctx->rdNext);	FD_ZERO(&ctx->wrNext);	FD_ZERO(&ctx->exNext);	FD_ZERO(&ctx->nonblockBefore);	ctx->fdMax = -1;	ctx->fdNext = NULL;	ctx->fdCount = 0;	/* Invalidate {rd,wr,ex}Last. */	ctx->highestFD = FD_SETSIZE - 1;#ifdef EVENTLIB_TIME_CHECKS	ctx->lastFdCount = 0;#endif	memset(ctx->fdTable, 0, sizeof ctx->fdTable);	/* Streams. */	ctx->streams = NULL;	ctx->strDone = NULL;	ctx->strLast = NULL;	/* Timers. */	ctx->lastEventTime = evNowTime();#ifdef EVENTLIB_TIME_CHECKS	ctx->lastSelectTime = ctx->lastEventTime;#endif	ctx->timers = evCreateTimers(ctx);	if (ctx->timers == NULL)		return (-1);	/* Waits. */	ctx->waitLists = NULL;	ctx->waitDone.first = ctx->waitDone.last = NULL;	ctx->waitDone.prev = ctx->waitDone.next = NULL;	opaqueCtx->opaque = ctx;	return (0);}voidevSetDebug(evContext opaqueCtx, int level, FILE *output) {	evContext_p *ctx = opaqueCtx.opaque;	ctx->debug = level;	ctx->output = output;}intevDestroy(evContext opaqueCtx) {	evContext_p *ctx = opaqueCtx.opaque;	int revs = 424242;	/* Doug Adams. */	evWaitList *this_wl, *next_wl;	evWait *this_wait, *next_wait;	/* Connections. */	while (revs-- > 0 && ctx->conns != NULL) {		evConnID id;		id.opaque = ctx->conns;		(void) evCancelConn(opaqueCtx, id);	}	INSIST(revs >= 0);	/* Streams. */	while (revs-- > 0 && ctx->streams != NULL) {		evStreamID id;		id.opaque = ctx->streams;		(void) evCancelRW(opaqueCtx, id);	}	/* Files. */	while (revs-- > 0 && ctx->files != NULL) {		evFileID id;		id.opaque = ctx->files;		(void) evDeselectFD(opaqueCtx, id);	}	INSIST(revs >= 0);	/* Timers. */	evDestroyTimers(ctx);	/* Waits. */	for (this_wl = ctx->waitLists;	     revs-- > 0 && this_wl != NULL;	     this_wl = next_wl) {		next_wl = this_wl->next;		for (this_wait = this_wl->first;		     revs-- > 0 && this_wait != NULL;		     this_wait = next_wait) {			next_wait = this_wait->next;			FREE(this_wait);		}		FREE(this_wl);	}	for (this_wait = ctx->waitDone.first;	     revs-- > 0 && this_wait != NULL;	     this_wait = next_wait) {		next_wait = this_wait->next;		FREE(this_wait);	}	FREE(ctx);	return (0);}intevGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) {	evContext_p *ctx = opaqueCtx.opaque;	struct timespec nextTime;	evTimer *nextTimer;	evEvent_p *new;	int x, pselect_errno, timerPast;#ifdef EVENTLIB_TIME_CHECKS	struct timespec interval;#endif	/* Ensure that exactly one of EV_POLL or EV_WAIT was specified. */	x = ((options & EV_POLL) != 0) + ((options & EV_WAIT) != 0);	if (x != 1)		EV_ERR(EINVAL);	/* Get the time of day.  We'll do this again after select() blocks. */	ctx->lastEventTime = evNowTime(); again:	/* Finished accept()'s do not require a select(). */	if (!EMPTY(ctx->accepts)) {		OKNEW(new);		new->type = Accept;		new->u.accept.this = HEAD(ctx->accepts);		UNLINK(ctx->accepts, HEAD(ctx->accepts), link);		opaqueEv->opaque = new;		return (0);	}	/* Stream IO does not require a select(). */	if (ctx->strDone != NULL) {		OKNEW(new);		new->type = Stream;		new->u.stream.this = ctx->strDone;		ctx->strDone = ctx->strDone->nextDone;		if (ctx->strDone == NULL)			ctx->strLast = NULL;		opaqueEv->opaque = new;		return (0);	}	/* Waits do not require a select(). */	if (ctx->waitDone.first != NULL) {		OKNEW(new);		new->type = Wait;		new->u.wait.this = ctx->waitDone.first;		ctx->waitDone.first = ctx->waitDone.first->next;		if (ctx->waitDone.first == NULL)			ctx->waitDone.last = NULL;		opaqueEv->opaque = new;		return (0);	}	/* Get the status and content of the next timer. */	if ((nextTimer = heap_element(ctx->timers, 1)) != NULL) {		nextTime = nextTimer->due;		timerPast = (evCmpTime(nextTime, ctx->lastEventTime) <= 0);	} else		timerPast = 0;	/* Make gcc happy. */	evPrintf(ctx, 9, "evGetNext: fdCount %d\n", ctx->fdCount);	if (ctx->fdCount == 0) {		static const struct timespec NoTime = {0, 0L};		enum { JustPoll, Block, Timer } m;		struct timespec t, *tp;		/* Are there any events at all? */		if ((options & EV_WAIT) != 0 && !nextTimer && ctx->fdMax == -1)			EV_ERR(ENOENT);		/* Figure out what select()'s timeout parameter should be. */		if ((options & EV_POLL) != 0) {			m = JustPoll;			t = NoTime;			tp = &t;		} else if (nextTimer == NULL) {			m = Block;			/* ``t'' unused. */			tp = NULL;		} else if (timerPast) {			m = JustPoll;			t = NoTime;			tp = &t;		} else {			m = Timer;			/* ``t'' filled in later. */			tp = &t;		}#ifdef EVENTLIB_TIME_CHECKS		if (ctx->debug > 0) {			interval = evSubTime(ctx->lastEventTime,					     ctx->lastSelectTime);			if (interval.tv_sec > 0 || interval.tv_nsec > 0)				evPrintf(ctx, 1,				   "time between pselect() %u.%09u count %d\n",					 interval.tv_sec, interval.tv_nsec,					 ctx->lastFdCount);		}#endif		do {			/* XXX need to copy only the bits we are using. */			ctx->rdLast = ctx->rdNext;			ctx->wrLast = ctx->wrNext;			ctx->exLast = ctx->exNext;			if (m == Timer) {				INSIST(tp == &t);				t = evSubTime(nextTime, ctx->lastEventTime);			}			evPrintf(ctx, 4,				"pselect(%d, 0x%lx, 0x%lx, 0x%lx, %ld.%09ld)\n",				 ctx->fdMax+1,				 (u_long)ctx->rdLast.fds_bits[0],				 (u_long)ctx->wrLast.fds_bits[0],				 (u_long)ctx->exLast.fds_bits[0],				 tp ? (long)tp->tv_sec : -1L,				 tp ? tp->tv_nsec : -1);			/* XXX should predict system's earliness and adjust. */			x = pselect(ctx->fdMax+1,				    &ctx->rdLast, &ctx->wrLast, &ctx->exLast,				    tp, NULL);			pselect_errno = errno;			evPrintf(ctx, 4, "select() returns %d (err: %s)\n",				 x, (x == -1) ? strerror(errno) : "none");			/* Anything but a poll can change the time. */			if (m != JustPoll)				ctx->lastEventTime = evNowTime();			/* Select() likes to finish about 10ms early. */		} while (x == 0 && m == Timer &&			 evCmpTime(ctx->lastEventTime, nextTime) < 0);#ifdef EVENTLIB_TIME_CHECKS		ctx->lastSelectTime = ctx->lastEventTime;#endif		if (x < 0) {			if (pselect_errno == EINTR) {				if ((options & EV_NULL) != 0)					goto again;				OKNEW(new);				new->type = Null;				/* No data. */				opaqueEv->opaque = new;				return (0);			}			if (pselect_errno == EBADF) {				for (x = 0; x <= ctx->fdMax; x++) {					struct stat sb;					if (FD_ISSET(x, &ctx->rdNext) == 0 &&					    FD_ISSET(x, &ctx->wrNext) == 0 &&					    FD_ISSET(x, &ctx->exNext) == 0)						continue;					if (fstat(x, &sb) == -1 &&					    errno == EBADF)						evPrintf(ctx, 1, "EBADF: %d\n",							 x);				}				abort();			}			EV_ERR(pselect_errno);		}		if (x == 0 && (nextTimer == NULL || !timerPast) &&		    (options & EV_POLL))			EV_ERR(EWOULDBLOCK);		ctx->fdCount = x;#ifdef EVENTLIB_TIME_CHECKS		ctx->lastFdCount = x;#endif	}	INSIST(nextTimer || ctx->fdCount);	/* Timers go first since we'd like them to be accurate. */	if (nextTimer && !timerPast) {		/* Has anything happened since we blocked? */		timerPast = (evCmpTime(nextTime, ctx->lastEventTime) <= 0);	}	if (nextTimer && timerPast) {		OKNEW(new);		new->type = Timer;

⌨️ 快捷键说明

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