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