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