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