10Sstevel@tonic-gate /* 2*11038SRao.Shoaib@Sun.COM * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") 30Sstevel@tonic-gate * Copyright (c) 1995-1999 by Internet Software Consortium 40Sstevel@tonic-gate * 50Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 60Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 70Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 80Sstevel@tonic-gate * 9*11038SRao.Shoaib@Sun.COM * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10*11038SRao.Shoaib@Sun.COM * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11*11038SRao.Shoaib@Sun.COM * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12*11038SRao.Shoaib@Sun.COM * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13*11038SRao.Shoaib@Sun.COM * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14*11038SRao.Shoaib@Sun.COM * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15*11038SRao.Shoaib@Sun.COM * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 160Sstevel@tonic-gate */ 170Sstevel@tonic-gate 18*11038SRao.Shoaib@Sun.COM /*! \file 19*11038SRao.Shoaib@Sun.COM * \brief private interfaces for eventlib 20*11038SRao.Shoaib@Sun.COM * \author vix 09sep95 [initial] 210Sstevel@tonic-gate * 22*11038SRao.Shoaib@Sun.COM * $Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp $ 230Sstevel@tonic-gate */ 240Sstevel@tonic-gate 250Sstevel@tonic-gate #ifndef _EVENTLIB_P_H 260Sstevel@tonic-gate #define _EVENTLIB_P_H 270Sstevel@tonic-gate 280Sstevel@tonic-gate #include <sys/param.h> 290Sstevel@tonic-gate #include <sys/types.h> 300Sstevel@tonic-gate #include <sys/socket.h> 310Sstevel@tonic-gate #include <netinet/in.h> 320Sstevel@tonic-gate #include <sys/un.h> 330Sstevel@tonic-gate 340Sstevel@tonic-gate #define EVENTLIB_DEBUG 1 350Sstevel@tonic-gate 360Sstevel@tonic-gate #include <errno.h> 370Sstevel@tonic-gate #include <fcntl.h> 380Sstevel@tonic-gate #include <stdio.h> 390Sstevel@tonic-gate #include <stdlib.h> 400Sstevel@tonic-gate #include <string.h> 410Sstevel@tonic-gate 420Sstevel@tonic-gate #include <isc/heap.h> 430Sstevel@tonic-gate #include <isc/list.h> 440Sstevel@tonic-gate #include <isc/memcluster.h> 450Sstevel@tonic-gate 460Sstevel@tonic-gate #define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) 470Sstevel@tonic-gate #define EV_ERR(e) return (errno = (e), -1) 480Sstevel@tonic-gate #define OK(x) if ((x) < 0) EV_ERR(errno); else (void)NULL 49*11038SRao.Shoaib@Sun.COM #define OKFREE(x, y) if ((x) < 0) { FREE((y)); EV_ERR(errno); } \ 50*11038SRao.Shoaib@Sun.COM else (void)NULL 510Sstevel@tonic-gate 520Sstevel@tonic-gate #define NEW(p) if (((p) = memget(sizeof *(p))) != NULL) \ 530Sstevel@tonic-gate FILL(p); \ 540Sstevel@tonic-gate else \ 550Sstevel@tonic-gate (void)NULL; 560Sstevel@tonic-gate #define OKNEW(p) if (!((p) = memget(sizeof *(p)))) { \ 570Sstevel@tonic-gate errno = ENOMEM; \ 580Sstevel@tonic-gate return (-1); \ 590Sstevel@tonic-gate } else \ 600Sstevel@tonic-gate FILL(p) 610Sstevel@tonic-gate #define FREE(p) memput((p), sizeof *(p)) 620Sstevel@tonic-gate 630Sstevel@tonic-gate #if EVENTLIB_DEBUG 640Sstevel@tonic-gate #define FILL(p) memset((p), 0xF5, sizeof *(p)) 650Sstevel@tonic-gate #else 660Sstevel@tonic-gate #define FILL(p) 670Sstevel@tonic-gate #endif 680Sstevel@tonic-gate 69*11038SRao.Shoaib@Sun.COM #ifdef USE_POLL 70*11038SRao.Shoaib@Sun.COM #ifdef HAVE_STROPTS_H 710Sstevel@tonic-gate #include <stropts.h> 72*11038SRao.Shoaib@Sun.COM #endif 730Sstevel@tonic-gate #include <poll.h> 74*11038SRao.Shoaib@Sun.COM #endif /* USE_POLL */ 750Sstevel@tonic-gate 760Sstevel@tonic-gate typedef struct evConn { 770Sstevel@tonic-gate evConnFunc func; 780Sstevel@tonic-gate void * uap; 790Sstevel@tonic-gate int fd; 800Sstevel@tonic-gate int flags; 81*11038SRao.Shoaib@Sun.COM #define EV_CONN_LISTEN 0x0001 /*%< Connection is a listener. */ 82*11038SRao.Shoaib@Sun.COM #define EV_CONN_SELECTED 0x0002 /*%< evSelectFD(conn->file). */ 83*11038SRao.Shoaib@Sun.COM #define EV_CONN_BLOCK 0x0004 /*%< Listener fd was blocking. */ 840Sstevel@tonic-gate evFileID file; 850Sstevel@tonic-gate struct evConn * prev; 860Sstevel@tonic-gate struct evConn * next; 870Sstevel@tonic-gate } evConn; 880Sstevel@tonic-gate 890Sstevel@tonic-gate typedef struct evAccept { 900Sstevel@tonic-gate int fd; 910Sstevel@tonic-gate union { 920Sstevel@tonic-gate struct sockaddr sa; 930Sstevel@tonic-gate struct sockaddr_in in; 940Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 950Sstevel@tonic-gate struct sockaddr_un un; 960Sstevel@tonic-gate #endif 970Sstevel@tonic-gate } la; 980Sstevel@tonic-gate ISC_SOCKLEN_T lalen; 990Sstevel@tonic-gate union { 1000Sstevel@tonic-gate struct sockaddr sa; 1010Sstevel@tonic-gate struct sockaddr_in in; 1020Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 1030Sstevel@tonic-gate struct sockaddr_un un; 1040Sstevel@tonic-gate #endif 1050Sstevel@tonic-gate } ra; 1060Sstevel@tonic-gate ISC_SOCKLEN_T ralen; 1070Sstevel@tonic-gate int ioErrno; 1080Sstevel@tonic-gate evConn * conn; 1090Sstevel@tonic-gate LINK(struct evAccept) link; 1100Sstevel@tonic-gate } evAccept; 1110Sstevel@tonic-gate 1120Sstevel@tonic-gate typedef struct evFile { 1130Sstevel@tonic-gate evFileFunc func; 1140Sstevel@tonic-gate void * uap; 1150Sstevel@tonic-gate int fd; 1160Sstevel@tonic-gate int eventmask; 1170Sstevel@tonic-gate int preemptive; 1180Sstevel@tonic-gate struct evFile * prev; 1190Sstevel@tonic-gate struct evFile * next; 1200Sstevel@tonic-gate struct evFile * fdprev; 1210Sstevel@tonic-gate struct evFile * fdnext; 1220Sstevel@tonic-gate } evFile; 1230Sstevel@tonic-gate 1240Sstevel@tonic-gate typedef struct evStream { 1250Sstevel@tonic-gate evStreamFunc func; 1260Sstevel@tonic-gate void * uap; 1270Sstevel@tonic-gate evFileID file; 1280Sstevel@tonic-gate evTimerID timer; 1290Sstevel@tonic-gate int flags; 130*11038SRao.Shoaib@Sun.COM #define EV_STR_TIMEROK 0x0001 /*%< IFF timer valid. */ 1310Sstevel@tonic-gate int fd; 1320Sstevel@tonic-gate struct iovec * iovOrig; 1330Sstevel@tonic-gate int iovOrigCount; 1340Sstevel@tonic-gate struct iovec * iovCur; 1350Sstevel@tonic-gate int iovCurCount; 1360Sstevel@tonic-gate int ioTotal; 1370Sstevel@tonic-gate int ioDone; 1380Sstevel@tonic-gate int ioErrno; 1390Sstevel@tonic-gate struct evStream *prevDone, *nextDone; 1400Sstevel@tonic-gate struct evStream *prev, *next; 1410Sstevel@tonic-gate } evStream; 1420Sstevel@tonic-gate 1430Sstevel@tonic-gate typedef struct evTimer { 1440Sstevel@tonic-gate evTimerFunc func; 1450Sstevel@tonic-gate void * uap; 1460Sstevel@tonic-gate struct timespec due, inter; 1470Sstevel@tonic-gate int index; 148*11038SRao.Shoaib@Sun.COM int mode; 149*11038SRao.Shoaib@Sun.COM #define EV_TMR_RATE 1 1500Sstevel@tonic-gate } evTimer; 1510Sstevel@tonic-gate 1520Sstevel@tonic-gate typedef struct evWait { 1530Sstevel@tonic-gate evWaitFunc func; 1540Sstevel@tonic-gate void * uap; 1550Sstevel@tonic-gate const void * tag; 1560Sstevel@tonic-gate struct evWait * next; 1570Sstevel@tonic-gate } evWait; 1580Sstevel@tonic-gate 1590Sstevel@tonic-gate typedef struct evWaitList { 1600Sstevel@tonic-gate evWait * first; 1610Sstevel@tonic-gate evWait * last; 1620Sstevel@tonic-gate struct evWaitList * prev; 1630Sstevel@tonic-gate struct evWaitList * next; 1640Sstevel@tonic-gate } evWaitList; 1650Sstevel@tonic-gate 1660Sstevel@tonic-gate typedef struct evEvent_p { 1670Sstevel@tonic-gate enum { Accept, File, Stream, Timer, Wait, Free, Null } type; 1680Sstevel@tonic-gate union { 1690Sstevel@tonic-gate struct { evAccept *this; } accept; 1700Sstevel@tonic-gate struct { evFile *this; int eventmask; } file; 1710Sstevel@tonic-gate struct { evStream *this; } stream; 1720Sstevel@tonic-gate struct { evTimer *this; } timer; 1730Sstevel@tonic-gate struct { evWait *this; } wait; 1740Sstevel@tonic-gate struct { struct evEvent_p *next; } free; 1750Sstevel@tonic-gate struct { const void *placeholder; } null; 1760Sstevel@tonic-gate } u; 1770Sstevel@tonic-gate } evEvent_p; 1780Sstevel@tonic-gate 179*11038SRao.Shoaib@Sun.COM #ifdef USE_POLL 180*11038SRao.Shoaib@Sun.COM typedef struct { 181*11038SRao.Shoaib@Sun.COM void *ctx; /* pointer to the evContext_p */ 182*11038SRao.Shoaib@Sun.COM uint32_t type; /* READ, WRITE, EXCEPT, nonblk */ 183*11038SRao.Shoaib@Sun.COM uint32_t result; /* 1 => revents, 0 => events */ 184*11038SRao.Shoaib@Sun.COM } __evEmulMask; 1850Sstevel@tonic-gate 186*11038SRao.Shoaib@Sun.COM #define emulMaskInit(ctx, field, ev, lastnext) \ 1870Sstevel@tonic-gate ctx->field.ctx = ctx; \ 1880Sstevel@tonic-gate ctx->field.type = ev; \ 189*11038SRao.Shoaib@Sun.COM ctx->field.result = lastnext; 190*11038SRao.Shoaib@Sun.COM 191*11038SRao.Shoaib@Sun.COM extern short *__fd_eventfield(int fd, __evEmulMask *maskp); 192*11038SRao.Shoaib@Sun.COM extern short __poll_event(__evEmulMask *maskp); 193*11038SRao.Shoaib@Sun.COM extern void __fd_clr(int fd, __evEmulMask *maskp); 194*11038SRao.Shoaib@Sun.COM extern void __fd_set(int fd, __evEmulMask *maskp); 1950Sstevel@tonic-gate 196*11038SRao.Shoaib@Sun.COM #undef FD_ZERO 197*11038SRao.Shoaib@Sun.COM #define FD_ZERO(maskp) 198*11038SRao.Shoaib@Sun.COM 199*11038SRao.Shoaib@Sun.COM #undef FD_SET 200*11038SRao.Shoaib@Sun.COM #define FD_SET(fd, maskp) \ 201*11038SRao.Shoaib@Sun.COM __fd_set(fd, maskp) 2020Sstevel@tonic-gate 203*11038SRao.Shoaib@Sun.COM #undef FD_CLR 204*11038SRao.Shoaib@Sun.COM #define FD_CLR(fd, maskp) \ 205*11038SRao.Shoaib@Sun.COM __fd_clr(fd, maskp) 2060Sstevel@tonic-gate 207*11038SRao.Shoaib@Sun.COM #undef FD_ISSET 208*11038SRao.Shoaib@Sun.COM #define FD_ISSET(fd, maskp) \ 209*11038SRao.Shoaib@Sun.COM ((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0) 2100Sstevel@tonic-gate 211*11038SRao.Shoaib@Sun.COM #endif /* USE_POLL */ 2120Sstevel@tonic-gate 2130Sstevel@tonic-gate typedef struct { 2140Sstevel@tonic-gate /* Global. */ 2150Sstevel@tonic-gate const evEvent_p *cur; 2160Sstevel@tonic-gate /* Debugging. */ 2170Sstevel@tonic-gate int debug; 2180Sstevel@tonic-gate FILE *output; 2190Sstevel@tonic-gate /* Connections. */ 2200Sstevel@tonic-gate evConn *conns; 2210Sstevel@tonic-gate LIST(evAccept) accepts; 2220Sstevel@tonic-gate /* Files. */ 2230Sstevel@tonic-gate evFile *files, *fdNext; 224*11038SRao.Shoaib@Sun.COM #ifndef USE_POLL 2250Sstevel@tonic-gate fd_set rdLast, rdNext; 2260Sstevel@tonic-gate fd_set wrLast, wrNext; 2270Sstevel@tonic-gate fd_set exLast, exNext; 2280Sstevel@tonic-gate fd_set nonblockBefore; 2290Sstevel@tonic-gate int fdMax, fdCount, highestFD; 2300Sstevel@tonic-gate evFile *fdTable[FD_SETSIZE]; 231*11038SRao.Shoaib@Sun.COM #else 232*11038SRao.Shoaib@Sun.COM struct pollfd *pollfds; /* Allocated as needed */ 233*11038SRao.Shoaib@Sun.COM evFile **fdTable; /* Ditto */ 234*11038SRao.Shoaib@Sun.COM int maxnfds; /* # elements in above */ 235*11038SRao.Shoaib@Sun.COM int firstfd; /* First active fd */ 236*11038SRao.Shoaib@Sun.COM int fdMax; /* Last active fd */ 237*11038SRao.Shoaib@Sun.COM int fdCount; /* # fd:s with I/O */ 238*11038SRao.Shoaib@Sun.COM int highestFD; /* max fd allowed by OS */ 239*11038SRao.Shoaib@Sun.COM __evEmulMask rdLast, rdNext; 240*11038SRao.Shoaib@Sun.COM __evEmulMask wrLast, wrNext; 241*11038SRao.Shoaib@Sun.COM __evEmulMask exLast, exNext; 242*11038SRao.Shoaib@Sun.COM __evEmulMask nonblockBefore; 243*11038SRao.Shoaib@Sun.COM #endif /* USE_POLL */ 2440Sstevel@tonic-gate #ifdef EVENTLIB_TIME_CHECKS 2450Sstevel@tonic-gate struct timespec lastSelectTime; 2460Sstevel@tonic-gate int lastFdCount; 2470Sstevel@tonic-gate #endif 2480Sstevel@tonic-gate /* Streams. */ 2490Sstevel@tonic-gate evStream *streams; 2500Sstevel@tonic-gate evStream *strDone, *strLast; 2510Sstevel@tonic-gate /* Timers. */ 2520Sstevel@tonic-gate struct timespec lastEventTime; 2530Sstevel@tonic-gate heap_context timers; 2540Sstevel@tonic-gate /* Waits. */ 2550Sstevel@tonic-gate evWaitList *waitLists; 2560Sstevel@tonic-gate evWaitList waitDone; 2570Sstevel@tonic-gate } evContext_p; 2580Sstevel@tonic-gate 2590Sstevel@tonic-gate /* eventlib.c */ 2600Sstevel@tonic-gate #define evPrintf __evPrintf 2610Sstevel@tonic-gate void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) 2620Sstevel@tonic-gate ISC_FORMAT_PRINTF(3, 4); 2630Sstevel@tonic-gate 264*11038SRao.Shoaib@Sun.COM #ifdef USE_POLL 265*11038SRao.Shoaib@Sun.COM extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd); 266*11038SRao.Shoaib@Sun.COM #endif /* USE_POLL */ 2670Sstevel@tonic-gate 2680Sstevel@tonic-gate /* ev_timers.c */ 2690Sstevel@tonic-gate #define evCreateTimers __evCreateTimers 2700Sstevel@tonic-gate heap_context evCreateTimers(const evContext_p *); 2710Sstevel@tonic-gate #define evDestroyTimers __evDestroyTimers 2720Sstevel@tonic-gate void evDestroyTimers(const evContext_p *); 2730Sstevel@tonic-gate 2740Sstevel@tonic-gate /* ev_waits.c */ 2750Sstevel@tonic-gate #define evFreeWait __evFreeWait 2760Sstevel@tonic-gate evWait *evFreeWait(evContext_p *ctx, evWait *old); 2770Sstevel@tonic-gate 278*11038SRao.Shoaib@Sun.COM /* Global options */ 279*11038SRao.Shoaib@Sun.COM extern int __evOptMonoTime; 280*11038SRao.Shoaib@Sun.COM 2810Sstevel@tonic-gate #endif /*_EVENTLIB_P_H*/ 282