1191665Sbms/*	$NetBSD: eventlib_p.h,v 1.1.1.4 2009/04/12 16:35:46 christos Exp $	*/
2191665Sbms
3191665Sbms/*
4191665Sbms * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
5191665Sbms * Copyright (c) 1995-1999 by Internet Software Consortium
6191665Sbms *
7191665Sbms * Permission to use, copy, modify, and distribute this software for any
8191665Sbms * purpose with or without fee is hereby granted, provided that the above
9191665Sbms * copyright notice and this permission notice appear in all copies.
10191665Sbms *
11191665Sbms * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12191665Sbms * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13191665Sbms * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14191665Sbms * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15191665Sbms * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16191665Sbms * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17191665Sbms * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18191665Sbms */
19191665Sbms
20191665Sbms/*! \file
21191665Sbms * \brief private interfaces for eventlib
22191665Sbms * \author vix 09sep95 [initial]
23191665Sbms *
24191665Sbms * Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp
25191665Sbms */
26191665Sbms
27191665Sbms#ifndef _EVENTLIB_P_H
28191665Sbms#define _EVENTLIB_P_H
29191665Sbms
30191665Sbms#include <sys/param.h>
31191665Sbms#include <sys/types.h>
32191672Sbms#include <sys/socket.h>
33191665Sbms#include <netinet/in.h>
34191665Sbms#include <sys/un.h>
35191665Sbms
36191665Sbms#define EVENTLIB_DEBUG 1
37191665Sbms
38191665Sbms#include <errno.h>
39191665Sbms#include <fcntl.h>
40191665Sbms#include <stdio.h>
41191665Sbms#include <stdlib.h>
42191665Sbms#include <string.h>
43191665Sbms
44191665Sbms#include <isc/heap.h>
45191665Sbms#include <isc/list.h>
46191665Sbms#include <isc/memcluster.h>
47191665Sbms
48191665Sbms#define	EV_MASK_ALL	(EV_READ | EV_WRITE | EV_EXCEPT)
49191665Sbms#define EV_ERR(e)		return (errno = (e), -1)
50191665Sbms#define OK(x)		if ((x) < 0) EV_ERR(errno); else (void)NULL
51191665Sbms#define OKFREE(x, y)	if ((x) < 0) { FREE((y)); EV_ERR(errno); } \
52191665Sbms			else (void)NULL
53191665Sbms
54191665Sbms#define	NEW(p)		if (((p) = memget(sizeof *(p))) != NULL) \
55191665Sbms				FILL(p); \
56191665Sbms			else \
57191665Sbms				(void)NULL;
58191665Sbms#define OKNEW(p)	if (!((p) = memget(sizeof *(p)))) { \
59191665Sbms				errno = ENOMEM; \
60191665Sbms				return (-1); \
61191665Sbms			} else \
62191665Sbms				FILL(p)
63191665Sbms#define FREE(p)		memput((p), sizeof *(p))
64191665Sbms
65191665Sbms#if EVENTLIB_DEBUG
66191665Sbms#define FILL(p)		memset((p), 0xF5, sizeof *(p))
67191665Sbms#else
68191665Sbms#define FILL(p)
69195699Srwatson#endif
70191665Sbms
71191665Sbms#ifdef USE_POLL
72191665Sbms#ifdef HAVE_STROPTS_H
73191665Sbms#include <stropts.h>
74191665Sbms#endif
75191665Sbms#include <poll.h>
76191665Sbms#endif /* USE_POLL */
77191665Sbms
78191665Sbmstypedef struct evConn {
79191665Sbms	evConnFunc	func;
80191665Sbms	void *		uap;
81191665Sbms	int		fd;
82191665Sbms	int		flags;
83191665Sbms#define EV_CONN_LISTEN		0x0001		/*%< Connection is a listener. */
84191665Sbms#define EV_CONN_SELECTED	0x0002		/*%< evSelectFD(conn->file). */
85191665Sbms#define EV_CONN_BLOCK		0x0004		/*%< Listener fd was blocking. */
86191665Sbms	evFileID	file;
87191665Sbms	struct evConn *	prev;
88191665Sbms	struct evConn *	next;
89191665Sbms} evConn;
90191665Sbms
91191665Sbmstypedef struct evAccept {
92191665Sbms	int		fd;
93191665Sbms	union {
94191665Sbms		struct sockaddr		sa;
95191665Sbms		struct sockaddr_in	in;
96191665Sbms#ifndef NO_SOCKADDR_UN
97191665Sbms		struct sockaddr_un	un;
98191665Sbms#endif
99191665Sbms	}		la;
100191665Sbms	ISC_SOCKLEN_T	lalen;
101191665Sbms	union {
102191665Sbms		struct sockaddr		sa;
103191665Sbms		struct sockaddr_in	in;
104191665Sbms#ifndef NO_SOCKADDR_UN
105191665Sbms		struct sockaddr_un	un;
106191665Sbms#endif
107191665Sbms	}		ra;
108191665Sbms	ISC_SOCKLEN_T	ralen;
109191665Sbms	int		ioErrno;
110191665Sbms	evConn *	conn;
111191665Sbms	LINK(struct evAccept) link;
112191665Sbms} evAccept;
113191665Sbms
114191665Sbmstypedef struct evFile {
115191665Sbms	evFileFunc	func;
116191665Sbms	void *		uap;
117191665Sbms	int		fd;
118191665Sbms	int		eventmask;
119191665Sbms	int		preemptive;
120191665Sbms	struct evFile *	prev;
121191665Sbms	struct evFile *	next;
122191665Sbms	struct evFile *	fdprev;
123191665Sbms	struct evFile *	fdnext;
124191665Sbms} evFile;
125191665Sbms
126191665Sbmstypedef struct evStream {
127191665Sbms	evStreamFunc	func;
128191665Sbms	void *		uap;
129191665Sbms	evFileID	file;
130191665Sbms	evTimerID	timer;
131191665Sbms	int		flags;
132191665Sbms#define EV_STR_TIMEROK	0x0001	/*%< IFF timer valid. */
133191665Sbms	int		fd;
134259983Sdim	struct iovec *	iovOrig;
135191665Sbms	int		iovOrigCount;
136259983Sdim	struct iovec *	iovCur;
137191665Sbms	int		iovCurCount;
138191665Sbms	int		ioTotal;
139191665Sbms	int		ioDone;
140191665Sbms	int		ioErrno;
141191665Sbms	struct evStream	*prevDone, *nextDone;
142191665Sbms	struct evStream	*prev, *next;
143191665Sbms} evStream;
144191665Sbms
145191672Sbmstypedef struct evTimer {
146191672Sbms	evTimerFunc	func;
147191672Sbms	void *		uap;
148191665Sbms	struct timespec	due, inter;
149191665Sbms	int		index;
150191665Sbms	int		mode;
151191665Sbms#define EV_TMR_RATE	1
152191665Sbms} evTimer;
153191665Sbms
154191665Sbmstypedef struct evWait {
155227309Sed	evWaitFunc	func;
156227309Sed	void *		uap;
157191665Sbms	const void *	tag;
158191665Sbms	struct evWait *	next;
159191665Sbms} evWait;
160191665Sbms
161191665Sbmstypedef struct evWaitList {
162191665Sbms	evWait *		first;
163191665Sbms	evWait *		last;
164191665Sbms	struct evWaitList *	prev;
165191665Sbms	struct evWaitList *	next;
166191665Sbms} evWaitList;
167191665Sbms
168191665Sbmstypedef struct evEvent_p {
169191665Sbms	enum {  Accept, File, Stream, Timer, Wait, Free, Null  } type;
170191665Sbms	union {
171191665Sbms		struct {  evAccept *this;  }			accept;
172191665Sbms		struct {  evFile *this; int eventmask;  }	file;
173191665Sbms		struct {  evStream *this;  }			stream;
174191665Sbms		struct {  evTimer *this;  }			timer;
175191665Sbms		struct {  evWait *this;  }			wait;
176227309Sed		struct {  struct evEvent_p *next;  }		free;
177191665Sbms		struct {  const void *placeholder;  }		null;
178191665Sbms	} u;
179191665Sbms} evEvent_p;
180259983Sdim
181191665Sbms#ifdef USE_POLL
182191665Sbmstypedef struct {
183191665Sbms	void		*ctx;	/* pointer to the evContext_p   */
184191665Sbms	uint32_t	type;	/* READ, WRITE, EXCEPT, nonblk  */
185191665Sbms	uint32_t	result;	/* 1 => revents, 0 => events    */
186191665Sbms} __evEmulMask;
187191665Sbms
188191665Sbms#define emulMaskInit(ctx, field, ev, lastnext) \
189191665Sbms	ctx->field.ctx = ctx; \
190191665Sbms	ctx->field.type = ev; \
191191665Sbms	ctx->field.result = lastnext;
192191665Sbms
193191665Sbmsextern short	*__fd_eventfield(int fd, __evEmulMask *maskp);
194191665Sbmsextern short	__poll_event(__evEmulMask *maskp);
195191665Sbmsextern void		__fd_clr(int fd, __evEmulMask *maskp);
196191665Sbmsextern void		__fd_set(int fd, __evEmulMask *maskp);
197191665Sbms
198191665Sbms#undef  FD_ZERO
199191665Sbms#define FD_ZERO(maskp)
200191665Sbms
201191665Sbms#undef  FD_SET
202191665Sbms#define FD_SET(fd, maskp) \
203259983Sdim	__fd_set(fd, maskp)
204191665Sbms
205191665Sbms#undef  FD_CLR
206191665Sbms#define FD_CLR(fd, maskp) \
207191665Sbms	__fd_clr(fd, maskp)
208191665Sbms
209191665Sbms#undef  FD_ISSET
210191665Sbms#define FD_ISSET(fd, maskp) \
211191665Sbms	((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0)
212191665Sbms
213191665Sbms#endif /* USE_POLL */
214191665Sbms
215191665Sbmstypedef struct {
216191665Sbms	/* Global. */
217191665Sbms	const evEvent_p	*cur;
218191665Sbms	/* Debugging. */
219191665Sbms	int		debug;
220191665Sbms	FILE		*output;
221191665Sbms	/* Connections. */
222191665Sbms	evConn		*conns;
223191665Sbms	LIST(evAccept)	accepts;
224191665Sbms	/* Files. */
225191665Sbms	evFile		*files, *fdNext;
226191665Sbms#ifndef USE_POLL
227191665Sbms	fd_set		rdLast, rdNext;
228191665Sbms	fd_set		wrLast, wrNext;
229191665Sbms	fd_set		exLast, exNext;
230191665Sbms	fd_set		nonblockBefore;
231191665Sbms	int		fdMax, fdCount, highestFD;
232191665Sbms	evFile		*fdTable[FD_SETSIZE];
233191665Sbms#else
234191665Sbms	struct pollfd	*pollfds;	/* Allocated as needed  */
235191665Sbms	evFile		**fdTable;	/* Ditto                */
236191665Sbms	int		maxnfds;	/* # elements in above  */
237191665Sbms	int		firstfd;	/* First active fd      */
238191665Sbms	int		fdMax;		/* Last active fd       */
239191665Sbms	int		fdCount;	/* # fd:s with I/O      */
240191665Sbms	int		highestFD;	/* max fd allowed by OS */
241191665Sbms	__evEmulMask	rdLast, rdNext;
242191665Sbms	__evEmulMask	wrLast, wrNext;
243191665Sbms	__evEmulMask	exLast, exNext;
244191665Sbms	__evEmulMask	nonblockBefore;
245191665Sbms#endif /* USE_POLL */
246191665Sbms#ifdef EVENTLIB_TIME_CHECKS
247191665Sbms	struct timespec	lastSelectTime;
248191665Sbms	int		lastFdCount;
249191665Sbms#endif
250191665Sbms	/* Streams. */
251191665Sbms	evStream	*streams;
252191665Sbms	evStream	*strDone, *strLast;
253191665Sbms	/* Timers. */
254191665Sbms	struct timespec	lastEventTime;
255191665Sbms	heap_context	timers;
256191665Sbms	/* Waits. */
257191665Sbms	evWaitList	*waitLists;
258191665Sbms	evWaitList	waitDone;
259191665Sbms} evContext_p;
260191665Sbms
261191665Sbms/* eventlib.c */
262191665Sbms#define evPrintf __evPrintf
263191665Sbmsvoid evPrintf(const evContext_p *ctx, int level, const char *fmt, ...)
264191665Sbms     ISC_FORMAT_PRINTF(3, 4);
265191665Sbms
266191665Sbms#ifdef USE_POLL
267191665Sbmsextern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd);
268191665Sbms#endif /* USE_POLL */
269191665Sbms
270191665Sbms/* ev_timers.c */
271191665Sbms#define evCreateTimers __evCreateTimers
272191665Sbmsheap_context evCreateTimers(const evContext_p *);
273191665Sbms#define evDestroyTimers __evDestroyTimers
274191665Sbmsvoid evDestroyTimers(const evContext_p *);
275191665Sbms
276191665Sbms/* ev_waits.c */
277191665Sbms#define evFreeWait __evFreeWait
278191665SbmsevWait *evFreeWait(evContext_p *ctx, evWait *old);
279191665Sbms
280191665Sbms/* Global options */
281191665Sbmsextern int	__evOptMonoTime;
282191665Sbms
283191665Sbms#endif /*_EVENTLIB_P_H*/
284191665Sbms