130862Sache/* $NetBSD$ */ 230862Sache 330862Sache/* 430862Sache * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC") 530862Sache * Copyright (c) 1995-1999 by Internet Software Consortium 630862Sache * 730862Sache * Permission to use, copy, modify, and distribute this software for any 830862Sache * purpose with or without fee is hereby granted, provided that the above 930862Sache * copyright notice and this permission notice appear in all copies. 1030862Sache * 1130862Sache * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 1230862Sache * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 1330862Sache * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 1430862Sache * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 1530862Sache * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 1630862Sache * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 1730862Sache * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 1830862Sache */ 1930862Sache 2030862Sache/*! \file 2130862Sache * \brief private interfaces for eventlib 2230862Sache * \author vix 09sep95 [initial] 2330862Sache * 2430862Sache * Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp 2530862Sache */ 2630862Sache 2730862Sache#ifndef _EVENTLIB_P_H 2830862Sache#define _EVENTLIB_P_H 2930862Sache 3030862Sache#include <sys/param.h> 3130862Sache#include <sys/types.h> 3230862Sache#include <sys/socket.h> 3330862Sache#include <netinet/in.h> 3430862Sache#include <sys/un.h> 3530862Sache 3630862Sache#define EVENTLIB_DEBUG 1 3730862Sache 3830862Sache#include <errno.h> 3930862Sache#include <fcntl.h> 4030862Sache#include <stdio.h> 4130862Sache#include <stdlib.h> 4230862Sache#include <string.h> 4330862Sache 4430862Sache#include <isc/heap.h> 4530862Sache#include <isc/list.h> 4630862Sache#include <isc/memcluster.h> 4730862Sache 4830862Sache#define EV_MASK_ALL (EV_READ | EV_WRITE | EV_EXCEPT) 4930862Sache#define EV_ERR(e) return (errno = (e), -1) 5030862Sache#define OK(x) if ((x) < 0) EV_ERR(errno); else (void)NULL 5130862Sache#define OKFREE(x, y) if ((x) < 0) { FREE((y)); EV_ERR(errno); } \ 5230862Sache else (void)NULL 5330862Sache 5430862Sache#define NEW(p) if (((p) = memget(sizeof *(p))) != NULL) \ 5530862Sache FILL(p); \ 5630862Sache else \ 5730862Sache (void)NULL; 5830862Sache#define OKNEW(p) if (!((p) = memget(sizeof *(p)))) { \ 5930862Sache errno = ENOMEM; \ 6030862Sache return (-1); \ 6130862Sache } else \ 6230862Sache FILL(p) 6330862Sache#define FREE(p) memput((p), sizeof *(p)) 6430862Sache 6530862Sache#if EVENTLIB_DEBUG 6630862Sache#define FILL(p) memset((p), 0xF5, sizeof *(p)) 6730862Sache#else 6830862Sache#define FILL(p) 6930862Sache#endif 7030862Sache 7130862Sache#ifdef USE_POLL 7230862Sache#ifdef HAVE_STROPTS_H 7330862Sache#include <stropts.h> 7430862Sache#endif 7530862Sache#include <poll.h> 7630862Sache#endif /* USE_POLL */ 7730862Sache 7830862Sachetypedef struct evConn { 7930862Sache evConnFunc func; 8030862Sache void * uap; 8130862Sache int fd; 8230862Sache int flags; 8330862Sache#define EV_CONN_LISTEN 0x0001 /*%< Connection is a listener. */ 8430862Sache#define EV_CONN_SELECTED 0x0002 /*%< evSelectFD(conn->file). */ 8530862Sache#define EV_CONN_BLOCK 0x0004 /*%< Listener fd was blocking. */ 8630862Sache evFileID file; 8730862Sache struct evConn * prev; 8830862Sache struct evConn * next; 8930862Sache} evConn; 9030862Sache 9130862Sachetypedef struct evAccept { 9230862Sache int fd; 9330862Sache union { 9430862Sache struct sockaddr sa; 9530862Sache struct sockaddr_in in; 9630862Sache#ifndef NO_SOCKADDR_UN 9730862Sache struct sockaddr_un un; 9830862Sache#endif 9930862Sache } la; 10030862Sache ISC_SOCKLEN_T lalen; 10130862Sache union { 10230862Sache struct sockaddr sa; 10330862Sache struct sockaddr_in in; 10430862Sache#ifndef NO_SOCKADDR_UN 10530862Sache struct sockaddr_un un; 10630862Sache#endif 10730862Sache } ra; 10830862Sache ISC_SOCKLEN_T ralen; 10930862Sache int ioErrno; 11030862Sache evConn * conn; 11130862Sache LINK(struct evAccept) link; 11230862Sache} evAccept; 11330862Sache 11430862Sachetypedef struct evFile { 11530862Sache evFileFunc func; 11630862Sache void * uap; 11730862Sache int fd; 11830862Sache int eventmask; 119 int preemptive; 120 struct evFile * prev; 121 struct evFile * next; 122 struct evFile * fdprev; 123 struct evFile * fdnext; 124} evFile; 125 126typedef struct evStream { 127 evStreamFunc func; 128 void * uap; 129 evFileID file; 130 evTimerID timer; 131 int flags; 132#define EV_STR_TIMEROK 0x0001 /*%< IFF timer valid. */ 133 int fd; 134 struct iovec * iovOrig; 135 int iovOrigCount; 136 struct iovec * iovCur; 137 int iovCurCount; 138 int ioTotal; 139 int ioDone; 140 int ioErrno; 141 struct evStream *prevDone, *nextDone; 142 struct evStream *prev, *next; 143} evStream; 144 145typedef struct evTimer { 146 evTimerFunc func; 147 void * uap; 148 struct timespec due, inter; 149 int index; 150 int mode; 151#define EV_TMR_RATE 1 152} evTimer; 153 154typedef struct evWait { 155 evWaitFunc func; 156 void * uap; 157 const void * tag; 158 struct evWait * next; 159} evWait; 160 161typedef struct evWaitList { 162 evWait * first; 163 evWait * last; 164 struct evWaitList * prev; 165 struct evWaitList * next; 166} evWaitList; 167 168typedef struct evEvent_p { 169 enum { Accept, File, Stream, Timer, Wait, Free, Null } type; 170 union { 171 struct { evAccept *this; } accept; 172 struct { evFile *this; int eventmask; } file; 173 struct { evStream *this; } stream; 174 struct { evTimer *this; } timer; 175 struct { evWait *this; } wait; 176 struct { struct evEvent_p *next; } free; 177 struct { const void *placeholder; } null; 178 } u; 179} evEvent_p; 180 181#ifdef USE_POLL 182typedef struct { 183 void *ctx; /* pointer to the evContext_p */ 184 uint32_t type; /* READ, WRITE, EXCEPT, nonblk */ 185 uint32_t result; /* 1 => revents, 0 => events */ 186} __evEmulMask; 187 188#define emulMaskInit(ctx, field, ev, lastnext) \ 189 ctx->field.ctx = ctx; \ 190 ctx->field.type = ev; \ 191 ctx->field.result = lastnext; 192 193extern short *__fd_eventfield(int fd, __evEmulMask *maskp); 194extern short __poll_event(__evEmulMask *maskp); 195extern void __fd_clr(int fd, __evEmulMask *maskp); 196extern void __fd_set(int fd, __evEmulMask *maskp); 197 198#undef FD_ZERO 199#define FD_ZERO(maskp) 200 201#undef FD_SET 202#define FD_SET(fd, maskp) \ 203 __fd_set(fd, maskp) 204 205#undef FD_CLR 206#define FD_CLR(fd, maskp) \ 207 __fd_clr(fd, maskp) 208 209#undef FD_ISSET 210#define FD_ISSET(fd, maskp) \ 211 ((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0) 212 213#endif /* USE_POLL */ 214 215typedef struct { 216 /* Global. */ 217 const evEvent_p *cur; 218 /* Debugging. */ 219 int debug; 220 FILE *output; 221 /* Connections. */ 222 evConn *conns; 223 LIST(evAccept) accepts; 224 /* Files. */ 225 evFile *files, *fdNext; 226#ifndef USE_POLL 227 fd_set rdLast, rdNext; 228 fd_set wrLast, wrNext; 229 fd_set exLast, exNext; 230 fd_set nonblockBefore; 231 int fdMax, fdCount, highestFD; 232 evFile *fdTable[FD_SETSIZE]; 233#else 234 struct pollfd *pollfds; /* Allocated as needed */ 235 evFile **fdTable; /* Ditto */ 236 int maxnfds; /* # elements in above */ 237 int firstfd; /* First active fd */ 238 int fdMax; /* Last active fd */ 239 int fdCount; /* # fd:s with I/O */ 240 int highestFD; /* max fd allowed by OS */ 241 __evEmulMask rdLast, rdNext; 242 __evEmulMask wrLast, wrNext; 243 __evEmulMask exLast, exNext; 244 __evEmulMask nonblockBefore; 245#endif /* USE_POLL */ 246#ifdef EVENTLIB_TIME_CHECKS 247 struct timespec lastSelectTime; 248 int lastFdCount; 249#endif 250 /* Streams. */ 251 evStream *streams; 252 evStream *strDone, *strLast; 253 /* Timers. */ 254 struct timespec lastEventTime; 255 heap_context timers; 256 /* Waits. */ 257 evWaitList *waitLists; 258 evWaitList waitDone; 259} evContext_p; 260 261/* eventlib.c */ 262#define evPrintf __evPrintf 263void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...) 264 ISC_FORMAT_PRINTF(3, 4); 265 266#ifdef USE_POLL 267extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd); 268#endif /* USE_POLL */ 269 270/* ev_timers.c */ 271#define evCreateTimers __evCreateTimers 272heap_context evCreateTimers(const evContext_p *); 273#define evDestroyTimers __evDestroyTimers 274void evDestroyTimers(const evContext_p *); 275 276/* ev_waits.c */ 277#define evFreeWait __evFreeWait 278evWait *evFreeWait(evContext_p *ctx, evWait *old); 279 280/* Global options */ 281extern int __evOptMonoTime; 282 283#endif /*_EVENTLIB_P_H*/ 284