17c478bd9Sstevel@tonic-gate /* 29525b14bSRao Shoaib * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") 37c478bd9Sstevel@tonic-gate * Copyright (c) 1995-1999 by Internet Software Consortium 47c478bd9Sstevel@tonic-gate * 57c478bd9Sstevel@tonic-gate * Permission to use, copy, modify, and distribute this software for any 67c478bd9Sstevel@tonic-gate * purpose with or without fee is hereby granted, provided that the above 77c478bd9Sstevel@tonic-gate * copyright notice and this permission notice appear in all copies. 87c478bd9Sstevel@tonic-gate * 99525b14bSRao Shoaib * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 109525b14bSRao Shoaib * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 119525b14bSRao Shoaib * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 129525b14bSRao Shoaib * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 139525b14bSRao Shoaib * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 149525b14bSRao Shoaib * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 159525b14bSRao Shoaib * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 167c478bd9Sstevel@tonic-gate */ 177c478bd9Sstevel@tonic-gate 18*55fea89dSDan Cross /*! \file 199525b14bSRao Shoaib * \brief private interfaces for eventlib 209525b14bSRao Shoaib * \author vix 09sep95 [initial] 217c478bd9Sstevel@tonic-gate * 229525b14bSRao Shoaib * $Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp $ 237c478bd9Sstevel@tonic-gate */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate #ifndef _EVENTLIB_P_H 267c478bd9Sstevel@tonic-gate #define _EVENTLIB_P_H 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #include <sys/param.h> 297c478bd9Sstevel@tonic-gate #include <sys/types.h> 307c478bd9Sstevel@tonic-gate #include <sys/socket.h> 317c478bd9Sstevel@tonic-gate #include <netinet/in.h> 327c478bd9Sstevel@tonic-gate #include <sys/un.h> 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #define EVENTLIB_DEBUG 1 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate #include <errno.h> 377c478bd9Sstevel@tonic-gate #include <fcntl.h> 387c478bd9Sstevel@tonic-gate #include <stdio.h> 397c478bd9Sstevel@tonic-gate #include <stdlib.h> 407c478bd9Sstevel@tonic-gate #include <string.h> 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate #include <isc/heap.h> 437c478bd9Sstevel@tonic-gate #include <isc/list.h> 447c478bd9Sstevel@tonic-gate #include <isc/memcluster.h> 457c478bd9Sstevel@tonic-gate 467c478bd9Sstevel@tonic-gate #define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) 477c478bd9Sstevel@tonic-gate #define EV_ERR(e) return (errno = (e), -1) 487c478bd9Sstevel@tonic-gate #define OK(x) if ((x) < 0) EV_ERR(errno); else (void)NULL 499525b14bSRao Shoaib #define OKFREE(x, y) if ((x) < 0) { FREE((y)); EV_ERR(errno); } \ 509525b14bSRao Shoaib else (void)NULL 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate #define NEW(p) if (((p) = memget(sizeof *(p))) != NULL) \ 537c478bd9Sstevel@tonic-gate FILL(p); \ 547c478bd9Sstevel@tonic-gate else \ 557c478bd9Sstevel@tonic-gate (void)NULL; 567c478bd9Sstevel@tonic-gate #define OKNEW(p) if (!((p) = memget(sizeof *(p)))) { \ 577c478bd9Sstevel@tonic-gate errno = ENOMEM; \ 587c478bd9Sstevel@tonic-gate return (-1); \ 597c478bd9Sstevel@tonic-gate } else \ 607c478bd9Sstevel@tonic-gate FILL(p) 617c478bd9Sstevel@tonic-gate #define FREE(p) memput((p), sizeof *(p)) 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate #if EVENTLIB_DEBUG 647c478bd9Sstevel@tonic-gate #define FILL(p) memset((p), 0xF5, sizeof *(p)) 657c478bd9Sstevel@tonic-gate #else 667c478bd9Sstevel@tonic-gate #define FILL(p) 677c478bd9Sstevel@tonic-gate #endif 687c478bd9Sstevel@tonic-gate 699525b14bSRao Shoaib #ifdef USE_POLL 709525b14bSRao Shoaib #ifdef HAVE_STROPTS_H 717c478bd9Sstevel@tonic-gate #include <stropts.h> 727c478bd9Sstevel@tonic-gate #endif 739525b14bSRao Shoaib #include <poll.h> 749525b14bSRao Shoaib #endif /* USE_POLL */ 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate typedef struct evConn { 777c478bd9Sstevel@tonic-gate evConnFunc func; 787c478bd9Sstevel@tonic-gate void * uap; 797c478bd9Sstevel@tonic-gate int fd; 807c478bd9Sstevel@tonic-gate int flags; 819525b14bSRao Shoaib #define EV_CONN_LISTEN 0x0001 /*%< Connection is a listener. */ 829525b14bSRao Shoaib #define EV_CONN_SELECTED 0x0002 /*%< evSelectFD(conn->file). */ 839525b14bSRao Shoaib #define EV_CONN_BLOCK 0x0004 /*%< Listener fd was blocking. */ 847c478bd9Sstevel@tonic-gate evFileID file; 857c478bd9Sstevel@tonic-gate struct evConn * prev; 867c478bd9Sstevel@tonic-gate struct evConn * next; 877c478bd9Sstevel@tonic-gate } evConn; 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate typedef struct evAccept { 907c478bd9Sstevel@tonic-gate int fd; 917c478bd9Sstevel@tonic-gate union { 927c478bd9Sstevel@tonic-gate struct sockaddr sa; 937c478bd9Sstevel@tonic-gate struct sockaddr_in in; 947c478bd9Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 957c478bd9Sstevel@tonic-gate struct sockaddr_un un; 967c478bd9Sstevel@tonic-gate #endif 977c478bd9Sstevel@tonic-gate } la; 987c478bd9Sstevel@tonic-gate ISC_SOCKLEN_T lalen; 997c478bd9Sstevel@tonic-gate union { 1007c478bd9Sstevel@tonic-gate struct sockaddr sa; 1017c478bd9Sstevel@tonic-gate struct sockaddr_in in; 1027c478bd9Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN 1037c478bd9Sstevel@tonic-gate struct sockaddr_un un; 1047c478bd9Sstevel@tonic-gate #endif 1057c478bd9Sstevel@tonic-gate } ra; 1067c478bd9Sstevel@tonic-gate ISC_SOCKLEN_T ralen; 1077c478bd9Sstevel@tonic-gate int ioErrno; 1087c478bd9Sstevel@tonic-gate evConn * conn; 1097c478bd9Sstevel@tonic-gate LINK(struct evAccept) link; 1107c478bd9Sstevel@tonic-gate } evAccept; 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate typedef struct evFile { 1137c478bd9Sstevel@tonic-gate evFileFunc func; 1147c478bd9Sstevel@tonic-gate void * uap; 1157c478bd9Sstevel@tonic-gate int fd; 1167c478bd9Sstevel@tonic-gate int eventmask; 1177c478bd9Sstevel@tonic-gate int preemptive; 1187c478bd9Sstevel@tonic-gate struct evFile * prev; 1197c478bd9Sstevel@tonic-gate struct evFile * next; 1207c478bd9Sstevel@tonic-gate struct evFile * fdprev; 1217c478bd9Sstevel@tonic-gate struct evFile * fdnext; 1227c478bd9Sstevel@tonic-gate } evFile; 1237c478bd9Sstevel@tonic-gate 1247c478bd9Sstevel@tonic-gate typedef struct evStream { 1257c478bd9Sstevel@tonic-gate evStreamFunc func; 1267c478bd9Sstevel@tonic-gate void * uap; 1277c478bd9Sstevel@tonic-gate evFileID file; 1287c478bd9Sstevel@tonic-gate evTimerID timer; 1297c478bd9Sstevel@tonic-gate int flags; 1309525b14bSRao Shoaib #define EV_STR_TIMEROK 0x0001 /*%< IFF timer valid. */ 1317c478bd9Sstevel@tonic-gate int fd; 1327c478bd9Sstevel@tonic-gate struct iovec * iovOrig; 1337c478bd9Sstevel@tonic-gate int iovOrigCount; 1347c478bd9Sstevel@tonic-gate struct iovec * iovCur; 1357c478bd9Sstevel@tonic-gate int iovCurCount; 1367c478bd9Sstevel@tonic-gate int ioTotal; 1377c478bd9Sstevel@tonic-gate int ioDone; 1387c478bd9Sstevel@tonic-gate int ioErrno; 1397c478bd9Sstevel@tonic-gate struct evStream *prevDone, *nextDone; 1407c478bd9Sstevel@tonic-gate struct evStream *prev, *next; 1417c478bd9Sstevel@tonic-gate } evStream; 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate typedef struct evTimer { 1447c478bd9Sstevel@tonic-gate evTimerFunc func; 1457c478bd9Sstevel@tonic-gate void * uap; 1467c478bd9Sstevel@tonic-gate struct timespec due, inter; 1477c478bd9Sstevel@tonic-gate int index; 1489525b14bSRao Shoaib int mode; 1499525b14bSRao Shoaib #define EV_TMR_RATE 1 1507c478bd9Sstevel@tonic-gate } evTimer; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate typedef struct evWait { 1537c478bd9Sstevel@tonic-gate evWaitFunc func; 1547c478bd9Sstevel@tonic-gate void * uap; 1557c478bd9Sstevel@tonic-gate const void * tag; 1567c478bd9Sstevel@tonic-gate struct evWait * next; 1577c478bd9Sstevel@tonic-gate } evWait; 1587c478bd9Sstevel@tonic-gate 1597c478bd9Sstevel@tonic-gate typedef struct evWaitList { 1607c478bd9Sstevel@tonic-gate evWait * first; 1617c478bd9Sstevel@tonic-gate evWait * last; 1627c478bd9Sstevel@tonic-gate struct evWaitList * prev; 1637c478bd9Sstevel@tonic-gate struct evWaitList * next; 1647c478bd9Sstevel@tonic-gate } evWaitList; 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate typedef struct evEvent_p { 1677c478bd9Sstevel@tonic-gate enum { Accept, File, Stream, Timer, Wait, Free, Null } type; 1687c478bd9Sstevel@tonic-gate union { 1697c478bd9Sstevel@tonic-gate struct { evAccept *this; } accept; 1707c478bd9Sstevel@tonic-gate struct { evFile *this; int eventmask; } file; 1717c478bd9Sstevel@tonic-gate struct { evStream *this; } stream; 1727c478bd9Sstevel@tonic-gate struct { evTimer *this; } timer; 1737c478bd9Sstevel@tonic-gate struct { evWait *this; } wait; 1747c478bd9Sstevel@tonic-gate struct { struct evEvent_p *next; } free; 1757c478bd9Sstevel@tonic-gate struct { const void *placeholder; } null; 1767c478bd9Sstevel@tonic-gate } u; 1777c478bd9Sstevel@tonic-gate } evEvent_p; 1787c478bd9Sstevel@tonic-gate 1799525b14bSRao Shoaib #ifdef USE_POLL 180*55fea89dSDan Cross typedef struct { 181*55fea89dSDan Cross void *ctx; /* pointer to the evContext_p */ 182*55fea89dSDan Cross uint32_t type; /* READ, WRITE, EXCEPT, nonblk */ 183*55fea89dSDan Cross uint32_t result; /* 1 => revents, 0 => events */ 184*55fea89dSDan Cross } __evEmulMask; 1857c478bd9Sstevel@tonic-gate 1869525b14bSRao Shoaib #define emulMaskInit(ctx, field, ev, lastnext) \ 1877c478bd9Sstevel@tonic-gate ctx->field.ctx = ctx; \ 1887c478bd9Sstevel@tonic-gate ctx->field.type = ev; \ 189*55fea89dSDan Cross ctx->field.result = lastnext; 190*55fea89dSDan Cross 191*55fea89dSDan Cross extern short *__fd_eventfield(int fd, __evEmulMask *maskp); 192*55fea89dSDan Cross extern short __poll_event(__evEmulMask *maskp); 193*55fea89dSDan Cross extern void __fd_clr(int fd, __evEmulMask *maskp); 194*55fea89dSDan Cross extern void __fd_set(int fd, __evEmulMask *maskp); 195*55fea89dSDan Cross 196*55fea89dSDan Cross #undef FD_ZERO 197*55fea89dSDan Cross #define FD_ZERO(maskp) 198*55fea89dSDan Cross 199*55fea89dSDan Cross #undef FD_SET 2009525b14bSRao Shoaib #define FD_SET(fd, maskp) \ 201*55fea89dSDan Cross __fd_set(fd, maskp) 2029525b14bSRao Shoaib 203*55fea89dSDan Cross #undef FD_CLR 2049525b14bSRao Shoaib #define FD_CLR(fd, maskp) \ 205*55fea89dSDan Cross __fd_clr(fd, maskp) 2069525b14bSRao Shoaib 207*55fea89dSDan Cross #undef FD_ISSET 2089525b14bSRao Shoaib #define FD_ISSET(fd, maskp) \ 209*55fea89dSDan Cross ((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0) 2109525b14bSRao Shoaib 2119525b14bSRao Shoaib #endif /* USE_POLL */ 2127c478bd9Sstevel@tonic-gate 2137c478bd9Sstevel@tonic-gate typedef struct { 2147c478bd9Sstevel@tonic-gate /* Global. */ 2157c478bd9Sstevel@tonic-gate const evEvent_p *cur; 2167c478bd9Sstevel@tonic-gate /* Debugging. */ 2177c478bd9Sstevel@tonic-gate int debug; 2187c478bd9Sstevel@tonic-gate FILE *output; 2197c478bd9Sstevel@tonic-gate /* Connections. */ 2207c478bd9Sstevel@tonic-gate evConn *conns; 2217c478bd9Sstevel@tonic-gate LIST(evAccept) accepts; 2227c478bd9Sstevel@tonic-gate /* Files. */ 2237c478bd9Sstevel@tonic-gate evFile *files, *fdNext; 2249525b14bSRao Shoaib #ifndef USE_POLL 2257c478bd9Sstevel@tonic-gate fd_set rdLast, rdNext; 2267c478bd9Sstevel@tonic-gate fd_set wrLast, wrNext; 2277c478bd9Sstevel@tonic-gate fd_set exLast, exNext; 2287c478bd9Sstevel@tonic-gate fd_set nonblockBefore; 2297c478bd9Sstevel@tonic-gate int fdMax, fdCount, highestFD; 2307c478bd9Sstevel@tonic-gate evFile *fdTable[FD_SETSIZE]; 2319525b14bSRao Shoaib #else 232*55fea89dSDan Cross struct pollfd *pollfds; /* Allocated as needed */ 233*55fea89dSDan Cross evFile **fdTable; /* Ditto */ 234*55fea89dSDan Cross int maxnfds; /* # elements in above */ 235*55fea89dSDan Cross int firstfd; /* First active fd */ 236*55fea89dSDan Cross int fdMax; /* Last active fd */ 237*55fea89dSDan Cross int fdCount; /* # fd:s with I/O */ 238*55fea89dSDan Cross int highestFD; /* max fd allowed by OS */ 239*55fea89dSDan Cross __evEmulMask rdLast, rdNext; 240*55fea89dSDan Cross __evEmulMask wrLast, wrNext; 241*55fea89dSDan Cross __evEmulMask exLast, exNext; 242*55fea89dSDan Cross __evEmulMask nonblockBefore; 2439525b14bSRao Shoaib #endif /* USE_POLL */ 2447c478bd9Sstevel@tonic-gate #ifdef EVENTLIB_TIME_CHECKS 2457c478bd9Sstevel@tonic-gate struct timespec lastSelectTime; 2467c478bd9Sstevel@tonic-gate int lastFdCount; 2477c478bd9Sstevel@tonic-gate #endif 2487c478bd9Sstevel@tonic-gate /* Streams. */ 2497c478bd9Sstevel@tonic-gate evStream *streams; 2507c478bd9Sstevel@tonic-gate evStream *strDone, *strLast; 2517c478bd9Sstevel@tonic-gate /* Timers. */ 2527c478bd9Sstevel@tonic-gate struct timespec lastEventTime; 2537c478bd9Sstevel@tonic-gate heap_context timers; 2547c478bd9Sstevel@tonic-gate /* Waits. */ 2557c478bd9Sstevel@tonic-gate evWaitList *waitLists; 2567c478bd9Sstevel@tonic-gate evWaitList waitDone; 2577c478bd9Sstevel@tonic-gate } evContext_p; 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate /* eventlib.c */ 2607c478bd9Sstevel@tonic-gate #define evPrintf __evPrintf 2617c478bd9Sstevel@tonic-gate void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) 2627c478bd9Sstevel@tonic-gate ISC_FORMAT_PRINTF(3, 4); 2637c478bd9Sstevel@tonic-gate 2649525b14bSRao Shoaib #ifdef USE_POLL 2659525b14bSRao Shoaib extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd); 2669525b14bSRao Shoaib #endif /* USE_POLL */ 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* ev_timers.c */ 2697c478bd9Sstevel@tonic-gate #define evCreateTimers __evCreateTimers 2707c478bd9Sstevel@tonic-gate heap_context evCreateTimers(const evContext_p *); 2717c478bd9Sstevel@tonic-gate #define evDestroyTimers __evDestroyTimers 2727c478bd9Sstevel@tonic-gate void evDestroyTimers(const evContext_p *); 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate /* ev_waits.c */ 2757c478bd9Sstevel@tonic-gate #define evFreeWait __evFreeWait 2767c478bd9Sstevel@tonic-gate evWait *evFreeWait(evContext_p *ctx, evWait *old); 2777c478bd9Sstevel@tonic-gate 2789525b14bSRao Shoaib /* Global options */ 2799525b14bSRao Shoaib extern int __evOptMonoTime; 2809525b14bSRao Shoaib 2817c478bd9Sstevel@tonic-gate #endif /*_EVENTLIB_P_H*/ 282