eventlib_p.h revision 156952
1/*
2 * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (c) 1995-1999 by Internet Software Consortium
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
18/* eventlib_p.h - private interfaces for eventlib
19 * vix 09sep95 [initial]
20 *
21 * $Id: eventlib_p.h,v 1.3.2.1.4.3 2005/07/28 07:43:20 marka Exp $
22 */
23
24#ifndef _EVENTLIB_P_H
25#define _EVENTLIB_P_H
26
27#include <sys/param.h>
28#include <sys/types.h>
29#include <sys/socket.h>
30#include <netinet/in.h>
31#include <sys/un.h>
32
33#define EVENTLIB_DEBUG 1
34
35#include <errno.h>
36#include <fcntl.h>
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
40
41#include <isc/heap.h>
42#include <isc/list.h>
43#include <isc/memcluster.h>
44
45#define	EV_MASK_ALL	(EV_READ | EV_WRITE | EV_EXCEPT)
46#define EV_ERR(e)		return (errno = (e), -1)
47#define OK(x)		if ((x) < 0) EV_ERR(errno); else (void)NULL
48
49#define	NEW(p)		if (((p) = memget(sizeof *(p))) != NULL) \
50				FILL(p); \
51			else \
52				(void)NULL;
53#define OKNEW(p)	if (!((p) = memget(sizeof *(p)))) { \
54				errno = ENOMEM; \
55				return (-1); \
56			} else \
57				FILL(p)
58#define FREE(p)		memput((p), sizeof *(p))
59
60#if EVENTLIB_DEBUG
61#define FILL(p)		memset((p), 0xF5, sizeof *(p))
62#else
63#define FILL(p)
64#endif
65
66#ifdef USE_POLL
67#ifdef HAVE_STROPTS_H
68#include <stropts.h>
69#endif
70#include <poll.h>
71#endif /* USE_POLL */
72
73typedef struct evConn {
74	evConnFunc	func;
75	void *		uap;
76	int		fd;
77	int		flags;
78#define EV_CONN_LISTEN		0x0001		/* Connection is a listener. */
79#define EV_CONN_SELECTED	0x0002		/* evSelectFD(conn->file). */
80#define EV_CONN_BLOCK		0x0004		/* Listener fd was blocking. */
81	evFileID	file;
82	struct evConn *	prev;
83	struct evConn *	next;
84} evConn;
85
86typedef struct evAccept {
87	int		fd;
88	union {
89		struct sockaddr		sa;
90		struct sockaddr_in	in;
91#ifndef NO_SOCKADDR_UN
92		struct sockaddr_un	un;
93#endif
94	}		la;
95	ISC_SOCKLEN_T	lalen;
96	union {
97		struct sockaddr		sa;
98		struct sockaddr_in	in;
99#ifndef NO_SOCKADDR_UN
100		struct sockaddr_un	un;
101#endif
102	}		ra;
103	ISC_SOCKLEN_T	ralen;
104	int		ioErrno;
105	evConn *	conn;
106	LINK(struct evAccept) link;
107} evAccept;
108
109typedef struct evFile {
110	evFileFunc	func;
111	void *		uap;
112	int		fd;
113	int		eventmask;
114	int		preemptive;
115	struct evFile *	prev;
116	struct evFile *	next;
117	struct evFile *	fdprev;
118	struct evFile *	fdnext;
119} evFile;
120
121typedef struct evStream {
122	evStreamFunc	func;
123	void *		uap;
124	evFileID	file;
125	evTimerID	timer;
126	int		flags;
127#define EV_STR_TIMEROK	0x0001	/* IFF timer valid. */
128	int		fd;
129	struct iovec *	iovOrig;
130	int		iovOrigCount;
131	struct iovec *	iovCur;
132	int		iovCurCount;
133	int		ioTotal;
134	int		ioDone;
135	int		ioErrno;
136	struct evStream	*prevDone, *nextDone;
137	struct evStream	*prev, *next;
138} evStream;
139
140typedef struct evTimer {
141	evTimerFunc	func;
142	void *		uap;
143	struct timespec	due, inter;
144	int		index;
145	int		mode;
146#define EV_TMR_RATE	1
147} evTimer;
148
149typedef struct evWait {
150	evWaitFunc	func;
151	void *		uap;
152	const void *	tag;
153	struct evWait *	next;
154} evWait;
155
156typedef struct evWaitList {
157	evWait *		first;
158	evWait *		last;
159	struct evWaitList *	prev;
160	struct evWaitList *	next;
161} evWaitList;
162
163typedef struct evEvent_p {
164	enum {  Accept, File, Stream, Timer, Wait, Free, Null  } type;
165	union {
166		struct {  evAccept *this;  }			accept;
167		struct {  evFile *this; int eventmask;  }	file;
168		struct {  evStream *this;  }			stream;
169		struct {  evTimer *this;  }			timer;
170		struct {  evWait *this;  }			wait;
171		struct {  struct evEvent_p *next;  }		free;
172		struct {  const void *placeholder;  }		null;
173	} u;
174} evEvent_p;
175
176#ifdef USE_POLL
177typedef struct {
178	void		*ctx;	/* pointer to the evContext_p   */
179	uint32_t	type;	/* READ, WRITE, EXCEPT, nonblk  */
180	uint32_t	result;	/* 1 => revents, 0 => events    */
181} __evEmulMask;
182
183#define emulMaskInit(ctx, field, ev, lastnext) \
184	ctx->field.ctx = ctx; \
185	ctx->field.type = ev; \
186	ctx->field.result = lastnext;
187
188extern short	*__fd_eventfield(int fd, __evEmulMask *maskp);
189extern short	__poll_event(__evEmulMask *maskp);
190extern void		__fd_clr(int fd, __evEmulMask *maskp);
191extern void		__fd_set(int fd, __evEmulMask *maskp);
192
193#undef  FD_ZERO
194#define FD_ZERO(maskp)
195
196#undef  FD_SET
197#define FD_SET(fd, maskp) \
198	__fd_set(fd, maskp)
199
200#undef  FD_CLR
201#define FD_CLR(fd, maskp) \
202	__fd_clr(fd, maskp)
203
204#undef  FD_ISSET
205#define FD_ISSET(fd, maskp) \
206	((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0)
207
208#endif /* USE_POLL */
209
210typedef struct {
211	/* Global. */
212	const evEvent_p	*cur;
213	/* Debugging. */
214	int		debug;
215	FILE		*output;
216	/* Connections. */
217	evConn		*conns;
218	LIST(evAccept)	accepts;
219	/* Files. */
220	evFile		*files, *fdNext;
221#ifndef USE_POLL
222	fd_set		rdLast, rdNext;
223	fd_set		wrLast, wrNext;
224	fd_set		exLast, exNext;
225	fd_set		nonblockBefore;
226	int		fdMax, fdCount, highestFD;
227	evFile		*fdTable[FD_SETSIZE];
228#else
229	struct pollfd	*pollfds;	/* Allocated as needed  */
230	evFile		**fdTable;	/* Ditto                */
231	int		maxnfds;	/* # elements in above  */
232	int		firstfd;	/* First active fd      */
233	int		fdMax;		/* Last active fd       */
234	int		fdCount;	/* # fd:s with I/O      */
235	int		highestFD;	/* max fd allowed by OS */
236	__evEmulMask	rdLast, rdNext;
237	__evEmulMask	wrLast, wrNext;
238	__evEmulMask	exLast, exNext;
239	__evEmulMask	nonblockBefore;
240#endif /* USE_POLL */
241#ifdef EVENTLIB_TIME_CHECKS
242	struct timespec	lastSelectTime;
243	int		lastFdCount;
244#endif
245	/* Streams. */
246	evStream	*streams;
247	evStream	*strDone, *strLast;
248	/* Timers. */
249	struct timespec	lastEventTime;
250	heap_context	timers;
251	/* Waits. */
252	evWaitList	*waitLists;
253	evWaitList	waitDone;
254} evContext_p;
255
256/* eventlib.c */
257#define evPrintf __evPrintf
258void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...)
259     ISC_FORMAT_PRINTF(3, 4);
260
261#ifdef USE_POLL
262extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd);
263#endif /* USE_POLL */
264
265/* ev_timers.c */
266#define evCreateTimers __evCreateTimers
267heap_context evCreateTimers(const evContext_p *);
268#define evDestroyTimers __evDestroyTimers
269void evDestroyTimers(const evContext_p *);
270
271/* ev_waits.c */
272#define evFreeWait __evFreeWait
273evWait *evFreeWait(evContext_p *ctx, evWait *old);
274
275/* Global options */
276extern int	__evOptMonoTime;
277
278#endif /*_EVENTLIB_P_H*/
279