1*59a755a4Schristos /* $NetBSD: eventlib_p.h,v 1.3 2009/04/12 17:07:17 christos Exp $ */ 2330989eeSchristos 3330989eeSchristos /* 48e42b6c9Schristos * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") 5330989eeSchristos * Copyright (c) 1995-1999 by Internet Software Consortium 6330989eeSchristos * 7330989eeSchristos * Permission to use, copy, modify, and distribute this software for any 8330989eeSchristos * purpose with or without fee is hereby granted, provided that the above 9330989eeSchristos * copyright notice and this permission notice appear in all copies. 10330989eeSchristos * 11330989eeSchristos * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 12330989eeSchristos * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13330989eeSchristos * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 14330989eeSchristos * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15330989eeSchristos * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16330989eeSchristos * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 17330989eeSchristos * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18330989eeSchristos */ 19330989eeSchristos 208e42b6c9Schristos /*! \file 218e42b6c9Schristos * \brief private interfaces for eventlib 228e42b6c9Schristos * \author vix 09sep95 [initial] 23330989eeSchristos * 243873655bSchristos * Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp 25330989eeSchristos */ 26330989eeSchristos 27330989eeSchristos #ifndef _EVENTLIB_P_H 28330989eeSchristos #define _EVENTLIB_P_H 29330989eeSchristos 30330989eeSchristos #include <sys/param.h> 31330989eeSchristos #include <sys/types.h> 32330989eeSchristos #include <sys/socket.h> 33330989eeSchristos #include <netinet/in.h> 34330989eeSchristos #include <sys/un.h> 35330989eeSchristos 36330989eeSchristos #define EVENTLIB_DEBUG 1 37330989eeSchristos 38330989eeSchristos #include <errno.h> 39330989eeSchristos #include <fcntl.h> 40330989eeSchristos #include <stdio.h> 41330989eeSchristos #include <stdlib.h> 42330989eeSchristos #include <string.h> 43330989eeSchristos 44330989eeSchristos #include <isc/heap.h> 45330989eeSchristos #include <isc/list.h> 46330989eeSchristos #include <isc/memcluster.h> 47330989eeSchristos 48330989eeSchristos #define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) 49330989eeSchristos #define EV_ERR(e) return (errno = (e), -1) 50330989eeSchristos #define OK(x) if ((x) < 0) EV_ERR(errno); else (void)NULL 518e42b6c9Schristos #define OKFREE(x, y) if ((x) < 0) { FREE((y)); EV_ERR(errno); } \ 528e42b6c9Schristos else (void)NULL 53330989eeSchristos 54330989eeSchristos #define NEW(p) if (((p) = memget(sizeof *(p))) != NULL) \ 55330989eeSchristos FILL(p); \ 56330989eeSchristos else \ 57330989eeSchristos (void)NULL; 58330989eeSchristos #define OKNEW(p) if (!((p) = memget(sizeof *(p)))) { \ 59330989eeSchristos errno = ENOMEM; \ 60330989eeSchristos return (-1); \ 61330989eeSchristos } else \ 62330989eeSchristos FILL(p) 63330989eeSchristos #define FREE(p) memput((p), sizeof *(p)) 64330989eeSchristos 65330989eeSchristos #if EVENTLIB_DEBUG 66330989eeSchristos #define FILL(p) memset((p), 0xF5, sizeof *(p)) 67330989eeSchristos #else 68330989eeSchristos #define FILL(p) 69330989eeSchristos #endif 70330989eeSchristos 718e42b6c9Schristos #ifdef USE_POLL 728e42b6c9Schristos #ifdef HAVE_STROPTS_H 738e42b6c9Schristos #include <stropts.h> 748e42b6c9Schristos #endif 758e42b6c9Schristos #include <poll.h> 768e42b6c9Schristos #endif /* USE_POLL */ 778e42b6c9Schristos 78330989eeSchristos typedef struct evConn { 79330989eeSchristos evConnFunc func; 80330989eeSchristos void * uap; 81330989eeSchristos int fd; 82330989eeSchristos int flags; 838e42b6c9Schristos #define EV_CONN_LISTEN 0x0001 /*%< Connection is a listener. */ 848e42b6c9Schristos #define EV_CONN_SELECTED 0x0002 /*%< evSelectFD(conn->file). */ 858e42b6c9Schristos #define EV_CONN_BLOCK 0x0004 /*%< Listener fd was blocking. */ 86330989eeSchristos evFileID file; 87330989eeSchristos struct evConn * prev; 88330989eeSchristos struct evConn * next; 89330989eeSchristos } evConn; 90330989eeSchristos 91330989eeSchristos typedef struct evAccept { 92330989eeSchristos int fd; 93330989eeSchristos union { 94330989eeSchristos struct sockaddr sa; 95330989eeSchristos struct sockaddr_in in; 96330989eeSchristos #ifndef NO_SOCKADDR_UN 97330989eeSchristos struct sockaddr_un un; 98330989eeSchristos #endif 99330989eeSchristos } la; 100330989eeSchristos ISC_SOCKLEN_T lalen; 101330989eeSchristos union { 102330989eeSchristos struct sockaddr sa; 103330989eeSchristos struct sockaddr_in in; 104330989eeSchristos #ifndef NO_SOCKADDR_UN 105330989eeSchristos struct sockaddr_un un; 106330989eeSchristos #endif 107330989eeSchristos } ra; 108330989eeSchristos ISC_SOCKLEN_T ralen; 109330989eeSchristos int ioErrno; 110330989eeSchristos evConn * conn; 111330989eeSchristos LINK(struct evAccept) link; 112330989eeSchristos } evAccept; 113330989eeSchristos 114330989eeSchristos typedef struct evFile { 115330989eeSchristos evFileFunc func; 116330989eeSchristos void * uap; 117330989eeSchristos int fd; 118330989eeSchristos int eventmask; 119330989eeSchristos int preemptive; 120330989eeSchristos struct evFile * prev; 121330989eeSchristos struct evFile * next; 122330989eeSchristos struct evFile * fdprev; 123330989eeSchristos struct evFile * fdnext; 124330989eeSchristos } evFile; 125330989eeSchristos 126330989eeSchristos typedef struct evStream { 127330989eeSchristos evStreamFunc func; 128330989eeSchristos void * uap; 129330989eeSchristos evFileID file; 130330989eeSchristos evTimerID timer; 131330989eeSchristos int flags; 1328e42b6c9Schristos #define EV_STR_TIMEROK 0x0001 /*%< IFF timer valid. */ 133330989eeSchristos int fd; 134330989eeSchristos struct iovec * iovOrig; 135330989eeSchristos int iovOrigCount; 136330989eeSchristos struct iovec * iovCur; 137330989eeSchristos int iovCurCount; 138330989eeSchristos int ioTotal; 139330989eeSchristos int ioDone; 140330989eeSchristos int ioErrno; 141330989eeSchristos struct evStream *prevDone, *nextDone; 142330989eeSchristos struct evStream *prev, *next; 143330989eeSchristos } evStream; 144330989eeSchristos 145330989eeSchristos typedef struct evTimer { 146330989eeSchristos evTimerFunc func; 147330989eeSchristos void * uap; 148330989eeSchristos struct timespec due, inter; 149330989eeSchristos int index; 150330989eeSchristos int mode; 151330989eeSchristos #define EV_TMR_RATE 1 152330989eeSchristos } evTimer; 153330989eeSchristos 154330989eeSchristos typedef struct evWait { 155330989eeSchristos evWaitFunc func; 156330989eeSchristos void * uap; 157330989eeSchristos const void * tag; 158330989eeSchristos struct evWait * next; 159330989eeSchristos } evWait; 160330989eeSchristos 161330989eeSchristos typedef struct evWaitList { 162330989eeSchristos evWait * first; 163330989eeSchristos evWait * last; 164330989eeSchristos struct evWaitList * prev; 165330989eeSchristos struct evWaitList * next; 166330989eeSchristos } evWaitList; 167330989eeSchristos 168330989eeSchristos typedef struct evEvent_p { 169330989eeSchristos enum { Accept, File, Stream, Timer, Wait, Free, Null } type; 170330989eeSchristos union { 171330989eeSchristos struct { evAccept *this; } accept; 172330989eeSchristos struct { evFile *this; int eventmask; } file; 173330989eeSchristos struct { evStream *this; } stream; 174330989eeSchristos struct { evTimer *this; } timer; 175330989eeSchristos struct { evWait *this; } wait; 176330989eeSchristos struct { struct evEvent_p *next; } free; 177330989eeSchristos struct { const void *placeholder; } null; 178330989eeSchristos } u; 179330989eeSchristos } evEvent_p; 180330989eeSchristos 1818e42b6c9Schristos #ifdef USE_POLL 1828e42b6c9Schristos typedef struct { 1838e42b6c9Schristos void *ctx; /* pointer to the evContext_p */ 1848e42b6c9Schristos uint32_t type; /* READ, WRITE, EXCEPT, nonblk */ 1858e42b6c9Schristos uint32_t result; /* 1 => revents, 0 => events */ 1868e42b6c9Schristos } __evEmulMask; 1878e42b6c9Schristos 1888e42b6c9Schristos #define emulMaskInit(ctx, field, ev, lastnext) \ 1898e42b6c9Schristos ctx->field.ctx = ctx; \ 1908e42b6c9Schristos ctx->field.type = ev; \ 1918e42b6c9Schristos ctx->field.result = lastnext; 1928e42b6c9Schristos 1938e42b6c9Schristos extern short *__fd_eventfield(int fd, __evEmulMask *maskp); 1948e42b6c9Schristos extern short __poll_event(__evEmulMask *maskp); 1958e42b6c9Schristos extern void __fd_clr(int fd, __evEmulMask *maskp); 1968e42b6c9Schristos extern void __fd_set(int fd, __evEmulMask *maskp); 1978e42b6c9Schristos 1988e42b6c9Schristos #undef FD_ZERO 1998e42b6c9Schristos #define FD_ZERO(maskp) 2008e42b6c9Schristos 2018e42b6c9Schristos #undef FD_SET 2028e42b6c9Schristos #define FD_SET(fd, maskp) \ 2038e42b6c9Schristos __fd_set(fd, maskp) 2048e42b6c9Schristos 2058e42b6c9Schristos #undef FD_CLR 2068e42b6c9Schristos #define FD_CLR(fd, maskp) \ 2078e42b6c9Schristos __fd_clr(fd, maskp) 2088e42b6c9Schristos 2098e42b6c9Schristos #undef FD_ISSET 2108e42b6c9Schristos #define FD_ISSET(fd, maskp) \ 2118e42b6c9Schristos ((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0) 2128e42b6c9Schristos 2138e42b6c9Schristos #endif /* USE_POLL */ 2148e42b6c9Schristos 215330989eeSchristos typedef struct { 216330989eeSchristos /* Global. */ 217330989eeSchristos const evEvent_p *cur; 218330989eeSchristos /* Debugging. */ 219330989eeSchristos int debug; 220330989eeSchristos FILE *output; 221330989eeSchristos /* Connections. */ 222330989eeSchristos evConn *conns; 223330989eeSchristos LIST(evAccept) accepts; 224330989eeSchristos /* Files. */ 225330989eeSchristos evFile *files, *fdNext; 2268e42b6c9Schristos #ifndef USE_POLL 227330989eeSchristos fd_set rdLast, rdNext; 228330989eeSchristos fd_set wrLast, wrNext; 229330989eeSchristos fd_set exLast, exNext; 230330989eeSchristos fd_set nonblockBefore; 231330989eeSchristos int fdMax, fdCount, highestFD; 232330989eeSchristos evFile *fdTable[FD_SETSIZE]; 2338e42b6c9Schristos #else 2348e42b6c9Schristos struct pollfd *pollfds; /* Allocated as needed */ 2358e42b6c9Schristos evFile **fdTable; /* Ditto */ 2368e42b6c9Schristos int maxnfds; /* # elements in above */ 2378e42b6c9Schristos int firstfd; /* First active fd */ 2388e42b6c9Schristos int fdMax; /* Last active fd */ 2398e42b6c9Schristos int fdCount; /* # fd:s with I/O */ 2408e42b6c9Schristos int highestFD; /* max fd allowed by OS */ 2418e42b6c9Schristos __evEmulMask rdLast, rdNext; 2428e42b6c9Schristos __evEmulMask wrLast, wrNext; 2438e42b6c9Schristos __evEmulMask exLast, exNext; 2448e42b6c9Schristos __evEmulMask nonblockBefore; 2458e42b6c9Schristos #endif /* USE_POLL */ 246330989eeSchristos #ifdef EVENTLIB_TIME_CHECKS 247330989eeSchristos struct timespec lastSelectTime; 248330989eeSchristos int lastFdCount; 249330989eeSchristos #endif 250330989eeSchristos /* Streams. */ 251330989eeSchristos evStream *streams; 252330989eeSchristos evStream *strDone, *strLast; 253330989eeSchristos /* Timers. */ 254330989eeSchristos struct timespec lastEventTime; 255330989eeSchristos heap_context timers; 256330989eeSchristos /* Waits. */ 257330989eeSchristos evWaitList *waitLists; 258330989eeSchristos evWaitList waitDone; 259330989eeSchristos } evContext_p; 260330989eeSchristos 261330989eeSchristos /* eventlib.c */ 262330989eeSchristos #define evPrintf __evPrintf 263330989eeSchristos void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) 264330989eeSchristos ISC_FORMAT_PRINTF(3, 4); 265330989eeSchristos 2668e42b6c9Schristos #ifdef USE_POLL 2678e42b6c9Schristos extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd); 2688e42b6c9Schristos #endif /* USE_POLL */ 2698e42b6c9Schristos 270330989eeSchristos /* ev_timers.c */ 271330989eeSchristos #define evCreateTimers __evCreateTimers 272330989eeSchristos heap_context evCreateTimers(const evContext_p *); 273330989eeSchristos #define evDestroyTimers __evDestroyTimers 274330989eeSchristos void evDestroyTimers(const evContext_p *); 275330989eeSchristos 276330989eeSchristos /* ev_waits.c */ 277330989eeSchristos #define evFreeWait __evFreeWait 278330989eeSchristos evWait *evFreeWait(evContext_p *ctx, evWait *old); 279330989eeSchristos 280330989eeSchristos /* Global options */ 2818e42b6c9Schristos extern int __evOptMonoTime; 282330989eeSchristos 283330989eeSchristos #endif /*_EVENTLIB_P_H*/ 284