17c478bd9Sstevel@tonic-gate /*
29525b14bSRao Shoaib  * Copyright (c) 2005 by Internet Systems Consortium, Inc. ("ISC")
37c478bd9Sstevel@tonic-gate  * Copyright (c) 1995-1999 by Internet Software Consortium
47c478bd9Sstevel@tonic-gate  *
57c478bd9Sstevel@tonic-gate  * Permission to use, copy, modify, and distribute this software for any
67c478bd9Sstevel@tonic-gate  * purpose with or without fee is hereby granted, provided that the above
77c478bd9Sstevel@tonic-gate  * copyright notice and this permission notice appear in all copies.
87c478bd9Sstevel@tonic-gate  *
99525b14bSRao Shoaib  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
109525b14bSRao Shoaib  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
119525b14bSRao Shoaib  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
129525b14bSRao Shoaib  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
139525b14bSRao Shoaib  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
149525b14bSRao Shoaib  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
159525b14bSRao Shoaib  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
167c478bd9Sstevel@tonic-gate  */
177c478bd9Sstevel@tonic-gate 
18*55fea89dSDan Cross /*! \file
199525b14bSRao Shoaib  * \brief private interfaces for eventlib
209525b14bSRao Shoaib  * \author vix 09sep95 [initial]
217c478bd9Sstevel@tonic-gate  *
229525b14bSRao Shoaib  * $Id: eventlib_p.h,v 1.9 2006/03/09 23:57:56 marka Exp $
237c478bd9Sstevel@tonic-gate  */
247c478bd9Sstevel@tonic-gate 
257c478bd9Sstevel@tonic-gate #ifndef _EVENTLIB_P_H
267c478bd9Sstevel@tonic-gate #define _EVENTLIB_P_H
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate #include <sys/param.h>
297c478bd9Sstevel@tonic-gate #include <sys/types.h>
307c478bd9Sstevel@tonic-gate #include <sys/socket.h>
317c478bd9Sstevel@tonic-gate #include <netinet/in.h>
327c478bd9Sstevel@tonic-gate #include <sys/un.h>
337c478bd9Sstevel@tonic-gate 
347c478bd9Sstevel@tonic-gate #define EVENTLIB_DEBUG 1
357c478bd9Sstevel@tonic-gate 
367c478bd9Sstevel@tonic-gate #include <errno.h>
377c478bd9Sstevel@tonic-gate #include <fcntl.h>
387c478bd9Sstevel@tonic-gate #include <stdio.h>
397c478bd9Sstevel@tonic-gate #include <stdlib.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate 
427c478bd9Sstevel@tonic-gate #include <isc/heap.h>
437c478bd9Sstevel@tonic-gate #include <isc/list.h>
447c478bd9Sstevel@tonic-gate #include <isc/memcluster.h>
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate #define	EV_MASK_ALL	(EV_READ | EV_WRITE | EV_EXCEPT)
477c478bd9Sstevel@tonic-gate #define EV_ERR(e)		return (errno = (e), -1)
487c478bd9Sstevel@tonic-gate #define OK(x)		if ((x) < 0) EV_ERR(errno); else (void)NULL
499525b14bSRao Shoaib #define OKFREE(x, y)	if ((x) < 0) { FREE((y)); EV_ERR(errno); } \
509525b14bSRao Shoaib 			else (void)NULL
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #define	NEW(p)		if (((p) = memget(sizeof *(p))) != NULL) \
537c478bd9Sstevel@tonic-gate 				FILL(p); \
547c478bd9Sstevel@tonic-gate 			else \
557c478bd9Sstevel@tonic-gate 				(void)NULL;
567c478bd9Sstevel@tonic-gate #define OKNEW(p)	if (!((p) = memget(sizeof *(p)))) { \
577c478bd9Sstevel@tonic-gate 				errno = ENOMEM; \
587c478bd9Sstevel@tonic-gate 				return (-1); \
597c478bd9Sstevel@tonic-gate 			} else \
607c478bd9Sstevel@tonic-gate 				FILL(p)
617c478bd9Sstevel@tonic-gate #define FREE(p)		memput((p), sizeof *(p))
627c478bd9Sstevel@tonic-gate 
637c478bd9Sstevel@tonic-gate #if EVENTLIB_DEBUG
647c478bd9Sstevel@tonic-gate #define FILL(p)		memset((p), 0xF5, sizeof *(p))
657c478bd9Sstevel@tonic-gate #else
667c478bd9Sstevel@tonic-gate #define FILL(p)
677c478bd9Sstevel@tonic-gate #endif
687c478bd9Sstevel@tonic-gate 
699525b14bSRao Shoaib #ifdef USE_POLL
709525b14bSRao Shoaib #ifdef HAVE_STROPTS_H
717c478bd9Sstevel@tonic-gate #include <stropts.h>
727c478bd9Sstevel@tonic-gate #endif
739525b14bSRao Shoaib #include <poll.h>
749525b14bSRao Shoaib #endif /* USE_POLL */
757c478bd9Sstevel@tonic-gate 
767c478bd9Sstevel@tonic-gate typedef struct evConn {
777c478bd9Sstevel@tonic-gate 	evConnFunc	func;
787c478bd9Sstevel@tonic-gate 	void *		uap;
797c478bd9Sstevel@tonic-gate 	int		fd;
807c478bd9Sstevel@tonic-gate 	int		flags;
819525b14bSRao Shoaib #define EV_CONN_LISTEN		0x0001		/*%< Connection is a listener. */
829525b14bSRao Shoaib #define EV_CONN_SELECTED	0x0002		/*%< evSelectFD(conn->file). */
839525b14bSRao Shoaib #define EV_CONN_BLOCK		0x0004		/*%< Listener fd was blocking. */
847c478bd9Sstevel@tonic-gate 	evFileID	file;
857c478bd9Sstevel@tonic-gate 	struct evConn *	prev;
867c478bd9Sstevel@tonic-gate 	struct evConn *	next;
877c478bd9Sstevel@tonic-gate } evConn;
887c478bd9Sstevel@tonic-gate 
897c478bd9Sstevel@tonic-gate typedef struct evAccept {
907c478bd9Sstevel@tonic-gate 	int		fd;
917c478bd9Sstevel@tonic-gate 	union {
927c478bd9Sstevel@tonic-gate 		struct sockaddr		sa;
937c478bd9Sstevel@tonic-gate 		struct sockaddr_in	in;
947c478bd9Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN
957c478bd9Sstevel@tonic-gate 		struct sockaddr_un	un;
967c478bd9Sstevel@tonic-gate #endif
977c478bd9Sstevel@tonic-gate 	}		la;
987c478bd9Sstevel@tonic-gate 	ISC_SOCKLEN_T	lalen;
997c478bd9Sstevel@tonic-gate 	union {
1007c478bd9Sstevel@tonic-gate 		struct sockaddr		sa;
1017c478bd9Sstevel@tonic-gate 		struct sockaddr_in	in;
1027c478bd9Sstevel@tonic-gate #ifndef NO_SOCKADDR_UN
1037c478bd9Sstevel@tonic-gate 		struct sockaddr_un	un;
1047c478bd9Sstevel@tonic-gate #endif
1057c478bd9Sstevel@tonic-gate 	}		ra;
1067c478bd9Sstevel@tonic-gate 	ISC_SOCKLEN_T	ralen;
1077c478bd9Sstevel@tonic-gate 	int		ioErrno;
1087c478bd9Sstevel@tonic-gate 	evConn *	conn;
1097c478bd9Sstevel@tonic-gate 	LINK(struct evAccept) link;
1107c478bd9Sstevel@tonic-gate } evAccept;
1117c478bd9Sstevel@tonic-gate 
1127c478bd9Sstevel@tonic-gate typedef struct evFile {
1137c478bd9Sstevel@tonic-gate 	evFileFunc	func;
1147c478bd9Sstevel@tonic-gate 	void *		uap;
1157c478bd9Sstevel@tonic-gate 	int		fd;
1167c478bd9Sstevel@tonic-gate 	int		eventmask;
1177c478bd9Sstevel@tonic-gate 	int		preemptive;
1187c478bd9Sstevel@tonic-gate 	struct evFile *	prev;
1197c478bd9Sstevel@tonic-gate 	struct evFile *	next;
1207c478bd9Sstevel@tonic-gate 	struct evFile *	fdprev;
1217c478bd9Sstevel@tonic-gate 	struct evFile *	fdnext;
1227c478bd9Sstevel@tonic-gate } evFile;
1237c478bd9Sstevel@tonic-gate 
1247c478bd9Sstevel@tonic-gate typedef struct evStream {
1257c478bd9Sstevel@tonic-gate 	evStreamFunc	func;
1267c478bd9Sstevel@tonic-gate 	void *		uap;
1277c478bd9Sstevel@tonic-gate 	evFileID	file;
1287c478bd9Sstevel@tonic-gate 	evTimerID	timer;
1297c478bd9Sstevel@tonic-gate 	int		flags;
1309525b14bSRao Shoaib #define EV_STR_TIMEROK	0x0001	/*%< IFF timer valid. */
1317c478bd9Sstevel@tonic-gate 	int		fd;
1327c478bd9Sstevel@tonic-gate 	struct iovec *	iovOrig;
1337c478bd9Sstevel@tonic-gate 	int		iovOrigCount;
1347c478bd9Sstevel@tonic-gate 	struct iovec *	iovCur;
1357c478bd9Sstevel@tonic-gate 	int		iovCurCount;
1367c478bd9Sstevel@tonic-gate 	int		ioTotal;
1377c478bd9Sstevel@tonic-gate 	int		ioDone;
1387c478bd9Sstevel@tonic-gate 	int		ioErrno;
1397c478bd9Sstevel@tonic-gate 	struct evStream	*prevDone, *nextDone;
1407c478bd9Sstevel@tonic-gate 	struct evStream	*prev, *next;
1417c478bd9Sstevel@tonic-gate } evStream;
1427c478bd9Sstevel@tonic-gate 
1437c478bd9Sstevel@tonic-gate typedef struct evTimer {
1447c478bd9Sstevel@tonic-gate 	evTimerFunc	func;
1457c478bd9Sstevel@tonic-gate 	void *		uap;
1467c478bd9Sstevel@tonic-gate 	struct timespec	due, inter;
1477c478bd9Sstevel@tonic-gate 	int		index;
1489525b14bSRao Shoaib 	int		mode;
1499525b14bSRao Shoaib #define EV_TMR_RATE	1
1507c478bd9Sstevel@tonic-gate } evTimer;
1517c478bd9Sstevel@tonic-gate 
1527c478bd9Sstevel@tonic-gate typedef struct evWait {
1537c478bd9Sstevel@tonic-gate 	evWaitFunc	func;
1547c478bd9Sstevel@tonic-gate 	void *		uap;
1557c478bd9Sstevel@tonic-gate 	const void *	tag;
1567c478bd9Sstevel@tonic-gate 	struct evWait *	next;
1577c478bd9Sstevel@tonic-gate } evWait;
1587c478bd9Sstevel@tonic-gate 
1597c478bd9Sstevel@tonic-gate typedef struct evWaitList {
1607c478bd9Sstevel@tonic-gate 	evWait *		first;
1617c478bd9Sstevel@tonic-gate 	evWait *		last;
1627c478bd9Sstevel@tonic-gate 	struct evWaitList *	prev;
1637c478bd9Sstevel@tonic-gate 	struct evWaitList *	next;
1647c478bd9Sstevel@tonic-gate } evWaitList;
1657c478bd9Sstevel@tonic-gate 
1667c478bd9Sstevel@tonic-gate typedef struct evEvent_p {
1677c478bd9Sstevel@tonic-gate 	enum {  Accept, File, Stream, Timer, Wait, Free, Null  } type;
1687c478bd9Sstevel@tonic-gate 	union {
1697c478bd9Sstevel@tonic-gate 		struct {  evAccept *this;  }			accept;
1707c478bd9Sstevel@tonic-gate 		struct {  evFile *this; int eventmask;  }	file;
1717c478bd9Sstevel@tonic-gate 		struct {  evStream *this;  }			stream;
1727c478bd9Sstevel@tonic-gate 		struct {  evTimer *this;  }			timer;
1737c478bd9Sstevel@tonic-gate 		struct {  evWait *this;  }			wait;
1747c478bd9Sstevel@tonic-gate 		struct {  struct evEvent_p *next;  }		free;
1757c478bd9Sstevel@tonic-gate 		struct {  const void *placeholder;  }		null;
1767c478bd9Sstevel@tonic-gate 	} u;
1777c478bd9Sstevel@tonic-gate } evEvent_p;
1787c478bd9Sstevel@tonic-gate 
1799525b14bSRao Shoaib #ifdef USE_POLL
180*55fea89dSDan Cross typedef struct {
181*55fea89dSDan Cross 	void		*ctx;	/* pointer to the evContext_p   */
182*55fea89dSDan Cross 	uint32_t	type;	/* READ, WRITE, EXCEPT, nonblk  */
183*55fea89dSDan Cross 	uint32_t	result;	/* 1 => revents, 0 => events    */
184*55fea89dSDan Cross } __evEmulMask;
1857c478bd9Sstevel@tonic-gate 
1869525b14bSRao Shoaib #define emulMaskInit(ctx, field, ev, lastnext) \
1877c478bd9Sstevel@tonic-gate 	ctx->field.ctx = ctx; \
1887c478bd9Sstevel@tonic-gate 	ctx->field.type = ev; \
189*55fea89dSDan Cross 	ctx->field.result = lastnext;
190*55fea89dSDan Cross 
191*55fea89dSDan Cross extern short	*__fd_eventfield(int fd, __evEmulMask *maskp);
192*55fea89dSDan Cross extern short	__poll_event(__evEmulMask *maskp);
193*55fea89dSDan Cross extern void		__fd_clr(int fd, __evEmulMask *maskp);
194*55fea89dSDan Cross extern void		__fd_set(int fd, __evEmulMask *maskp);
195*55fea89dSDan Cross 
196*55fea89dSDan Cross #undef  FD_ZERO
197*55fea89dSDan Cross #define FD_ZERO(maskp)
198*55fea89dSDan Cross 
199*55fea89dSDan Cross #undef  FD_SET
2009525b14bSRao Shoaib #define FD_SET(fd, maskp) \
201*55fea89dSDan Cross 	__fd_set(fd, maskp)
2029525b14bSRao Shoaib 
203*55fea89dSDan Cross #undef  FD_CLR
2049525b14bSRao Shoaib #define FD_CLR(fd, maskp) \
205*55fea89dSDan Cross 	__fd_clr(fd, maskp)
2069525b14bSRao Shoaib 
207*55fea89dSDan Cross #undef  FD_ISSET
2089525b14bSRao Shoaib #define FD_ISSET(fd, maskp) \
209*55fea89dSDan Cross 	((*__fd_eventfield(fd, maskp) & __poll_event(maskp)) != 0)
2109525b14bSRao Shoaib 
2119525b14bSRao Shoaib #endif /* USE_POLL */
2127c478bd9Sstevel@tonic-gate 
2137c478bd9Sstevel@tonic-gate typedef struct {
2147c478bd9Sstevel@tonic-gate 	/* Global. */
2157c478bd9Sstevel@tonic-gate 	const evEvent_p	*cur;
2167c478bd9Sstevel@tonic-gate 	/* Debugging. */
2177c478bd9Sstevel@tonic-gate 	int		debug;
2187c478bd9Sstevel@tonic-gate 	FILE		*output;
2197c478bd9Sstevel@tonic-gate 	/* Connections. */
2207c478bd9Sstevel@tonic-gate 	evConn		*conns;
2217c478bd9Sstevel@tonic-gate 	LIST(evAccept)	accepts;
2227c478bd9Sstevel@tonic-gate 	/* Files. */
2237c478bd9Sstevel@tonic-gate 	evFile		*files, *fdNext;
2249525b14bSRao Shoaib #ifndef USE_POLL
2257c478bd9Sstevel@tonic-gate 	fd_set		rdLast, rdNext;
2267c478bd9Sstevel@tonic-gate 	fd_set		wrLast, wrNext;
2277c478bd9Sstevel@tonic-gate 	fd_set		exLast, exNext;
2287c478bd9Sstevel@tonic-gate 	fd_set		nonblockBefore;
2297c478bd9Sstevel@tonic-gate 	int		fdMax, fdCount, highestFD;
2307c478bd9Sstevel@tonic-gate 	evFile		*fdTable[FD_SETSIZE];
2319525b14bSRao Shoaib #else
232*55fea89dSDan Cross 	struct pollfd	*pollfds;	/* Allocated as needed  */
233*55fea89dSDan Cross 	evFile		**fdTable;	/* Ditto                */
234*55fea89dSDan Cross 	int		maxnfds;	/* # elements in above  */
235*55fea89dSDan Cross 	int		firstfd;	/* First active fd      */
236*55fea89dSDan Cross 	int		fdMax;		/* Last active fd       */
237*55fea89dSDan Cross 	int		fdCount;	/* # fd:s with I/O      */
238*55fea89dSDan Cross 	int		highestFD;	/* max fd allowed by OS */
239*55fea89dSDan Cross 	__evEmulMask	rdLast, rdNext;
240*55fea89dSDan Cross 	__evEmulMask	wrLast, wrNext;
241*55fea89dSDan Cross 	__evEmulMask	exLast, exNext;
242*55fea89dSDan Cross 	__evEmulMask	nonblockBefore;
2439525b14bSRao Shoaib #endif /* USE_POLL */
2447c478bd9Sstevel@tonic-gate #ifdef EVENTLIB_TIME_CHECKS
2457c478bd9Sstevel@tonic-gate 	struct timespec	lastSelectTime;
2467c478bd9Sstevel@tonic-gate 	int		lastFdCount;
2477c478bd9Sstevel@tonic-gate #endif
2487c478bd9Sstevel@tonic-gate 	/* Streams. */
2497c478bd9Sstevel@tonic-gate 	evStream	*streams;
2507c478bd9Sstevel@tonic-gate 	evStream	*strDone, *strLast;
2517c478bd9Sstevel@tonic-gate 	/* Timers. */
2527c478bd9Sstevel@tonic-gate 	struct timespec	lastEventTime;
2537c478bd9Sstevel@tonic-gate 	heap_context	timers;
2547c478bd9Sstevel@tonic-gate 	/* Waits. */
2557c478bd9Sstevel@tonic-gate 	evWaitList	*waitLists;
2567c478bd9Sstevel@tonic-gate 	evWaitList	waitDone;
2577c478bd9Sstevel@tonic-gate } evContext_p;
2587c478bd9Sstevel@tonic-gate 
2597c478bd9Sstevel@tonic-gate /* eventlib.c */
2607c478bd9Sstevel@tonic-gate #define evPrintf __evPrintf
2617c478bd9Sstevel@tonic-gate void evPrintf(const evContext_p *ctx, int level, const char *fmt, ...)
2627c478bd9Sstevel@tonic-gate      ISC_FORMAT_PRINTF(3, 4);
2637c478bd9Sstevel@tonic-gate 
2649525b14bSRao Shoaib #ifdef USE_POLL
2659525b14bSRao Shoaib extern int evPollfdRealloc(evContext_p *ctx, int pollfd_chunk_size, int fd);
2669525b14bSRao Shoaib #endif /* USE_POLL */
2677c478bd9Sstevel@tonic-gate 
2687c478bd9Sstevel@tonic-gate /* ev_timers.c */
2697c478bd9Sstevel@tonic-gate #define evCreateTimers __evCreateTimers
2707c478bd9Sstevel@tonic-gate heap_context evCreateTimers(const evContext_p *);
2717c478bd9Sstevel@tonic-gate #define evDestroyTimers __evDestroyTimers
2727c478bd9Sstevel@tonic-gate void evDestroyTimers(const evContext_p *);
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate /* ev_waits.c */
2757c478bd9Sstevel@tonic-gate #define evFreeWait __evFreeWait
2767c478bd9Sstevel@tonic-gate evWait *evFreeWait(evContext_p *ctx, evWait *old);
2777c478bd9Sstevel@tonic-gate 
2789525b14bSRao Shoaib /* Global options */
2799525b14bSRao Shoaib extern int	__evOptMonoTime;
2809525b14bSRao Shoaib 
2817c478bd9Sstevel@tonic-gate #endif /*_EVENTLIB_P_H*/
282