1246713Skib/* 2246713Skib * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") 3246713Skib * Copyright (c) 1995-1999 by Internet Software Consortium 4246713Skib * 5246713Skib * Permission to use, copy, modify, and distribute this software for any 6246713Skib * purpose with or without fee is hereby granted, provided that the above 7246713Skib * copyright notice and this permission notice appear in all copies. 8246713Skib * 9246713Skib * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 10246713Skib * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11246713Skib * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 12246713Skib * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13246713Skib * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14246713Skib * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 15246713Skib * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16246713Skib */ 17246713Skib 18246713Skib/*! \file 19246713Skib * \brief private interfaces for eventlib 20246713Skib * \author vix 09sep95 [initial] 21246713Skib * 22246713Skib * $Id: eventlib_p.h,v 1.5.18.4 2006/03/10 00:20:08 marka Exp $ 23246713Skib * $FreeBSD$ 24246713Skib */ 25246713Skib 26246713Skib#ifndef _EVENTLIB_P_H 27246713Skib#define _EVENTLIB_P_H 28246713Skib 29246713Skib#include <sys/param.h> 30246713Skib#include <sys/types.h> 31246713Skib#include <sys/socket.h> 32246713Skib#include <netinet/in.h> 33246713Skib#include <sys/un.h> 34246713Skib 35246713Skib#define EVENTLIB_DEBUG 1 36246713Skib 37246713Skib#include <errno.h> 38246713Skib#include <fcntl.h> 39246713Skib#include <stdio.h> 40246713Skib#include <stdlib.h> 41246713Skib#include <string.h> 42246713Skib 43246713Skib#ifndef _LIBC 44246713Skib#include <isc/list.h> 45246713Skib#include <isc/heap.h> 46246713Skib#include <isc/memcluster.h> 47246713Skib#endif 48246713Skib 49246713Skib#define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) 50246713Skib#define EV_ERR(e) return (errno = (e), -1) 51246713Skib#define OK(x) if ((x) < 0) EV_ERR(errno); else (void)NULL 52246713Skib#define OKFREE(x, y) if ((x) < 0) { FREE((y)); EV_ERR(errno); } \ 53246713Skib else (void)NULL 54246713Skib 55246713Skib#define NEW(p) if (((p) = memget(sizeof *(p))) != NULL) \ 56246713Skib FILL(p); \ 57246713Skib else \ 58246713Skib (void)NULL; 59246713Skib#define OKNEW(p) if (!((p) = memget(sizeof *(p)))) { \ 60246713Skib errno = ENOMEM; \ 61246713Skib return (-1); \ 62246713Skib } else \ 63246713Skib FILL(p) 64246713Skib#define FREE(p) memput((p), sizeof *(p)) 65246713Skib 66246713Skib#if EVENTLIB_DEBUG 67246713Skib#define FILL(p) memset((p), 0xF5, sizeof *(p)) 68246713Skib#else 69246713Skib#define FILL(p) 70246713Skib#endif 71246713Skib 72246713Skib#ifdef USE_POLL 73246713Skib#ifdef HAVE_STROPTS_H 74246713Skib#include <stropts.h> 75246713Skib#endif 76246713Skib#include <poll.h> 77246713Skib#endif /* USE_POLL */ 78246713Skib 79246713Skibtypedef struct evConn { 80246713Skib evConnFunc func; 81246713Skib void * uap; 82246713Skib int fd; 83246713Skib int flags; 84246713Skib#define EV_CONN_LISTEN 0x0001 /*%< Connection is a listener. */ 85246713Skib#define EV_CONN_SELECTED 0x0002 /*%< evSelectFD(conn->file). */ 86246713Skib#define EV_CONN_BLOCK 0x0004 /*%< Listener fd was blocking. */ 87246713Skib evFileID file; 88246713Skib struct evConn * prev; 89246713Skib struct evConn * next; 90246713Skib} evConn; 91246713Skib 92246713Skib#ifndef _LIBC 93246713Skibtypedef struct evAccept { 94246713Skib int fd; 95246713Skib union { 96246713Skib struct sockaddr sa; 97246713Skib struct sockaddr_in in; 98246713Skib#ifndef NO_SOCKADDR_UN 99246713Skib struct sockaddr_un un; 100246713Skib#endif 101246713Skib } la; 102246713Skib ISC_SOCKLEN_T lalen; 103246713Skib union { 104246713Skib struct sockaddr sa; 105246713Skib struct sockaddr_in in; 106246713Skib#ifndef NO_SOCKADDR_UN 107246713Skib struct sockaddr_un un; 108246713Skib#endif 109246713Skib } ra; 110246713Skib ISC_SOCKLEN_T ralen; 111246713Skib int ioErrno; 112246713Skib evConn * conn; 113246713Skib LINK(struct evAccept) link; 114246713Skib} evAccept; 115246713Skib 116246713Skibtypedef struct evFile { 117246713Skib evFileFunc func; 118246713Skib void * uap; 119246713Skib int fd; 120246713Skib int eventmask; 121246713Skib int preemptive; 122246713Skib struct evFile * prev; 123246713Skib struct evFile * next; 124246713Skib struct evFile * fdprev; 125246713Skib struct evFile * fdnext; 126246713Skib} evFile; 127246713Skib 128246713Skibtypedef struct evStream { 129246713Skib evStreamFunc func; 130246713Skib void * uap; 131246713Skib evFileID file; 132246713Skib evTimerID timer; 133246713Skib int flags; 134246713Skib#define EV_STR_TIMEROK 0x0001 /*%< IFF timer valid. */ 135246713Skib int fd; 136246713Skib struct iovec * iovOrig; 137246713Skib int iovOrigCount; 138246713Skib struct iovec * iovCur; 139246713Skib int iovCurCount; 140246713Skib int ioTotal; 141246713Skib int ioDone; 142246713Skib int ioErrno; 143246713Skib struct evStream *prevDone, *nextDone; 144246713Skib struct evStream *prev, *next; 145246713Skib} evStream; 146246713Skib 147246713Skibtypedef struct evTimer { 148246713Skib evTimerFunc func; 149246713Skib void * uap; 150246713Skib struct timespec due, inter; 151246713Skib int index; 152246713Skib int mode; 153246713Skib#define EV_TMR_RATE 1 154246713Skib} evTimer; 155246713Skib 156246713Skibtypedef struct evWait { 157 evWaitFunc func; 158 void * uap; 159 const void * tag; 160 struct evWait * next; 161} evWait; 162 163typedef struct evWaitList { 164 evWait * first; 165 evWait * last; 166 struct evWaitList * prev; 167 struct evWaitList * next; 168} evWaitList; 169 170typedef 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 185typedef 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 196extern short *__fd_eventfield(int fd, __evEmulMask *maskp); 197extern short __poll_event(__evEmulMask *maskp); 198extern void __fd_clr(int fd, __evEmulMask *maskp); 199extern 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 219typedef 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 267void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) 268 ISC_FORMAT_PRINTF(3, 4); 269 270#ifdef USE_POLL 271extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd); 272#endif /* USE_POLL */ 273 274/* ev_timers.c */ 275#define evCreateTimers __evCreateTimers 276heap_context evCreateTimers(const evContext_p *); 277#define evDestroyTimers __evDestroyTimers 278void evDestroyTimers(const evContext_p *); 279 280/* ev_waits.c */ 281#define evFreeWait __evFreeWait 282evWait *evFreeWait(evContext_p *ctx, evWait *old); 283#endif 284 285/* Global options */ 286#ifndef _LIBC 287extern int __evOptMonoTime; 288#endif 289 290#endif /*_EVENTLIB_P_H*/ 291