| /* $NetBSD: eventlib_p.h,v 1.3 2009/04/12 17:07:17 christos Exp $ */ |
| |
| /* |
| * Copyright (c) 2005 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. |
| */ |
| |
| /*! \file |
| * \brief private interfaces for eventlib |
| * \author vix 09sep95 [initial] |
| * |
| * Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp |
| */ |
| |
| #ifndef _EVENTLIB_P_H |
| #define _EVENTLIB_P_H |
| |
| #include <sys/param.h> |
| #include <sys/types.h> |
| #include <sys/socket.h> |
| #include <netinet/in.h> |
| #include <sys/un.h> |
| |
| #define EVENTLIB_DEBUG 1 |
| |
| #include <errno.h> |
| #include <fcntl.h> |
| #include <stdio.h> |
| #include <stdlib.h> |
| #include <string.h> |
| |
| #include <isc/heap.h> |
| #include <isc/list.h> |
| #include <isc/memcluster.h> |
| |
| #define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) |
| #define EV_ERR(e) return (errno = (e), -1) |
| #define OK(x) if ((x) < 0) EV_ERR(errno); else (void)NULL |
| #define OKFREE(x, y) if ((x) < 0) { FREE((y)); EV_ERR(errno); } \ |
| else (void)NULL |
| |
| #define NEW(p) if (((p) = memget(sizeof *(p))) != NULL) \ |
| FILL(p); \ |
| else \ |
| (void)NULL; |
| #define OKNEW(p) if (!((p) = memget(sizeof *(p)))) { \ |
| errno = ENOMEM; \ |
| return (-1); \ |
| } else \ |
| FILL(p) |
| #define FREE(p) memput((p), sizeof *(p)) |
| |
| #if EVENTLIB_DEBUG |
| #define FILL(p) memset((p), 0xF5, sizeof *(p)) |
| #else |
| #define FILL(p) |
| #endif |
| |
| #ifdef USE_POLL |
| #ifdef HAVE_STROPTS_H |
| #include <stropts.h> |
| #endif |
| #include <poll.h> |
| #endif /* USE_POLL */ |
| |
| typedef struct evConn { |
| evConnFunc func; |
| void * uap; |
| int fd; |
| int flags; |
| #define EV_CONN_LISTEN 0x0001 /*%< Connection is a listener. */ |
| #define EV_CONN_SELECTED 0x0002 /*%< evSelectFD(conn->file). */ |
| #define EV_CONN_BLOCK 0x0004 /*%< Listener fd was blocking. */ |
| evFileID file; |
| struct evConn * prev; |
| struct evConn * next; |
| } evConn; |
| |
| typedef struct evAccept { |
| int fd; |
| union { |
| struct sockaddr sa; |
| struct sockaddr_in in; |
| #ifndef NO_SOCKADDR_UN |
| struct sockaddr_un un; |
| #endif |
| } la; |
| ISC_SOCKLEN_T lalen; |
| union { |
| struct sockaddr sa; |
| struct sockaddr_in in; |
| #ifndef NO_SOCKADDR_UN |
| struct sockaddr_un un; |
| #endif |
| } ra; |
| ISC_SOCKLEN_T ralen; |
| int ioErrno; |
| evConn * conn; |
| LINK(struct evAccept) link; |
| } evAccept; |
| |
| typedef struct evFile { |
| evFileFunc func; |
| void * uap; |
| int fd; |
| int eventmask; |
| int preemptive; |
| struct evFile * prev; |
| struct evFile * next; |
| struct evFile * fdprev; |
| struct evFile * fdnext; |
| } evFile; |
| |
| typedef struct evStream { |
| evStreamFunc func; |
| void * uap; |
| evFileID file; |
| evTimerID timer; |
| int flags; |
| #define EV_STR_TIMEROK 0x0001 /*%< IFF timer valid. */ |
| int fd; |
| struct iovec * iovOrig; |
| int iovOrigCount; |
| struct iovec * iovCur; |
| int iovCurCount; |
| int ioTotal; |
| int ioDone; |
| int ioErrno; |
| struct evStream *prevDone, *nextDone; |
| struct evStream *prev, *next; |
| } evStream; |
| |
| typedef struct evTimer { |
| evTimerFunc func; |
| void * uap; |
| struct timespec due, inter; |
| int index; |
| int mode; |
| #define EV_TMR_RATE 1 |
| } evTimer; |
| |
| typedef struct evWait { |
| evWaitFunc func; |
| void * uap; |
| const void * tag; |
| struct evWait * next; |
| } evWait; |
| |
| typedef struct evWaitList { |
| evWait * first; |
| evWait * last; |
| struct evWaitList * prev; |
| struct evWaitList * next; |
| } evWaitList; |
| |
| typedef struct evEvent_p { |
| enum { Accept, File, Stream, Timer, Wait, Free, Null } type; |
| union { |
| struct { evAccept *this; } accept; |
| struct { evFile *this; int eventmask; } file; |
| struct { evStream *this; } stream; |
| struct { evTimer *this; } timer; |
| struct { evWait *this; } wait; |
| struct { struct evEvent_p *next; } free; |
| struct { const void *placeholder; } null; |
| } u; |
| } evEvent_p; |
| |
| #ifdef USE_POLL |
| typedef struct { |
| void *ctx; /* pointer to the evContext_p */ |
| uint32_t type; /* READ, WRITE, EXCEPT, nonblk */ |
| uint32_t result; /* 1 => revents, 0 => events */ |
| } __evEmulMask; |
| |
| #define emulMaskInit(ctx, field, ev, lastnext) \ |
| ctx->field.ctx = ctx; \ |
| ctx->field.type = ev; \ |
| ctx->field.result = lastnext; |
| |
| extern short *__fd_eventfield(int fd, __evEmulMask *maskp); |
| extern short __poll_event(__evEmulMask *maskp); |
| extern void __fd_clr(int fd, __evEmulMask *maskp); |
| extern void __fd_set(int fd, __evEmulMask *maskp); |
| |
| #undef FD_ZERO |
| #define FD_ZERO(maskp) |
| |
| #undef FD_SET |
| #define FD_SET(fd, maskp) \ |
| __fd_set(fd, maskp) |
| |
| #undef FD_CLR |
| #define FD_CLR(fd, maskp) \ |
| __fd_clr(fd, maskp) |
| |
| #undef FD_ISSET |
| #define FD_ISSET(fd, maskp) \ |
| ((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0) |
| |
| #endif /* USE_POLL */ |
| |
| typedef struct { |
| /* Global. */ |
| const evEvent_p *cur; |
| /* Debugging. */ |
| int debug; |
| FILE *output; |
| /* Connections. */ |
| evConn *conns; |
| LIST(evAccept) accepts; |
| /* Files. */ |
| evFile *files, *fdNext; |
| #ifndef USE_POLL |
| fd_set rdLast, rdNext; |
| fd_set wrLast, wrNext; |
| fd_set exLast, exNext; |
| fd_set nonblockBefore; |
| int fdMax, fdCount, highestFD; |
| evFile *fdTable[FD_SETSIZE]; |
| #else |
| struct pollfd *pollfds; /* Allocated as needed */ |
| evFile **fdTable; /* Ditto */ |
| int maxnfds; /* # elements in above */ |
| int firstfd; /* First active fd */ |
| int fdMax; /* Last active fd */ |
| int fdCount; /* # fd:s with I/O */ |
| int highestFD; /* max fd allowed by OS */ |
| __evEmulMask rdLast, rdNext; |
| __evEmulMask wrLast, wrNext; |
| __evEmulMask exLast, exNext; |
| __evEmulMask nonblockBefore; |
| #endif /* USE_POLL */ |
| #ifdef EVENTLIB_TIME_CHECKS |
| struct timespec lastSelectTime; |
| int lastFdCount; |
| #endif |
| /* Streams. */ |
| evStream *streams; |
| evStream *strDone, *strLast; |
| /* Timers. */ |
| struct timespec lastEventTime; |
| heap_context timers; |
| /* Waits. */ |
| evWaitList *waitLists; |
| evWaitList waitDone; |
| } evContext_p; |
| |
| /* eventlib.c */ |
| #define evPrintf __evPrintf |
| void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) |
| ISC_FORMAT_PRINTF(3, 4); |
| |
| #ifdef USE_POLL |
| extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd); |
| #endif /* USE_POLL */ |
| |
| /* ev_timers.c */ |
| #define evCreateTimers __evCreateTimers |
| heap_context evCreateTimers(const evContext_p *); |
| #define evDestroyTimers __evDestroyTimers |
| void evDestroyTimers(const evContext_p *); |
| |
| /* ev_waits.c */ |
| #define evFreeWait __evFreeWait |
| evWait *evFreeWait(evContext_p *ctx, evWait *old); |
| |
| /* Global options */ |
| extern int __evOptMonoTime; |
| |
| #endif /*_EVENTLIB_P_H*/ |