1156952Sume/*
2156952Sume * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
3156952Sume * Copyright (c) 1995-1999 by Internet Software Consortium
4156952Sume *
5156952Sume * Permission to use, copy, modify, and distribute this software for any
6156952Sume * purpose with or without fee is hereby granted, provided that the above
7156952Sume * copyright notice and this permission notice appear in all copies.
8156952Sume *
9156952Sume * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
10156952Sume * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11156952Sume * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
12156952Sume * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13156952Sume * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14156952Sume * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
15156952Sume * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16156952Sume */
17156952Sume
18170244Sume/*! \file
19170244Sume * \brief private interfaces for eventlib
20170244Sume * \author vix 09sep95 [initial]
21156952Sume *
22270838Sume * $Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp $
23156956Sume * $FreeBSD$
24156952Sume */
25156952Sume
26156952Sume#ifndef _EVENTLIB_P_H
27156952Sume#define _EVENTLIB_P_H
28156952Sume
29156952Sume#include <sys/param.h>
30156952Sume#include <sys/types.h>
31156952Sume#include <sys/socket.h>
32156952Sume#include <netinet/in.h>
33156952Sume#include <sys/un.h>
34156952Sume
35156952Sume#define EVENTLIB_DEBUG 1
36156952Sume
37156952Sume#include <errno.h>
38156952Sume#include <fcntl.h>
39156952Sume#include <stdio.h>
40156952Sume#include <stdlib.h>
41156952Sume#include <string.h>
42156952Sume
43156956Sume#ifndef _LIBC
44156956Sume#include <isc/list.h>
45156952Sume#include <isc/heap.h>
46156952Sume#include <isc/memcluster.h>
47156956Sume#endif
48156952Sume
49156952Sume#define	EV_MASK_ALL	(EV_READ | EV_WRITE | EV_EXCEPT)
50156952Sume#define EV_ERR(e)		return (errno = (e), -1)
51156952Sume#define OK(x)		if ((x) < 0) EV_ERR(errno); else (void)NULL
52165258Sume#define OKFREE(x, y)	if ((x) < 0) { FREE((y)); EV_ERR(errno); } \
53165258Sume			else (void)NULL
54156952Sume
55156952Sume#define	NEW(p)		if (((p) = memget(sizeof *(p))) != NULL) \
56156952Sume				FILL(p); \
57156952Sume			else \
58156952Sume				(void)NULL;
59156952Sume#define OKNEW(p)	if (!((p) = memget(sizeof *(p)))) { \
60156952Sume				errno = ENOMEM; \
61156952Sume				return (-1); \
62156952Sume			} else \
63156952Sume				FILL(p)
64156952Sume#define FREE(p)		memput((p), sizeof *(p))
65156952Sume
66156952Sume#if EVENTLIB_DEBUG
67156952Sume#define FILL(p)		memset((p), 0xF5, sizeof *(p))
68156952Sume#else
69156952Sume#define FILL(p)
70156952Sume#endif
71156952Sume
72156952Sume#ifdef USE_POLL
73156952Sume#ifdef HAVE_STROPTS_H
74156952Sume#include <stropts.h>
75156952Sume#endif
76156952Sume#include <poll.h>
77156952Sume#endif /* USE_POLL */
78156952Sume
79156952Sumetypedef struct evConn {
80156952Sume	evConnFunc	func;
81156952Sume	void *		uap;
82156952Sume	int		fd;
83156952Sume	int		flags;
84170244Sume#define EV_CONN_LISTEN		0x0001		/*%< Connection is a listener. */
85170244Sume#define EV_CONN_SELECTED	0x0002		/*%< evSelectFD(conn->file). */
86170244Sume#define EV_CONN_BLOCK		0x0004		/*%< Listener fd was blocking. */
87156952Sume	evFileID	file;
88156952Sume	struct evConn *	prev;
89156952Sume	struct evConn *	next;
90156952Sume} evConn;
91156952Sume
92156956Sume#ifndef _LIBC
93156952Sumetypedef struct evAccept {
94156952Sume	int		fd;
95156952Sume	union {
96156952Sume		struct sockaddr		sa;
97156952Sume		struct sockaddr_in	in;
98156952Sume#ifndef NO_SOCKADDR_UN
99156952Sume		struct sockaddr_un	un;
100156952Sume#endif
101156952Sume	}		la;
102156952Sume	ISC_SOCKLEN_T	lalen;
103156952Sume	union {
104156952Sume		struct sockaddr		sa;
105156952Sume		struct sockaddr_in	in;
106156952Sume#ifndef NO_SOCKADDR_UN
107156952Sume		struct sockaddr_un	un;
108156952Sume#endif
109156952Sume	}		ra;
110156952Sume	ISC_SOCKLEN_T	ralen;
111156952Sume	int		ioErrno;
112156952Sume	evConn *	conn;
113156952Sume	LINK(struct evAccept) link;
114156952Sume} evAccept;
115156952Sume
116156952Sumetypedef struct evFile {
117156952Sume	evFileFunc	func;
118156952Sume	void *		uap;
119156952Sume	int		fd;
120156952Sume	int		eventmask;
121156952Sume	int		preemptive;
122156952Sume	struct evFile *	prev;
123156952Sume	struct evFile *	next;
124156952Sume	struct evFile *	fdprev;
125156952Sume	struct evFile *	fdnext;
126156952Sume} evFile;
127156952Sume
128156952Sumetypedef struct evStream {
129156952Sume	evStreamFunc	func;
130156952Sume	void *		uap;
131156952Sume	evFileID	file;
132156952Sume	evTimerID	timer;
133156952Sume	int		flags;
134170244Sume#define EV_STR_TIMEROK	0x0001	/*%< IFF timer valid. */
135156952Sume	int		fd;
136156952Sume	struct iovec *	iovOrig;
137156952Sume	int		iovOrigCount;
138156952Sume	struct iovec *	iovCur;
139156952Sume	int		iovCurCount;
140156952Sume	int		ioTotal;
141156952Sume	int		ioDone;
142156952Sume	int		ioErrno;
143156952Sume	struct evStream	*prevDone, *nextDone;
144156952Sume	struct evStream	*prev, *next;
145156952Sume} evStream;
146156952Sume
147156952Sumetypedef struct evTimer {
148156952Sume	evTimerFunc	func;
149156952Sume	void *		uap;
150156952Sume	struct timespec	due, inter;
151156952Sume	int		index;
152156952Sume	int		mode;
153156952Sume#define EV_TMR_RATE	1
154156952Sume} evTimer;
155156952Sume
156156952Sumetypedef struct evWait {
157156952Sume	evWaitFunc	func;
158156952Sume	void *		uap;
159156952Sume	const void *	tag;
160156952Sume	struct evWait *	next;
161156952Sume} evWait;
162156952Sume
163156952Sumetypedef struct evWaitList {
164156952Sume	evWait *		first;
165156952Sume	evWait *		last;
166156952Sume	struct evWaitList *	prev;
167156952Sume	struct evWaitList *	next;
168156952Sume} evWaitList;
169156952Sume
170156952Sumetypedef struct evEvent_p {
171156952Sume	enum {  Accept, File, Stream, Timer, Wait, Free, Null  } type;
172156952Sume	union {
173156952Sume		struct {  evAccept *this;  }			accept;
174156952Sume		struct {  evFile *this; int eventmask;  }	file;
175156952Sume		struct {  evStream *this;  }			stream;
176156952Sume		struct {  evTimer *this;  }			timer;
177156952Sume		struct {  evWait *this;  }			wait;
178156952Sume		struct {  struct evEvent_p *next;  }		free;
179156952Sume		struct {  const void *placeholder;  }		null;
180156952Sume	} u;
181156952Sume} evEvent_p;
182156956Sume#endif
183156952Sume
184156952Sume#ifdef USE_POLL
185156952Sumetypedef struct {
186156952Sume	void		*ctx;	/* pointer to the evContext_p   */
187156952Sume	uint32_t	type;	/* READ, WRITE, EXCEPT, nonblk  */
188156952Sume	uint32_t	result;	/* 1 => revents, 0 => events    */
189156952Sume} __evEmulMask;
190156952Sume
191156952Sume#define emulMaskInit(ctx, field, ev, lastnext) \
192156952Sume	ctx->field.ctx = ctx; \
193156952Sume	ctx->field.type = ev; \
194156952Sume	ctx->field.result = lastnext;
195156952Sume
196156952Sumeextern short	*__fd_eventfield(int fd, __evEmulMask *maskp);
197156952Sumeextern short	__poll_event(__evEmulMask *maskp);
198156952Sumeextern void		__fd_clr(int fd, __evEmulMask *maskp);
199156952Sumeextern void		__fd_set(int fd, __evEmulMask *maskp);
200156952Sume
201156952Sume#undef  FD_ZERO
202156952Sume#define FD_ZERO(maskp)
203156952Sume
204156952Sume#undef  FD_SET
205156952Sume#define FD_SET(fd, maskp) \
206156952Sume	__fd_set(fd, maskp)
207156952Sume
208156952Sume#undef  FD_CLR
209156952Sume#define FD_CLR(fd, maskp) \
210156952Sume	__fd_clr(fd, maskp)
211156952Sume
212156952Sume#undef  FD_ISSET
213156952Sume#define FD_ISSET(fd, maskp) \
214156952Sume	((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0)
215156952Sume
216156952Sume#endif /* USE_POLL */
217156952Sume
218156956Sume#ifndef _LIBC
219156952Sumetypedef struct {
220156952Sume	/* Global. */
221156952Sume	const evEvent_p	*cur;
222156952Sume	/* Debugging. */
223156952Sume	int		debug;
224156952Sume	FILE		*output;
225156952Sume	/* Connections. */
226156952Sume	evConn		*conns;
227156952Sume	LIST(evAccept)	accepts;
228156952Sume	/* Files. */
229156952Sume	evFile		*files, *fdNext;
230156952Sume#ifndef USE_POLL
231156952Sume	fd_set		rdLast, rdNext;
232156952Sume	fd_set		wrLast, wrNext;
233156952Sume	fd_set		exLast, exNext;
234156952Sume	fd_set		nonblockBefore;
235156952Sume	int		fdMax, fdCount, highestFD;
236156952Sume	evFile		*fdTable[FD_SETSIZE];
237156952Sume#else
238156952Sume	struct pollfd	*pollfds;	/* Allocated as needed  */
239156952Sume	evFile		**fdTable;	/* Ditto                */
240156952Sume	int		maxnfds;	/* # elements in above  */
241156952Sume	int		firstfd;	/* First active fd      */
242156952Sume	int		fdMax;		/* Last active fd       */
243156952Sume	int		fdCount;	/* # fd:s with I/O      */
244156952Sume	int		highestFD;	/* max fd allowed by OS */
245156952Sume	__evEmulMask	rdLast, rdNext;
246156952Sume	__evEmulMask	wrLast, wrNext;
247156952Sume	__evEmulMask	exLast, exNext;
248156952Sume	__evEmulMask	nonblockBefore;
249156952Sume#endif /* USE_POLL */
250156952Sume#ifdef EVENTLIB_TIME_CHECKS
251156952Sume	struct timespec	lastSelectTime;
252156952Sume	int		lastFdCount;
253156952Sume#endif
254156952Sume	/* Streams. */
255156952Sume	evStream	*streams;
256156952Sume	evStream	*strDone, *strLast;
257156952Sume	/* Timers. */
258156952Sume	struct timespec	lastEventTime;
259156952Sume	heap_context	timers;
260156952Sume	/* Waits. */
261156952Sume	evWaitList	*waitLists;
262156952Sume	evWaitList	waitDone;
263156952Sume} evContext_p;
264156952Sume
265156952Sume/* eventlib.c */
266156952Sume#define evPrintf __evPrintf
267156952Sumevoid evPrintf(const evContext_p *ctx, int level, const char *fmt, ...)
268156952Sume     ISC_FORMAT_PRINTF(3, 4);
269156952Sume
270156952Sume#ifdef USE_POLL
271156952Sumeextern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd);
272156952Sume#endif /* USE_POLL */
273156952Sume
274156952Sume/* ev_timers.c */
275156952Sume#define evCreateTimers __evCreateTimers
276156952Sumeheap_context evCreateTimers(const evContext_p *);
277156952Sume#define evDestroyTimers __evDestroyTimers
278156952Sumevoid evDestroyTimers(const evContext_p *);
279156952Sume
280156952Sume/* ev_waits.c */
281156952Sume#define evFreeWait __evFreeWait
282156952SumeevWait *evFreeWait(evContext_p *ctx, evWait *old);
283156956Sume#endif
284156952Sume
285156952Sume/* Global options */
286162541Skan#ifndef _LIBC
287156952Sumeextern int	__evOptMonoTime;
288162541Skan#endif
289156952Sume
290156952Sume#endif /*_EVENTLIB_P_H*/
291