1*75e1de3cSAugustin Cavalier /* $NetBSD: eventlib_p.h,v 1.3 2009/04/12 17:07:17 christos Exp $ */ 2*75e1de3cSAugustin Cavalier 3aa6411e2SAugustin Cavalier /* 4aa6411e2SAugustin Cavalier * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") 5aa6411e2SAugustin Cavalier * Copyright (c) 1995-1999 by Internet Software Consortium 6aa6411e2SAugustin Cavalier * 7aa6411e2SAugustin Cavalier * Permission to use, copy, modify, and distribute this software for any 8aa6411e2SAugustin Cavalier * purpose with or without fee is hereby granted, provided that the above 9aa6411e2SAugustin Cavalier * copyright notice and this permission notice appear in all copies. 10aa6411e2SAugustin Cavalier * 11aa6411e2SAugustin Cavalier * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 12aa6411e2SAugustin Cavalier * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13aa6411e2SAugustin Cavalier * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 14aa6411e2SAugustin Cavalier * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15aa6411e2SAugustin Cavalier * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16aa6411e2SAugustin Cavalier * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17aa6411e2SAugustin Cavalier * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18aa6411e2SAugustin Cavalier */ 19aa6411e2SAugustin Cavalier 20aa6411e2SAugustin Cavalier /*! \file 21aa6411e2SAugustin Cavalier * \brief private interfaces for eventlib 22aa6411e2SAugustin Cavalier * \author vix 09sep95 [initial] 23aa6411e2SAugustin Cavalier * 24*75e1de3cSAugustin Cavalier * Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp 25aa6411e2SAugustin Cavalier */ 26aa6411e2SAugustin Cavalier 27aa6411e2SAugustin Cavalier #ifndef _EVENTLIB_P_H 28aa6411e2SAugustin Cavalier #define _EVENTLIB_P_H 29aa6411e2SAugustin Cavalier 30aa6411e2SAugustin Cavalier #include <sys/param.h> 31aa6411e2SAugustin Cavalier #include <sys/types.h> 32aa6411e2SAugustin Cavalier #include <sys/socket.h> 33aa6411e2SAugustin Cavalier #include <netinet/in.h> 34aa6411e2SAugustin Cavalier #include <sys/un.h> 35aa6411e2SAugustin Cavalier 36aa6411e2SAugustin Cavalier #define EVENTLIB_DEBUG 1 37aa6411e2SAugustin Cavalier 38aa6411e2SAugustin Cavalier #include <errno.h> 39aa6411e2SAugustin Cavalier #include <fcntl.h> 40aa6411e2SAugustin Cavalier #include <stdio.h> 41aa6411e2SAugustin Cavalier #include <stdlib.h> 42aa6411e2SAugustin Cavalier #include <string.h> 43aa6411e2SAugustin Cavalier 44aa6411e2SAugustin Cavalier #include <isc/heap.h> 45aa6411e2SAugustin Cavalier #include <isc/list.h> 46aa6411e2SAugustin Cavalier #include <isc/memcluster.h> 47aa6411e2SAugustin Cavalier 48aa6411e2SAugustin Cavalier #define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) 49aa6411e2SAugustin Cavalier #define EV_ERR(e) return (errno = (e), -1) 50aa6411e2SAugustin Cavalier #define OK(x) if ((x) < 0) EV_ERR(errno); else (void)NULL 51aa6411e2SAugustin Cavalier #define OKFREE(x, y) if ((x) < 0) { FREE((y)); EV_ERR(errno); } \ 52aa6411e2SAugustin Cavalier else (void)NULL 53aa6411e2SAugustin Cavalier 54aa6411e2SAugustin Cavalier #define NEW(p) if (((p) = memget(sizeof *(p))) != NULL) \ 55aa6411e2SAugustin Cavalier FILL(p); \ 56aa6411e2SAugustin Cavalier else \ 57aa6411e2SAugustin Cavalier (void)NULL; 58aa6411e2SAugustin Cavalier #define OKNEW(p) if (!((p) = memget(sizeof *(p)))) { \ 59aa6411e2SAugustin Cavalier errno = ENOMEM; \ 60aa6411e2SAugustin Cavalier return (-1); \ 61aa6411e2SAugustin Cavalier } else \ 62aa6411e2SAugustin Cavalier FILL(p) 63aa6411e2SAugustin Cavalier #define FREE(p) memput((p), sizeof *(p)) 64aa6411e2SAugustin Cavalier 65aa6411e2SAugustin Cavalier #if EVENTLIB_DEBUG 66aa6411e2SAugustin Cavalier #define FILL(p) memset((p), 0xF5, sizeof *(p)) 67aa6411e2SAugustin Cavalier #else 68aa6411e2SAugustin Cavalier #define FILL(p) 69aa6411e2SAugustin Cavalier #endif 70aa6411e2SAugustin Cavalier 71aa6411e2SAugustin Cavalier #ifdef USE_POLL 72aa6411e2SAugustin Cavalier #ifdef HAVE_STROPTS_H 73aa6411e2SAugustin Cavalier #include <stropts.h> 74aa6411e2SAugustin Cavalier #endif 75aa6411e2SAugustin Cavalier #include <poll.h> 76aa6411e2SAugustin Cavalier #endif /* USE_POLL */ 77aa6411e2SAugustin Cavalier 78aa6411e2SAugustin Cavalier typedef struct evConn { 79aa6411e2SAugustin Cavalier evConnFunc func; 80aa6411e2SAugustin Cavalier void * uap; 81aa6411e2SAugustin Cavalier int fd; 82aa6411e2SAugustin Cavalier int flags; 83aa6411e2SAugustin Cavalier #define EV_CONN_LISTEN 0x0001 /*%< Connection is a listener. */ 84aa6411e2SAugustin Cavalier #define EV_CONN_SELECTED 0x0002 /*%< evSelectFD(conn->file). */ 85aa6411e2SAugustin Cavalier #define EV_CONN_BLOCK 0x0004 /*%< Listener fd was blocking. */ 86aa6411e2SAugustin Cavalier evFileID file; 87aa6411e2SAugustin Cavalier struct evConn * prev; 88aa6411e2SAugustin Cavalier struct evConn * next; 89aa6411e2SAugustin Cavalier } evConn; 90aa6411e2SAugustin Cavalier 91aa6411e2SAugustin Cavalier typedef struct evAccept { 92aa6411e2SAugustin Cavalier int fd; 93aa6411e2SAugustin Cavalier union { 94aa6411e2SAugustin Cavalier struct sockaddr sa; 95aa6411e2SAugustin Cavalier struct sockaddr_in in; 96aa6411e2SAugustin Cavalier #ifndef NO_SOCKADDR_UN 97aa6411e2SAugustin Cavalier struct sockaddr_un un; 98aa6411e2SAugustin Cavalier #endif 99aa6411e2SAugustin Cavalier } la; 100aa6411e2SAugustin Cavalier ISC_SOCKLEN_T lalen; 101aa6411e2SAugustin Cavalier union { 102aa6411e2SAugustin Cavalier struct sockaddr sa; 103aa6411e2SAugustin Cavalier struct sockaddr_in in; 104aa6411e2SAugustin Cavalier #ifndef NO_SOCKADDR_UN 105aa6411e2SAugustin Cavalier struct sockaddr_un un; 106aa6411e2SAugustin Cavalier #endif 107aa6411e2SAugustin Cavalier } ra; 108aa6411e2SAugustin Cavalier ISC_SOCKLEN_T ralen; 109aa6411e2SAugustin Cavalier int ioErrno; 110aa6411e2SAugustin Cavalier evConn * conn; 111aa6411e2SAugustin Cavalier LINK(struct evAccept) link; 112aa6411e2SAugustin Cavalier } evAccept; 113aa6411e2SAugustin Cavalier 114aa6411e2SAugustin Cavalier typedef struct evFile { 115aa6411e2SAugustin Cavalier evFileFunc func; 116aa6411e2SAugustin Cavalier void * uap; 117aa6411e2SAugustin Cavalier int fd; 118aa6411e2SAugustin Cavalier int eventmask; 119aa6411e2SAugustin Cavalier int preemptive; 120aa6411e2SAugustin Cavalier struct evFile * prev; 121aa6411e2SAugustin Cavalier struct evFile * next; 122aa6411e2SAugustin Cavalier struct evFile * fdprev; 123aa6411e2SAugustin Cavalier struct evFile * fdnext; 124aa6411e2SAugustin Cavalier } evFile; 125aa6411e2SAugustin Cavalier 126aa6411e2SAugustin Cavalier typedef struct evStream { 127aa6411e2SAugustin Cavalier evStreamFunc func; 128aa6411e2SAugustin Cavalier void * uap; 129aa6411e2SAugustin Cavalier evFileID file; 130aa6411e2SAugustin Cavalier evTimerID timer; 131aa6411e2SAugustin Cavalier int flags; 132aa6411e2SAugustin Cavalier #define EV_STR_TIMEROK 0x0001 /*%< IFF timer valid. */ 133aa6411e2SAugustin Cavalier int fd; 134aa6411e2SAugustin Cavalier struct iovec * iovOrig; 135aa6411e2SAugustin Cavalier int iovOrigCount; 136aa6411e2SAugustin Cavalier struct iovec * iovCur; 137aa6411e2SAugustin Cavalier int iovCurCount; 138aa6411e2SAugustin Cavalier int ioTotal; 139aa6411e2SAugustin Cavalier int ioDone; 140aa6411e2SAugustin Cavalier int ioErrno; 141aa6411e2SAugustin Cavalier struct evStream *prevDone, *nextDone; 142aa6411e2SAugustin Cavalier struct evStream *prev, *next; 143aa6411e2SAugustin Cavalier } evStream; 144aa6411e2SAugustin Cavalier 145aa6411e2SAugustin Cavalier typedef struct evTimer { 146aa6411e2SAugustin Cavalier evTimerFunc func; 147aa6411e2SAugustin Cavalier void * uap; 148aa6411e2SAugustin Cavalier struct timespec due, inter; 149aa6411e2SAugustin Cavalier int index; 150aa6411e2SAugustin Cavalier int mode; 151aa6411e2SAugustin Cavalier #define EV_TMR_RATE 1 152aa6411e2SAugustin Cavalier } evTimer; 153aa6411e2SAugustin Cavalier 154aa6411e2SAugustin Cavalier typedef struct evWait { 155aa6411e2SAugustin Cavalier evWaitFunc func; 156aa6411e2SAugustin Cavalier void * uap; 157aa6411e2SAugustin Cavalier const void * tag; 158aa6411e2SAugustin Cavalier struct evWait * next; 159aa6411e2SAugustin Cavalier } evWait; 160aa6411e2SAugustin Cavalier 161aa6411e2SAugustin Cavalier typedef struct evWaitList { 162aa6411e2SAugustin Cavalier evWait * first; 163aa6411e2SAugustin Cavalier evWait * last; 164aa6411e2SAugustin Cavalier struct evWaitList * prev; 165aa6411e2SAugustin Cavalier struct evWaitList * next; 166aa6411e2SAugustin Cavalier } evWaitList; 167aa6411e2SAugustin Cavalier 168aa6411e2SAugustin Cavalier typedef struct evEvent_p { 169aa6411e2SAugustin Cavalier enum { Accept, File, Stream, Timer, Wait, Free, Null } type; 170aa6411e2SAugustin Cavalier union { 171aa6411e2SAugustin Cavalier struct { evAccept *this; } accept; 172aa6411e2SAugustin Cavalier struct { evFile *this; int eventmask; } file; 173aa6411e2SAugustin Cavalier struct { evStream *this; } stream; 174aa6411e2SAugustin Cavalier struct { evTimer *this; } timer; 175aa6411e2SAugustin Cavalier struct { evWait *this; } wait; 176aa6411e2SAugustin Cavalier struct { struct evEvent_p *next; } free; 177aa6411e2SAugustin Cavalier struct { const void *placeholder; } null; 178aa6411e2SAugustin Cavalier } u; 179aa6411e2SAugustin Cavalier } evEvent_p; 180aa6411e2SAugustin Cavalier 181aa6411e2SAugustin Cavalier #ifdef USE_POLL 182aa6411e2SAugustin Cavalier typedef struct { 183aa6411e2SAugustin Cavalier void *ctx; /* pointer to the evContext_p */ 184aa6411e2SAugustin Cavalier uint32_t type; /* READ, WRITE, EXCEPT, nonblk */ 185aa6411e2SAugustin Cavalier uint32_t result; /* 1 => revents, 0 => events */ 186aa6411e2SAugustin Cavalier } __evEmulMask; 187aa6411e2SAugustin Cavalier 188aa6411e2SAugustin Cavalier #define emulMaskInit(ctx, field, ev, lastnext) \ 189aa6411e2SAugustin Cavalier ctx->field.ctx = ctx; \ 190aa6411e2SAugustin Cavalier ctx->field.type = ev; \ 191aa6411e2SAugustin Cavalier ctx->field.result = lastnext; 192aa6411e2SAugustin Cavalier 193aa6411e2SAugustin Cavalier extern short *__fd_eventfield(int fd, __evEmulMask *maskp); 194aa6411e2SAugustin Cavalier extern short __poll_event(__evEmulMask *maskp); 195aa6411e2SAugustin Cavalier extern void __fd_clr(int fd, __evEmulMask *maskp); 196aa6411e2SAugustin Cavalier extern void __fd_set(int fd, __evEmulMask *maskp); 197aa6411e2SAugustin Cavalier 198aa6411e2SAugustin Cavalier #undef FD_ZERO 199aa6411e2SAugustin Cavalier #define FD_ZERO(maskp) 200aa6411e2SAugustin Cavalier 201aa6411e2SAugustin Cavalier #undef FD_SET 202aa6411e2SAugustin Cavalier #define FD_SET(fd, maskp) \ 203aa6411e2SAugustin Cavalier __fd_set(fd, maskp) 204aa6411e2SAugustin Cavalier 205aa6411e2SAugustin Cavalier #undef FD_CLR 206aa6411e2SAugustin Cavalier #define FD_CLR(fd, maskp) \ 207aa6411e2SAugustin Cavalier __fd_clr(fd, maskp) 208aa6411e2SAugustin Cavalier 209aa6411e2SAugustin Cavalier #undef FD_ISSET 210aa6411e2SAugustin Cavalier #define FD_ISSET(fd, maskp) \ 211aa6411e2SAugustin Cavalier ((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0) 212aa6411e2SAugustin Cavalier 213aa6411e2SAugustin Cavalier #endif /* USE_POLL */ 214aa6411e2SAugustin Cavalier 215aa6411e2SAugustin Cavalier typedef struct { 216aa6411e2SAugustin Cavalier /* Global. */ 217aa6411e2SAugustin Cavalier const evEvent_p *cur; 218aa6411e2SAugustin Cavalier /* Debugging. */ 219aa6411e2SAugustin Cavalier int debug; 220aa6411e2SAugustin Cavalier FILE *output; 221aa6411e2SAugustin Cavalier /* Connections. */ 222aa6411e2SAugustin Cavalier evConn *conns; 223aa6411e2SAugustin Cavalier LIST(evAccept) accepts; 224aa6411e2SAugustin Cavalier /* Files. */ 225aa6411e2SAugustin Cavalier evFile *files, *fdNext; 226aa6411e2SAugustin Cavalier #ifndef USE_POLL 227aa6411e2SAugustin Cavalier fd_set rdLast, rdNext; 228aa6411e2SAugustin Cavalier fd_set wrLast, wrNext; 229aa6411e2SAugustin Cavalier fd_set exLast, exNext; 230aa6411e2SAugustin Cavalier fd_set nonblockBefore; 231aa6411e2SAugustin Cavalier int fdMax, fdCount, highestFD; 232aa6411e2SAugustin Cavalier evFile *fdTable[FD_SETSIZE]; 233aa6411e2SAugustin Cavalier #else 234aa6411e2SAugustin Cavalier struct pollfd *pollfds; /* Allocated as needed */ 235aa6411e2SAugustin Cavalier evFile **fdTable; /* Ditto */ 236aa6411e2SAugustin Cavalier int maxnfds; /* # elements in above */ 237aa6411e2SAugustin Cavalier int firstfd; /* First active fd */ 238aa6411e2SAugustin Cavalier int fdMax; /* Last active fd */ 239aa6411e2SAugustin Cavalier int fdCount; /* # fd:s with I/O */ 240aa6411e2SAugustin Cavalier int highestFD; /* max fd allowed by OS */ 241aa6411e2SAugustin Cavalier __evEmulMask rdLast, rdNext; 242aa6411e2SAugustin Cavalier __evEmulMask wrLast, wrNext; 243aa6411e2SAugustin Cavalier __evEmulMask exLast, exNext; 244aa6411e2SAugustin Cavalier __evEmulMask nonblockBefore; 245aa6411e2SAugustin Cavalier #endif /* USE_POLL */ 246aa6411e2SAugustin Cavalier #ifdef EVENTLIB_TIME_CHECKS 247aa6411e2SAugustin Cavalier struct timespec lastSelectTime; 248aa6411e2SAugustin Cavalier int lastFdCount; 249aa6411e2SAugustin Cavalier #endif 250aa6411e2SAugustin Cavalier /* Streams. */ 251aa6411e2SAugustin Cavalier evStream *streams; 252aa6411e2SAugustin Cavalier evStream *strDone, *strLast; 253aa6411e2SAugustin Cavalier /* Timers. */ 254aa6411e2SAugustin Cavalier struct timespec lastEventTime; 255aa6411e2SAugustin Cavalier heap_context timers; 256aa6411e2SAugustin Cavalier /* Waits. */ 257aa6411e2SAugustin Cavalier evWaitList *waitLists; 258aa6411e2SAugustin Cavalier evWaitList waitDone; 259aa6411e2SAugustin Cavalier } evContext_p; 260aa6411e2SAugustin Cavalier 261aa6411e2SAugustin Cavalier /* eventlib.c */ 262aa6411e2SAugustin Cavalier #define evPrintf __evPrintf 263aa6411e2SAugustin Cavalier void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) 264aa6411e2SAugustin Cavalier ISC_FORMAT_PRINTF(3, 4); 265aa6411e2SAugustin Cavalier 266aa6411e2SAugustin Cavalier #ifdef USE_POLL 267aa6411e2SAugustin Cavalier extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd); 268aa6411e2SAugustin Cavalier #endif /* USE_POLL */ 269aa6411e2SAugustin Cavalier 270aa6411e2SAugustin Cavalier /* ev_timers.c */ 271aa6411e2SAugustin Cavalier #define evCreateTimers __evCreateTimers 272aa6411e2SAugustin Cavalier heap_context evCreateTimers(const evContext_p *); 273aa6411e2SAugustin Cavalier #define evDestroyTimers __evDestroyTimers 274aa6411e2SAugustin Cavalier void evDestroyTimers(const evContext_p *); 275aa6411e2SAugustin Cavalier 276aa6411e2SAugustin Cavalier /* ev_waits.c */ 277aa6411e2SAugustin Cavalier #define evFreeWait __evFreeWait 278aa6411e2SAugustin Cavalier evWait *evFreeWait(evContext_p *ctx, evWait *old); 279aa6411e2SAugustin Cavalier 280aa6411e2SAugustin Cavalier /* Global options */ 281aa6411e2SAugustin Cavalier extern int __evOptMonoTime; 282aa6411e2SAugustin Cavalier 283aa6411e2SAugustin Cavalier #endif /*_EVENTLIB_P_H*/ 284