1 /*        $NetBSD: eventlib_p.h,v 1.1.1.2 2012/09/09 16:08:02 christos Exp $    */
2 
3 /*
4  * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (c) 1995-1999 by Internet Software Consortium
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 /*! \file
21  * \brief private interfaces for eventlib
22  * \author vix 09sep95 [initial]
23  *
24  * Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp
25  */
26 
27 #ifndef _EVENTLIB_P_H
28 #define _EVENTLIB_P_H
29 
30 #include <sys/param.h>
31 #include <sys/types.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <sys/un.h>
35 
36 #define EVENTLIB_DEBUG 1
37 
38 #include <errno.h>
39 #include <fcntl.h>
40 #include <stdio.h>
41 #include <stdlib.h>
42 #include <string.h>
43 
44 #include <isc/heap.h>
45 #include <isc/list.h>
46 #include <isc/memcluster.h>
47 
48 #define   EV_MASK_ALL         (EV_READ | EV_WRITE | EV_EXCEPT)
49 #define EV_ERR(e)             return (errno = (e), -1)
50 #define OK(x)                 if ((x) < 0) EV_ERR(errno); else (void)NULL
51 #define OKFREE(x, y)          if ((x) < 0) { FREE((y)); EV_ERR(errno); } \
52                               else (void)NULL
53 
54 #define   NEW(p)              if (((p) = memget(sizeof *(p))) != NULL) \
55                                         FILL(p); \
56                               else \
57                                         (void)NULL;
58 #define OKNEW(p)    if (!((p) = memget(sizeof *(p)))) { \
59                                         errno = ENOMEM; \
60                                         return (-1); \
61                               } else \
62                                         FILL(p)
63 #define FREE(p)               memput((p), sizeof *(p))
64 
65 #if EVENTLIB_DEBUG
66 #define FILL(p)               memset((p), 0xF5, sizeof *(p))
67 #else
68 #define FILL(p)
69 #endif
70 
71 #ifdef USE_POLL
72 #ifdef HAVE_STROPTS_H
73 #include <stropts.h>
74 #endif
75 #include <poll.h>
76 #endif /* USE_POLL */
77 
78 typedef struct evConn {
79           evConnFunc          func;
80           void *              uap;
81           int                 fd;
82           int                 flags;
83 #define EV_CONN_LISTEN                  0x0001              /*%< Connection is a listener. */
84 #define EV_CONN_SELECTED      0x0002              /*%< evSelectFD(conn->file). */
85 #define EV_CONN_BLOCK                   0x0004              /*%< Listener fd was blocking. */
86           evFileID  file;
87           struct evConn *     prev;
88           struct evConn *     next;
89 } evConn;
90 
91 typedef struct evAccept {
92           int                 fd;
93           union {
94                     struct sockaddr               sa;
95                     struct sockaddr_in  in;
96 #ifndef NO_SOCKADDR_UN
97                     struct sockaddr_un  un;
98 #endif
99           }                   la;
100           ISC_SOCKLEN_T       lalen;
101           union {
102                     struct sockaddr               sa;
103                     struct sockaddr_in  in;
104 #ifndef NO_SOCKADDR_UN
105                     struct sockaddr_un  un;
106 #endif
107           }                   ra;
108           ISC_SOCKLEN_T       ralen;
109           int                 ioErrno;
110           evConn *  conn;
111           LINK(struct evAccept) link;
112 } evAccept;
113 
114 typedef struct evFile {
115           evFileFunc          func;
116           void *              uap;
117           int                 fd;
118           int                 eventmask;
119           int                 preemptive;
120           struct evFile *     prev;
121           struct evFile *     next;
122           struct evFile *     fdprev;
123           struct evFile *     fdnext;
124 } evFile;
125 
126 typedef 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 
145 typedef 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 
154 typedef struct evWait {
155           evWaitFunc          func;
156           void *              uap;
157           const void *        tag;
158           struct evWait *     next;
159 } evWait;
160 
161 typedef struct evWaitList {
162           evWait *            first;
163           evWait *            last;
164           struct evWaitList * prev;
165           struct evWaitList * next;
166 } evWaitList;
167 
168 typedef 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
182 typedef 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 
193 extern short        *__fd_eventfield(int fd, __evEmulMask *maskp);
194 extern short        __poll_event(__evEmulMask *maskp);
195 extern void                   __fd_clr(int fd, __evEmulMask *maskp);
196 extern 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 
215 typedef 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
263 void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...)
264      ISC_FORMAT_PRINTF(3, 4);
265 
266 #ifdef USE_POLL
267 extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd);
268 #endif /* USE_POLL */
269 
270 /* ev_timers.c */
271 #define evCreateTimers __evCreateTimers
272 heap_context evCreateTimers(const evContext_p *);
273 #define evDestroyTimers __evDestroyTimers
274 void evDestroyTimers(const evContext_p *);
275 
276 /* ev_waits.c */
277 #define evFreeWait __evFreeWait
278 evWait *evFreeWait(evContext_p *ctx, evWait *old);
279 
280 /* Global options */
281 extern int          __evOptMonoTime;
282 
283 #endif /*_EVENTLIB_P_H*/
284