1ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes/*	$NetBSD: ev_timers.c,v 1.11 2012/03/21 00:34:54 christos Exp $	*/
21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/*
41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1995-1999 by Internet Software Consortium
61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Permission to use, copy, modify, and distribute this software for any
81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * purpose with or without fee is hereby granted, provided that the above
91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * copyright notice and this permission notice appear in all copies.
101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project *
111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* ev_timers.c - implement timers for the eventlib
211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * vix 09sep95 [initial]
221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */
231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h>
251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#if !defined(LINT) && !defined(CODECENTER) && !defined(lint)
261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef notdef
27ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughesstatic const char rcsid[] = "Id: ev_timers.c,v 1.6 2005/04/27 04:56:36 sra Exp";
281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
29ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes__RCSID("$NetBSD: ev_timers.c,v 1.11 2012/03/21 00:34:54 christos Exp $");
301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Import. */
341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
35ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes#include "port_before.h"
36ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes#include "fd_setsize.h"
37ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes
381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <errno.h>
391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <isc/assertions.h>
411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <isc/eventlib.h>
421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "eventlib_p.h"
431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
44ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes#include "port_after.h"
45ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes
461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Constants. */
471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define	MILLION 1000000
491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define BILLION 1000000000
501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Forward. */
521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef _LIBC
541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int due_sooner(void *, void *);
551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void set_index(void *, int);
561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void free_timer(void *, void *);
571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void print_timer(void *, void *);
581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void idle_timeout(evContext, void *, struct timespec, struct timespec);
591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Private type. */
611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projecttypedef struct {
631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimerFunc	func;
641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	void *		uap;
651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec	lastTouched;
661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec	max_idle;
671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *	timer;
681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} idle_timer;
691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Public. */
721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct timespec
741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevConsTime(time_t sec, long nsec) {
751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec x;
761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x.tv_sec = sec;
781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x.tv_nsec = nsec;
791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (x);
801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct timespec
831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevAddTime(struct timespec addend1, struct timespec addend2) {
841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec x;
851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x.tv_sec = addend1.tv_sec + addend2.tv_sec;
871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x.tv_nsec = addend1.tv_nsec + addend2.tv_nsec;
881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (x.tv_nsec >= BILLION) {
891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x.tv_sec++;
901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x.tv_nsec -= BILLION;
911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (x);
931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct timespec
961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevSubTime(struct timespec minuend, struct timespec subtrahend) {
971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec x;
981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	x.tv_sec = minuend.tv_sec - subtrahend.tv_sec;
1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (minuend.tv_nsec >= subtrahend.tv_nsec)
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x.tv_nsec = minuend.tv_nsec - subtrahend.tv_nsec;
1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else {
1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x.tv_nsec = BILLION - subtrahend.tv_nsec + minuend.tv_nsec;
1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		x.tv_sec--;
1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (x);
1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevCmpTime(struct timespec a, struct timespec b) {
111ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes#define SGN(x) ((x) < 0 ? (-1) : (x) > 0 ? (1) : (0));
112ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes	time_t s = a.tv_sec - b.tv_sec;
113ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes	long n;
114ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes
115ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes	if (s != 0)
116ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes		return SGN(s);
1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
118ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes	n = a.tv_nsec - b.tv_nsec;
119ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes	return SGN(n);
1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct timespec
123ab44f52202878cdf2bf22457aeae33ec24089556Elliott HughesevNowTime(void)
124ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes{
1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timeval now;
1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef CLOCK_REALTIME
1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec tsnow;
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int m = CLOCK_REALTIME;
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef CLOCK_MONOTONIC
131ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes#ifndef _LIBC
1321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (__evOptMonoTime)
1331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		m = CLOCK_MONOTONIC;
1341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
135ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes#endif
1361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (clock_gettime(m, &tsnow) == 0)
1371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (tsnow);
1381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (gettimeofday(&now, NULL) < 0)
140ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes		return (evConsTime((time_t)0, 0L));
1411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (evTimeSpec(now));
1421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct timespec
1451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevUTCTime(void) {
1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timeval now;
1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef CLOCK_REALTIME
1481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec tsnow;
1491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (clock_gettime(CLOCK_REALTIME, &tsnow) == 0)
1501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (tsnow);
1511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (gettimeofday(&now, NULL) < 0)
153ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes		return (evConsTime((time_t)0, 0L));
1541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (evTimeSpec(now));
1551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef _LIBC
1581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct timespec
1591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevLastEventTime(evContext opaqueCtx) {
1601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
1611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (ctx->lastEventTime);
1631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
1651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct timespec
1671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevTimeSpec(struct timeval tv) {
1681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec ts;
1691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ts.tv_sec = tv.tv_sec;
1711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	ts.tv_nsec = tv.tv_usec * 1000;
1721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (ts);
1731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct timeval
1761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevTimeVal(struct timespec ts) {
1771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timeval tv;
1781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tv.tv_sec = ts.tv_sec;
180ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes	tv.tv_usec = (suseconds_t)(ts.tv_nsec / 1000);
1811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (tv);
1821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
1831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef _LIBC
1851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
1861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevSetTimer(evContext opaqueCtx,
1871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   evTimerFunc func,
1881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   void *uap,
1891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   struct timespec due,
1901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   struct timespec inter,
1911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	   evTimerID *opaqueID
1921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project) {
1931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
1941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *id;
1951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
196ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes	evPrintf(ctx, 1,
197ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes"evSetTimer(ctx %p, func %p, uap %p, due %ld.%09ld, inter %ld.%09ld)\n",
1981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 ctx, func, uap,
1991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 (long)due.tv_sec, due.tv_nsec,
2001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 (long)inter.tv_sec, inter.tv_nsec);
2011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __hpux
2031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
2041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * tv_sec and tv_nsec are unsigned.
2051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
2061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (due.tv_nsec >= BILLION)
2071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
2081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (inter.tv_nsec >= BILLION)
2101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
2111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
2121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (due.tv_sec < 0 || due.tv_nsec < 0 || due.tv_nsec >= BILLION)
2131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
2141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (inter.tv_sec < 0 || inter.tv_nsec < 0 || inter.tv_nsec >= BILLION)
2161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
2171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
2181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* due={0,0} is a magic cookie meaning "now." */
2201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (due.tv_sec == (time_t)0 && due.tv_nsec == 0L)
2211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		due = evNowTime();
2221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Allocate and fill. */
2241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	OKNEW(id);
2251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	id->func = func;
2261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	id->uap = uap;
2271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	id->due = due;
2281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	id->inter = inter;
2291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (heap_insert(ctx->timers, id) < 0)
2311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
2321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Remember the ID if the caller provided us a place for it. */
2341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (opaqueID)
2351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		opaqueID->opaque = id;
2361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ctx->debug > 7) {
238ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes		evPrintf(ctx, 7, "timers after evSetTimer:\n");
2391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		(void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
2401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (0);
2431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
2441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
2461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevClearTimer(evContext opaqueCtx, evTimerID id) {
2471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
2481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *del = id.opaque;
2491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ctx->cur != NULL &&
2511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ctx->cur->type == Timer &&
2521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    ctx->cur->u.timer.this == del) {
253ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes		evPrintf(ctx, 8, "deferring delete of timer (executing)\n");
2541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
2551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Setting the interval to zero ensures that evDrop() will
2561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * clean up the timer.
2571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
2581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		del->inter = evConsTime(0, 0);
2591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (0);
2601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (heap_element(ctx->timers, del->index) != del)
2631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(ENOENT);
2641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (heap_delete(ctx->timers, del->index) < 0)
2661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
2671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	FREE(del);
2681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ctx->debug > 7) {
270ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes		evPrintf(ctx, 7, "timers after evClearTimer:\n");
2711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		(void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
2721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
2731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (0);
2751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
2761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
2781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevConfigTimer(evContext opaqueCtx,
2791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     evTimerID id,
2801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     const char *param,
2811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     int value
2821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project) {
2831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
2841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *timer = id.opaque;
2851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int result=0;
2861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	UNUSED(value);
2881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (heap_element(ctx->timers, timer->index) != timer)
2901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(ENOENT);
2911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (strcmp(param, "rate") == 0)
2931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		timer->mode |= EV_TMR_RATE;
2941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else if (strcmp(param, "interval") == 0)
2951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		timer->mode &= ~EV_TMR_RATE;
2961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	else
2971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
2981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
2991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (result);
3001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
3011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
3031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevResetTimer(evContext opaqueCtx,
3041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     evTimerID id,
3051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     evTimerFunc func,
3061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     void *uap,
3071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     struct timespec due,
3081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     struct timespec inter
3091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project) {
3101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
3111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *timer = id.opaque;
3121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec old_due;
3131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	int result=0;
3141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (heap_element(ctx->timers, timer->index) != timer)
3161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(ENOENT);
3171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifdef __hpux
3191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/*
3201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 * tv_sec and tv_nsec are unsigned.
3211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	 */
3221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (due.tv_nsec >= BILLION)
3231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
3241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (inter.tv_nsec >= BILLION)
3261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
3271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#else
3281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (due.tv_sec < 0 || due.tv_nsec < 0 || due.tv_nsec >= BILLION)
3291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
3301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (inter.tv_sec < 0 || inter.tv_nsec < 0 || inter.tv_nsec >= BILLION)
3321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		EV_ERR(EINVAL);
3331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
3341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	old_due = timer->due;
3361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	timer->func = func;
3381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	timer->uap = uap;
3391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	timer->due = due;
3401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	timer->inter = inter;
3411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	switch (evCmpTime(due, old_due)) {
3431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case -1:
3441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		result = heap_increased(ctx->timers, timer->index);
3451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
3461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case 0:
3471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		result = 0;
3481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
3491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	case 1:
3501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		result = heap_decreased(ctx->timers, timer->index);
3511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		break;
3521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
3531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (ctx->debug > 7) {
355ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes		evPrintf(ctx, 7, "timers after evResetTimer:\n");
3561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		(void) heap_for_each(ctx->timers, print_timer, (void *)ctx);
3571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
3581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (result);
3601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
3611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
3631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevSetIdleTimer(evContext opaqueCtx,
3641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		evTimerFunc func,
3651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		void *uap,
3661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		struct timespec max_idle,
3671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		evTimerID *opaqueID
3681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project) {
3691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
3701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	idle_timer *tt;
3711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	/* Allocate and fill. */
3731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	OKNEW(tt);
3741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->func = func;
3751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->uap = uap;
3761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->lastTouched = ctx->lastEventTime;
3771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->max_idle = max_idle;
3781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (evSetTimer(opaqueCtx, idle_timeout, tt,
3801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		       evAddTime(ctx->lastEventTime, max_idle),
3811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		       max_idle, opaqueID) < 0) {
3821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		FREE(tt);
3831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		return (-1);
3841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
3851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->timer = opaqueID->opaque;
3871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (0);
3891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
3901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
3921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevClearIdleTimer(evContext opaqueCtx, evTimerID id) {
3931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *del = id.opaque;
3941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	idle_timer *tt = del->uap;
3951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
3961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	FREE(tt);
3971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (evClearTimer(opaqueCtx, id));
3981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
3991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
4011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevResetIdleTimer(evContext opaqueCtx,
4021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 evTimerID opaqueID,
4031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 evTimerFunc func,
4041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 void *uap,
4051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 struct timespec max_idle
4061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project) {
4071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
4081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *timer = opaqueID.opaque;
4091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	idle_timer *tt = timer->uap;
4101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->func = func;
4121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->uap = uap;
4131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->lastTouched = ctx->lastEventTime;
4141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->max_idle = max_idle;
4151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (evResetTimer(opaqueCtx, opaqueID, idle_timeout, tt,
4171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			     evAddTime(ctx->lastEventTime, max_idle),
4181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			     max_idle));
4191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectint
4221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevTouchIdleTimer(evContext opaqueCtx, evTimerID id) {
4231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
4241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *t = id.opaque;
4251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	idle_timer *tt = t->uap;
4261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	tt->lastTouched = ctx->lastEventTime;
4281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (0);
4301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Public to the rest of eventlib. */
4331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectheap_context
4351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevCreateTimers(const evContext_p *ctx) {
4361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	UNUSED(ctx);
4381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (heap_new(due_sooner, set_index, 2048));
4401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid
4431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectevDestroyTimers(const evContext_p *ctx) {
4441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(void) heap_for_each(ctx->timers, free_timer, NULL);
4451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	(void) heap_free(ctx->timers);
4461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* Private. */
4491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic int
4511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectdue_sooner(void *a, void *b) {
4521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *a_timer, *b_timer;
4531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	a_timer = a;
4551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	b_timer = b;
4561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	return (evCmpTime(a_timer->due, b_timer->due) < 0);
4571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4591dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
4601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectset_index(void *what, int idx) {
4611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *timer;
4621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	timer = what;
4641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	timer->index = idx;
4651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
4681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectfree_timer(void *what, void *uap) {
4691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *t = what;
4701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	UNUSED(uap);
4721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	FREE(t);
4741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
4771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectprint_timer(void *what, void *uap) {
4781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evTimer *cur = what;
4791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = uap;
4801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	cur = what;
4821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evPrintf(ctx, 7,
4831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	    "  func %p, uap %p, due %ld.%09ld, inter %ld.%09ld\n",
4841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 cur->func, cur->uap,
4851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 (long)cur->due.tv_sec, cur->due.tv_nsec,
4861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 (long)cur->inter.tv_sec, cur->inter.tv_nsec);
4871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
4881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstatic void
4901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectidle_timeout(evContext opaqueCtx,
4911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     void *uap,
4921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     struct timespec due,
4931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	     struct timespec inter
4941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project) {
4951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	evContext_p *ctx = opaqueCtx.opaque;
4961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	idle_timer *this = uap;
4971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	struct timespec idle;
4981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
4991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	UNUSED(due);
5001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	UNUSED(inter);
5011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
5021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	idle = evSubTime(ctx->lastEventTime, this->lastTouched);
5031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	if (evCmpTime(idle, this->max_idle) >= 0) {
5041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		(this->func)(opaqueCtx, this->uap, this->timer->due,
5051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project			     this->max_idle);
5061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/*
5071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * Setting the interval to zero will cause the timer to
5081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 * be cleaned up in evDrop().
5091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		 */
5101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		this->timer->inter = evConsTime(0L, 0L);
5111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		FREE(this);
5121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	} else {
5131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		/* evDrop() will reschedule the timer. */
5141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project		this->timer->inter = evSubTime(this->max_idle, idle);
5151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project	}
5161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project}
5171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif
518ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes
519ab44f52202878cdf2bf22457aeae33ec24089556Elliott Hughes/*! \file */
520