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