summaryrefslogtreecommitdiff
path: root/usr/src/lib/libresolv2/common/isc/eventlib.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libresolv2/common/isc/eventlib.c')
-rw-r--r--usr/src/lib/libresolv2/common/isc/eventlib.c329
1 files changed, 180 insertions, 149 deletions
diff --git a/usr/src/lib/libresolv2/common/isc/eventlib.c b/usr/src/lib/libresolv2/common/isc/eventlib.c
index beaed1c6bc..be4a7848b9 100644
--- a/usr/src/lib/libresolv2/common/isc/eventlib.c
+++ b/usr/src/lib/libresolv2/common/isc/eventlib.c
@@ -1,33 +1,26 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
- * Use is subject to license terms.
- */
-
-/*
+ * 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 INTERNET SOFTWARE CONSORTIUM DISCLAIMS
- * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
- * CONSORTIUM 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.
+ * 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.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* eventlib.c - implement glue for the eventlib
* vix 09sep95 [initial]
*/
#if !defined(LINT) && !defined(CODECENTER)
-static const char rcsid[] = "$Id: eventlib.c,v 1.48 2002/07/17 07:37:34 marka Exp $";
+static const char rcsid[] = "$Id: eventlib.c,v 1.10 2006/03/09 23:57:56 marka Exp $";
#endif
#include "port_before.h"
@@ -36,9 +29,9 @@ static const char rcsid[] = "$Id: eventlib.c,v 1.48 2002/07/17 07:37:34 marka Ex
#include <sys/types.h>
#include <sys/time.h>
#include <sys/stat.h>
-#ifdef SUNW_POLL
+#ifdef SOLARIS2
#include <limits.h>
-#endif /* SUNW_POLL */
+#endif /* SOLARIS2 */
#include <errno.h>
#include <signal.h>
@@ -52,21 +45,22 @@ static const char rcsid[] = "$Id: eventlib.c,v 1.48 2002/07/17 07:37:34 marka Ex
#include "port_after.h"
-#ifdef SUNW_POLL
-#if defined(pselect)
-#undef pselect
-#endif
-#define pselect Pselect
-#endif /* SUNW_POLL */
+int __evOptMonoTime;
+
+#ifdef USE_POLL
+#define pselect Pselect
+#endif /* USE_POLL */
/* Forward. */
-#ifdef NEED_PSELECT
+#if defined(NEED_PSELECT) || defined(USE_POLL)
static int pselect(int, void *, void *, void *,
struct timespec *,
const sigset_t *);
#endif
+int __evOptMonoTime;
+
/* Public. */
int
@@ -92,8 +86,8 @@ evCreate(evContext *opaqueCtx) {
/* Files. */
ctx->files = NULL;
-#ifdef SUNW_POLL
- ctx->pollfds = 0;
+#ifdef USE_POLL
+ ctx->pollfds = NULL;
ctx->maxnfds = 0;
ctx->firstfd = 0;
emulMaskInit(ctx, rdLast, EV_READ, 1);
@@ -103,27 +97,24 @@ evCreate(evContext *opaqueCtx) {
emulMaskInit(ctx, exLast, EV_EXCEPT, 1);
emulMaskInit(ctx, exNext, EV_EXCEPT, 0);
emulMaskInit(ctx, nonblockBefore, EV_WASNONBLOCKING, 0);
-#endif /* SUNW_POLL */
+#endif /* USE_POLL */
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. */
-#ifdef SUNW_POLL
- ctx->highestFD = INT_MAX;
-#else
+ ctx->fdCount = 0; /*%< Invalidate {rd,wr,ex}Last. */
+#ifndef USE_POLL
ctx->highestFD = FD_SETSIZE - 1;
-#endif /* SUNW_POLL */
+ memset(ctx->fdTable, 0, sizeof ctx->fdTable);
+#else
+ ctx->highestFD = INT_MAX / sizeof(struct pollfd);
+ ctx->fdTable = NULL;
+#endif /* USE_POLL */
#ifdef EVENTLIB_TIME_CHECKS
ctx->lastFdCount = 0;
#endif
-#ifdef SUNW_POLL
- ctx->fdTable = 0;
-#else
- memset(ctx->fdTable, 0, sizeof ctx->fdTable);
-#endif /* SUNW_POLL */
/* Streams. */
ctx->streams = NULL;
@@ -159,7 +150,7 @@ evSetDebug(evContext opaqueCtx, int level, FILE *output) {
int
evDestroy(evContext opaqueCtx) {
evContext_p *ctx = opaqueCtx.opaque;
- int revs = 424242; /* Doug Adams. */
+ int revs = 424242; /*%< Doug Adams. */
evWaitList *this_wl, *next_wl;
evWait *this_wait, *next_wait;
@@ -275,8 +266,7 @@ evGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) {
nextTime = nextTimer->due;
timerPast = (evCmpTime(nextTime, ctx->lastEventTime) <= 0);
} else
- timerPast = 0; /* Make gcc happy. */
-
+ 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};
@@ -309,7 +299,7 @@ evGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) {
if (ctx->debug > 0) {
interval = evSubTime(ctx->lastEventTime,
ctx->lastSelectTime);
- if (interval.tv_sec > 0)
+ 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,
@@ -317,51 +307,37 @@ evGetNext(evContext opaqueCtx, evEvent *opaqueEv, int options) {
}
#endif
do {
-#ifdef SUNW_POLL
+#ifndef USE_POLL
+ /* XXX need to copy only the bits we are using. */
+ ctx->rdLast = ctx->rdNext;
+ ctx->wrLast = ctx->wrNext;
+ ctx->exLast = ctx->exNext;
+#else
/*
* The pollfd structure uses separate fields for
* the input and output events (corresponding to
* the ??Next and ??Last fd sets), so there's no
* need to copy one to the other.
*/
-#else
- /* XXX need to copy only the bits we are using. */
- ctx->rdLast = ctx->rdNext;
- ctx->wrLast = ctx->wrNext;
- ctx->exLast = ctx->exNext;
-#endif /* SUNW_POLL */
-
+#endif /* USE_POLL */
if (m == Timer) {
INSIST(tp == &t);
t = evSubTime(nextTime, ctx->lastEventTime);
}
-#ifdef SUNW_POLL
-#else
- 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);
-#endif
-
/* XXX should predict system's earliness and adjust. */
x = pselect(ctx->fdMax+1,
&ctx->rdLast, &ctx->wrLast, &ctx->exLast,
tp, NULL);
pselect_errno = errno;
-#ifdef SUNW_POLL
- evPrintf(ctx, 4, "poll() returns %d (err: %s)\n",
- x, (x == -1) ? strerror(errno) : "none");
-#else
+#ifndef USE_POLL
evPrintf(ctx, 4, "select() returns %d (err: %s)\n",
x, (x == -1) ? strerror(errno) : "none");
-#endif /* SUNW_POLL */
-
+#else
+ evPrintf(ctx, 4, "poll() returns %d (err: %s)\n",
+ x, (x == -1) ? strerror(errno) : "none");
+#endif /* USE_POLL */
/* Anything but a poll can change the time. */
if (m != JustPoll)
ctx->lastEventTime = evNowTime();
@@ -644,14 +620,17 @@ evDrop(evContext opaqueCtx, evEvent opaqueEv) {
* Timer is still there. Delete it if it has expired,
* otherwise set it according to its next interval.
*/
- if (this->inter.tv_sec == 0 && this->inter.tv_nsec == 0L) {
+ 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(ctx->lastEventTime,
+ evAddTime((this->mode & EV_TMR_RATE) ?
+ this->due :
+ ctx->lastEventTime,
this->inter),
this->inter);
}
@@ -702,7 +681,56 @@ evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) {
va_end(ap);
}
-#ifdef NEED_PSELECT
+int
+evSetOption(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);
+}
+
+int
+evGetOption(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 int
pselect(int nfds, void *rfds, void *wfds, void *efds,
@@ -712,52 +740,53 @@ pselect(int nfds, void *rfds, void *wfds, void *efds,
struct timeval tv, *tvp;
sigset_t sigs;
int n;
-#ifdef SUNW_POLL
- int polltimeout = INFTIM;
+#ifdef USE_POLL
+ int polltimeout = INFTIM;
evContext_p *ctx;
struct pollfd *fds;
nfds_t pnfds;
-#endif
+
+ UNUSED(nfds);
+#endif /* USE_POLL */
if (tsp) {
tvp = &tv;
tv = evTimeVal(*tsp);
-#ifdef SUNW_POLL
- polltimeout = 1000*tv.tv_sec + tv.tv_usec/1000;
-#endif
+#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);
-#ifdef SUNW_POLL
- /*
+#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 != 0)
+ if (rfds != NULL)
ctx = ((__evEmulMask *)rfds)->ctx;
- else if (wfds != 0)
+ else if (wfds != NULL)
ctx = ((__evEmulMask *)wfds)->ctx;
- else if (efds != 0)
+ else if (efds != NULL)
ctx = ((__evEmulMask *)efds)->ctx;
else
- ctx = 0;
- if (ctx != 0) {
+ ctx = NULL;
+ if (ctx != NULL && ctx->fdMax != -1) {
fds = &(ctx->pollfds[ctx->firstfd]);
pnfds = ctx->fdMax - ctx->firstfd + 1;
} else {
- fds = 0;
+ fds = NULL;
pnfds = 0;
}
n = poll(fds, pnfds, polltimeout);
- /*
- * pselect() should return the total number of events on the file
- * descriptors, not just the count of fd:s with activity. Hence,
- * traverse the pollfds array and count the events.
- */
if (n > 0) {
- int i, e;
+ int i, e;
+
+ INSIST(ctx != NULL);
for (e = 0, i = ctx->firstfd; i <= ctx->fdMax; i++) {
if (ctx->pollfds[i].fd < 0)
continue;
@@ -770,9 +799,7 @@ pselect(int nfds, void *rfds, void *wfds, void *efds,
}
n = e;
}
-#else
- n = select(nfds, rfds, wfds, efds, tvp);
-#endif /* SUNW_POLL */
+#endif /* USE_POLL */
if (sigmask)
sigprocmask(SIG_SETMASK, &sigs, NULL);
if (tsp)
@@ -781,70 +808,62 @@ pselect(int nfds, void *rfds, void *wfds, void *efds,
}
#endif
-#ifdef SUNW_POLL
-void
+#ifdef USE_POLL
+int
evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd) {
-
- int old_maxnfds = ctx->maxnfds;
- int i;
-
- if (fd < old_maxnfds)
- return;
-
+
+ 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;
-
- ctx->maxnfds = (1 + (fd/pollfd_chunk_size)) * pollfd_chunk_size;
-
- ctx->pollfds = realloc(ctx->pollfds,
- ctx->maxnfds * sizeof(*ctx->pollfds));
- ctx->fdTable = realloc(ctx->fdTable,
- ctx->maxnfds * sizeof(*ctx->fdTable));
-
- if (ctx->pollfds == 0 || ctx->fdTable == 0) {
- evPrintf(ctx, 2, "pollfd() realloc (%lu) failed\n",
- ctx->maxnfds*sizeof(struct pollfd));
- exit(1);
+
+ 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 = old_maxnfds; i < ctx->maxnfds; i++) {
+
+ for (i = ctx->maxnfds; i < maxnfds; i++) {
ctx->pollfds[i].fd = -1;
ctx->pollfds[i].events = 0;
ctx->fdTable[i] = 0;
}
-}
-/*
- * Neither evPollfdAdd() nor evPollfdDel() are needed anymore. We keep
- * them as no-ops for now so that the in.named code doesn't have to change.
- */
-void
-evPollfdAdd(evContext opaqueCtx, int pollfd_chunk_size, int fd, short events)
-{
-}
+ ctx->maxnfds = maxnfds;
-void
-evPollfdDel(evContext opaqueCtx, int fd)
-{
+ 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;
-
+
+ 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);
@@ -858,7 +877,7 @@ __poll_event(__evEmulMask *maskp) {
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
@@ -866,20 +885,30 @@ __poll_event(__evEmulMask *maskp) {
*/
void
__fd_clr(int fd, __evEmulMask *maskp) {
-
- evContext_p *ctx = maskp->ctx;
-
+
+ evContext_p *ctx = maskp->ctx;
+
*__fd_eventfield(fd, maskp) &= ~__poll_event(maskp);
if ((ctx->pollfds[fd].events & ~POLLHUP) == 0) {
ctx->pollfds[fd].fd = -1;
- for ( ; ctx->fdMax > 0 && ctx->pollfds[ctx->fdMax].fd < 0;
- ctx->fdMax--);
- for ( ; ctx->firstfd <= ctx->fdMax &&
- ctx->pollfds[ctx->firstfd].fd < 0;
- ctx->firstfd++);
+ 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
@@ -887,16 +916,18 @@ __fd_clr(int fd, __evEmulMask *maskp) {
*/
void
__fd_set(int fd, __evEmulMask *maskp) {
-
- evContext_p *ctx = maskp->ctx;
+
+ 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->firstfd == 0)
+ if (fd < ctx->firstfd || ctx->fdMax == -1)
ctx->firstfd = fd;
if (fd > ctx->fdMax)
ctx->fdMax = fd;
}
}
-#endif
+#endif /* USE_POLL */
+
+/*! \file */