xref: /minix3/external/bsd/bind/dist/bin/tests/timers/t_timers.c (revision 00b67f09dd46474d133c95011a48590a8e8f94c7)
1*00b67f09SDavid van Moolenbroek /*	$NetBSD: t_timers.c,v 1.6 2014/12/10 04:37:54 christos Exp $	*/
2*00b67f09SDavid van Moolenbroek 
3*00b67f09SDavid van Moolenbroek /*
4*00b67f09SDavid van Moolenbroek  * Copyright (C) 2004, 2007-2009, 2011, 2013  Internet Systems Consortium, Inc. ("ISC")
5*00b67f09SDavid van Moolenbroek  * Copyright (C) 1999-2001  Internet Software Consortium.
6*00b67f09SDavid van Moolenbroek  *
7*00b67f09SDavid van Moolenbroek  * Permission to use, copy, modify, and/or distribute this software for any
8*00b67f09SDavid van Moolenbroek  * purpose with or without fee is hereby granted, provided that the above
9*00b67f09SDavid van Moolenbroek  * copyright notice and this permission notice appear in all copies.
10*00b67f09SDavid van Moolenbroek  *
11*00b67f09SDavid van Moolenbroek  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
12*00b67f09SDavid van Moolenbroek  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
13*00b67f09SDavid van Moolenbroek  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
14*00b67f09SDavid van Moolenbroek  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
15*00b67f09SDavid van Moolenbroek  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
16*00b67f09SDavid van Moolenbroek  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17*00b67f09SDavid van Moolenbroek  * PERFORMANCE OF THIS SOFTWARE.
18*00b67f09SDavid van Moolenbroek  */
19*00b67f09SDavid van Moolenbroek 
20*00b67f09SDavid van Moolenbroek /* Id: t_timers.c,v 1.33 2011/03/14 14:13:10 fdupont Exp  */
21*00b67f09SDavid van Moolenbroek 
22*00b67f09SDavid van Moolenbroek #include <config.h>
23*00b67f09SDavid van Moolenbroek 
24*00b67f09SDavid van Moolenbroek #include <stdlib.h>
25*00b67f09SDavid van Moolenbroek 
26*00b67f09SDavid van Moolenbroek #include <isc/condition.h>
27*00b67f09SDavid van Moolenbroek #include <isc/mem.h>
28*00b67f09SDavid van Moolenbroek #include <isc/platform.h>
29*00b67f09SDavid van Moolenbroek #include <isc/task.h>
30*00b67f09SDavid van Moolenbroek #include <isc/time.h>
31*00b67f09SDavid van Moolenbroek #include <isc/timer.h>
32*00b67f09SDavid van Moolenbroek #include <isc/util.h>
33*00b67f09SDavid van Moolenbroek 
34*00b67f09SDavid van Moolenbroek #include <tests/t_api.h>
35*00b67f09SDavid van Moolenbroek 
36*00b67f09SDavid van Moolenbroek #ifdef ISC_PLATFORM_USETHREADS
37*00b67f09SDavid van Moolenbroek isc_boolean_t threaded = ISC_TRUE;
38*00b67f09SDavid van Moolenbroek #else
39*00b67f09SDavid van Moolenbroek isc_boolean_t threaded = ISC_FALSE;
40*00b67f09SDavid van Moolenbroek #endif
41*00b67f09SDavid van Moolenbroek 
42*00b67f09SDavid van Moolenbroek #define	Tx_FUDGE_SECONDS	0	     /* in absence of clock_getres() */
43*00b67f09SDavid van Moolenbroek #define	Tx_FUDGE_NANOSECONDS	500000000    /* in absence of clock_getres() */
44*00b67f09SDavid van Moolenbroek 
45*00b67f09SDavid van Moolenbroek static	isc_time_t	Tx_endtime;
46*00b67f09SDavid van Moolenbroek static	isc_time_t	Tx_lasttime;
47*00b67f09SDavid van Moolenbroek static	int		Tx_eventcnt;
48*00b67f09SDavid van Moolenbroek static	int		Tx_nevents;
49*00b67f09SDavid van Moolenbroek static	isc_mutex_t	Tx_mx;
50*00b67f09SDavid van Moolenbroek static	isc_condition_t	Tx_cv;
51*00b67f09SDavid van Moolenbroek static	int		Tx_nfails;
52*00b67f09SDavid van Moolenbroek static	int		Tx_nprobs;
53*00b67f09SDavid van Moolenbroek static	isc_timer_t    *Tx_timer;
54*00b67f09SDavid van Moolenbroek static	int		Tx_seconds;
55*00b67f09SDavid van Moolenbroek static	int		Tx_nanoseconds;
56*00b67f09SDavid van Moolenbroek 
57*00b67f09SDavid van Moolenbroek static void
require_threads(void)58*00b67f09SDavid van Moolenbroek require_threads(void) {
59*00b67f09SDavid van Moolenbroek 	t_info("This test requires threads\n");
60*00b67f09SDavid van Moolenbroek 	t_result(T_THREADONLY);
61*00b67f09SDavid van Moolenbroek 	return;
62*00b67f09SDavid van Moolenbroek }
63*00b67f09SDavid van Moolenbroek 
64*00b67f09SDavid van Moolenbroek static void
tx_sde(isc_task_t * task,isc_event_t * event)65*00b67f09SDavid van Moolenbroek tx_sde(isc_task_t *task, isc_event_t *event) {
66*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
67*00b67f09SDavid van Moolenbroek 
68*00b67f09SDavid van Moolenbroek 	UNUSED(task);
69*00b67f09SDavid van Moolenbroek 	UNUSED(event);
70*00b67f09SDavid van Moolenbroek 
71*00b67f09SDavid van Moolenbroek 	/*
72*00b67f09SDavid van Moolenbroek 	 * Signal shutdown processing complete.
73*00b67f09SDavid van Moolenbroek 	 */
74*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_lock(&Tx_mx);
75*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
76*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_lock failed %s\n",
77*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
78*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
79*00b67f09SDavid van Moolenbroek 	}
80*00b67f09SDavid van Moolenbroek 
81*00b67f09SDavid van Moolenbroek 	isc_result = isc_condition_signal(&Tx_cv);
82*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
83*00b67f09SDavid van Moolenbroek 		t_info("isc_condition_signal failed %s\n",
84*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
85*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
86*00b67f09SDavid van Moolenbroek 	}
87*00b67f09SDavid van Moolenbroek 
88*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_unlock(&Tx_mx);
89*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
90*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_unlock failed %s\n",
91*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
92*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
93*00b67f09SDavid van Moolenbroek 	}
94*00b67f09SDavid van Moolenbroek 
95*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
96*00b67f09SDavid van Moolenbroek }
97*00b67f09SDavid van Moolenbroek 
98*00b67f09SDavid van Moolenbroek static void
tx_te(isc_task_t * task,isc_event_t * event)99*00b67f09SDavid van Moolenbroek tx_te(isc_task_t *task, isc_event_t *event) {
100*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
101*00b67f09SDavid van Moolenbroek 	isc_time_t	now;
102*00b67f09SDavid van Moolenbroek 	isc_time_t	base;
103*00b67f09SDavid van Moolenbroek 	isc_time_t	ulim;
104*00b67f09SDavid van Moolenbroek 	isc_time_t	llim;
105*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
106*00b67f09SDavid van Moolenbroek 	isc_eventtype_t	expected_event_type;
107*00b67f09SDavid van Moolenbroek 
108*00b67f09SDavid van Moolenbroek 	++Tx_eventcnt;
109*00b67f09SDavid van Moolenbroek 
110*00b67f09SDavid van Moolenbroek 	t_info("tick %d\n", Tx_eventcnt);
111*00b67f09SDavid van Moolenbroek 
112*00b67f09SDavid van Moolenbroek 	expected_event_type = ISC_TIMEREVENT_LIFE;
113*00b67f09SDavid van Moolenbroek 	if ((isc_timertype_t) event->ev_arg == isc_timertype_ticker)
114*00b67f09SDavid van Moolenbroek 		expected_event_type = ISC_TIMEREVENT_TICK;
115*00b67f09SDavid van Moolenbroek 
116*00b67f09SDavid van Moolenbroek 	if (event->ev_type != expected_event_type) {
117*00b67f09SDavid van Moolenbroek 		t_info("expected event type %d, got %d\n",
118*00b67f09SDavid van Moolenbroek 			expected_event_type, (int) event->ev_type);
119*00b67f09SDavid van Moolenbroek 		++Tx_nfails;
120*00b67f09SDavid van Moolenbroek 	}
121*00b67f09SDavid van Moolenbroek 
122*00b67f09SDavid van Moolenbroek 	isc_result = isc_time_now(&now);
123*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
124*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds);
125*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_add(&Tx_lasttime, &interval, &base);
126*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
127*00b67f09SDavid van Moolenbroek 			t_info("isc_time_add failed %s\n",
128*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
129*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
130*00b67f09SDavid van Moolenbroek 		}
131*00b67f09SDavid van Moolenbroek 	} else {
132*00b67f09SDavid van Moolenbroek 		t_info("isc_time_now failed %s\n",
133*00b67f09SDavid van Moolenbroek 			isc_result_totext(isc_result));
134*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
135*00b67f09SDavid van Moolenbroek 	}
136*00b67f09SDavid van Moolenbroek 
137*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
138*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval,
139*00b67f09SDavid van Moolenbroek 				 Tx_FUDGE_SECONDS, Tx_FUDGE_NANOSECONDS);
140*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_add(&base, &interval, &ulim);
141*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
142*00b67f09SDavid van Moolenbroek 			t_info("isc_time_add failed %s\n",
143*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
144*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
145*00b67f09SDavid van Moolenbroek 		}
146*00b67f09SDavid van Moolenbroek 	}
147*00b67f09SDavid van Moolenbroek 
148*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
149*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_subtract(&base, &interval, &llim);
150*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
151*00b67f09SDavid van Moolenbroek 			t_info("isc_time_subtract failed %s\n",
152*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
153*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
154*00b67f09SDavid van Moolenbroek 		}
155*00b67f09SDavid van Moolenbroek 	}
156*00b67f09SDavid van Moolenbroek 
157*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
158*00b67f09SDavid van Moolenbroek 		if (isc_time_compare(&llim, &now) > 0) {
159*00b67f09SDavid van Moolenbroek 			t_info("timer range error: early by "
160*00b67f09SDavid van Moolenbroek 			       "%lu microseconds\n",
161*00b67f09SDavid van Moolenbroek 			       (unsigned long)isc_time_microdiff(&base, &now));
162*00b67f09SDavid van Moolenbroek 			++Tx_nfails;
163*00b67f09SDavid van Moolenbroek 		} else if (isc_time_compare(&ulim, &now) < 0) {
164*00b67f09SDavid van Moolenbroek 			t_info("timer range error: late by "
165*00b67f09SDavid van Moolenbroek 			       "%lu microseconds\n",
166*00b67f09SDavid van Moolenbroek 			       (unsigned long)isc_time_microdiff(&now, &base));
167*00b67f09SDavid van Moolenbroek 			++Tx_nfails;
168*00b67f09SDavid van Moolenbroek 		}
169*00b67f09SDavid van Moolenbroek 		Tx_lasttime = now;
170*00b67f09SDavid van Moolenbroek 	}
171*00b67f09SDavid van Moolenbroek 
172*00b67f09SDavid van Moolenbroek 	if (Tx_eventcnt == Tx_nevents) {
173*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_now(&Tx_endtime);
174*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
175*00b67f09SDavid van Moolenbroek 			t_info("isc_time_now failed %s\n",
176*00b67f09SDavid van Moolenbroek 				isc_result_totext(isc_result));
177*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
178*00b67f09SDavid van Moolenbroek 		}
179*00b67f09SDavid van Moolenbroek 		isc_timer_detach(&Tx_timer);
180*00b67f09SDavid van Moolenbroek 		isc_task_shutdown(task);
181*00b67f09SDavid van Moolenbroek 	}
182*00b67f09SDavid van Moolenbroek 
183*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
184*00b67f09SDavid van Moolenbroek }
185*00b67f09SDavid van Moolenbroek 
186*00b67f09SDavid van Moolenbroek static void
t_timers_x(isc_timertype_t timertype,isc_time_t * expires,isc_interval_t * interval,void (* action)(isc_task_t *,isc_event_t *))187*00b67f09SDavid van Moolenbroek t_timers_x(isc_timertype_t timertype, isc_time_t *expires,
188*00b67f09SDavid van Moolenbroek 	   isc_interval_t *interval,
189*00b67f09SDavid van Moolenbroek 	   void (*action)(isc_task_t *, isc_event_t *))
190*00b67f09SDavid van Moolenbroek {
191*00b67f09SDavid van Moolenbroek 	char		*p;
192*00b67f09SDavid van Moolenbroek 	isc_mem_t	*mctx;
193*00b67f09SDavid van Moolenbroek 	isc_taskmgr_t	*tmgr;
194*00b67f09SDavid van Moolenbroek 	isc_task_t	*task;
195*00b67f09SDavid van Moolenbroek 	unsigned int	workers;
196*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
197*00b67f09SDavid van Moolenbroek 	isc_timermgr_t	*timermgr;
198*00b67f09SDavid van Moolenbroek 
199*00b67f09SDavid van Moolenbroek 	Tx_eventcnt = 0;
200*00b67f09SDavid van Moolenbroek 	isc_time_settoepoch(&Tx_endtime);
201*00b67f09SDavid van Moolenbroek 
202*00b67f09SDavid van Moolenbroek 	workers = 2;
203*00b67f09SDavid van Moolenbroek 	p = t_getenv("ISC_TASK_WORKERS");
204*00b67f09SDavid van Moolenbroek 	if (p != NULL)
205*00b67f09SDavid van Moolenbroek 		workers = atoi(p);
206*00b67f09SDavid van Moolenbroek 
207*00b67f09SDavid van Moolenbroek 	mctx = NULL;
208*00b67f09SDavid van Moolenbroek 	isc_result = isc_mem_create(0, 0, &mctx);
209*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
210*00b67f09SDavid van Moolenbroek 		t_info("isc_mem_create failed %s\n",
211*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
212*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
213*00b67f09SDavid van Moolenbroek 		return;
214*00b67f09SDavid van Moolenbroek 	}
215*00b67f09SDavid van Moolenbroek 
216*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_init(&Tx_mx);
217*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
218*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_init failed %s\n",
219*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
220*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
221*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
222*00b67f09SDavid van Moolenbroek 		return;
223*00b67f09SDavid van Moolenbroek 	}
224*00b67f09SDavid van Moolenbroek 
225*00b67f09SDavid van Moolenbroek 	isc_result = isc_condition_init(&Tx_cv);
226*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
227*00b67f09SDavid van Moolenbroek 		t_info("isc_condition_init failed %s\n",
228*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
229*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&Tx_mx);
230*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
231*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
232*00b67f09SDavid van Moolenbroek 		return;
233*00b67f09SDavid van Moolenbroek 	}
234*00b67f09SDavid van Moolenbroek 
235*00b67f09SDavid van Moolenbroek 	tmgr = NULL;
236*00b67f09SDavid van Moolenbroek 	isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr);
237*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
238*00b67f09SDavid van Moolenbroek 		t_info("isc_taskmgr_create failed %s\n",
239*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
240*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&Tx_mx);
241*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&Tx_cv);
242*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
243*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
244*00b67f09SDavid van Moolenbroek 		return;
245*00b67f09SDavid van Moolenbroek 	}
246*00b67f09SDavid van Moolenbroek 
247*00b67f09SDavid van Moolenbroek 	timermgr = NULL;
248*00b67f09SDavid van Moolenbroek 	isc_result = isc_timermgr_create(mctx, &timermgr);
249*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
250*00b67f09SDavid van Moolenbroek 		t_info("isc_timermgr_create failed %s\n",
251*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
252*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
253*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&Tx_mx);
254*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&Tx_cv);
255*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
256*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
257*00b67f09SDavid van Moolenbroek 		return;
258*00b67f09SDavid van Moolenbroek 	}
259*00b67f09SDavid van Moolenbroek 
260*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_lock(&Tx_mx);
261*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
262*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_lock failed %s\n",
263*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
264*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
265*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
266*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&Tx_mx);
267*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&Tx_cv);
268*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
269*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
270*00b67f09SDavid van Moolenbroek 		return;
271*00b67f09SDavid van Moolenbroek 	}
272*00b67f09SDavid van Moolenbroek 
273*00b67f09SDavid van Moolenbroek 	task = NULL;
274*00b67f09SDavid van Moolenbroek 	isc_result = isc_task_create(tmgr, 0, &task);
275*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
276*00b67f09SDavid van Moolenbroek 		t_info("isc_task_create failed %s\n",
277*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
278*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
279*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
280*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&Tx_mx);
281*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&Tx_cv);
282*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
283*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
284*00b67f09SDavid van Moolenbroek 		return;
285*00b67f09SDavid van Moolenbroek 	}
286*00b67f09SDavid van Moolenbroek 
287*00b67f09SDavid van Moolenbroek 	isc_result = isc_task_onshutdown(task, tx_sde, NULL);
288*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
289*00b67f09SDavid van Moolenbroek 		t_info("isc_task_onshutdown failed %s\n",
290*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
291*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
292*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&task);
293*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
294*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&Tx_mx);
295*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&Tx_cv);
296*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
297*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
298*00b67f09SDavid van Moolenbroek 		return;
299*00b67f09SDavid van Moolenbroek 	}
300*00b67f09SDavid van Moolenbroek 
301*00b67f09SDavid van Moolenbroek 	isc_result = isc_time_now(&Tx_lasttime);
302*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
303*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
304*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&task);
305*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
306*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&Tx_mx);
307*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&Tx_cv);
308*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
309*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
310*00b67f09SDavid van Moolenbroek 		return;
311*00b67f09SDavid van Moolenbroek 	}
312*00b67f09SDavid van Moolenbroek 
313*00b67f09SDavid van Moolenbroek 	Tx_timer = NULL;
314*00b67f09SDavid van Moolenbroek 	isc_result = isc_timer_create(timermgr, timertype, expires, interval,
315*00b67f09SDavid van Moolenbroek 				      task, action, (void *)timertype,
316*00b67f09SDavid van Moolenbroek 				      &Tx_timer);
317*00b67f09SDavid van Moolenbroek 
318*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
319*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
320*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&task);
321*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
322*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&Tx_mx);
323*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&Tx_cv);
324*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
325*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
326*00b67f09SDavid van Moolenbroek 		return;
327*00b67f09SDavid van Moolenbroek 	}
328*00b67f09SDavid van Moolenbroek 
329*00b67f09SDavid van Moolenbroek 	/*
330*00b67f09SDavid van Moolenbroek 	 * Wait for shutdown processing to complete.
331*00b67f09SDavid van Moolenbroek 	 */
332*00b67f09SDavid van Moolenbroek 	while (Tx_eventcnt != Tx_nevents) {
333*00b67f09SDavid van Moolenbroek 		isc_result = isc_condition_wait(&Tx_cv, &Tx_mx);
334*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
335*00b67f09SDavid van Moolenbroek 			t_info("isc_condition_waituntil failed %s\n",
336*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
337*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
338*00b67f09SDavid van Moolenbroek 		}
339*00b67f09SDavid van Moolenbroek 	}
340*00b67f09SDavid van Moolenbroek 
341*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_unlock(&Tx_mx);
342*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
343*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_unlock failed %s\n",
344*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
345*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
346*00b67f09SDavid van Moolenbroek 	}
347*00b67f09SDavid van Moolenbroek 
348*00b67f09SDavid van Moolenbroek 	isc_task_detach(&task);
349*00b67f09SDavid van Moolenbroek 	isc_taskmgr_destroy(&tmgr);
350*00b67f09SDavid van Moolenbroek 	isc_timermgr_destroy(&timermgr);
351*00b67f09SDavid van Moolenbroek 	DESTROYLOCK(&Tx_mx);
352*00b67f09SDavid van Moolenbroek 	(void) isc_condition_destroy(&Tx_cv);
353*00b67f09SDavid van Moolenbroek 	isc_mem_destroy(&mctx);
354*00b67f09SDavid van Moolenbroek 
355*00b67f09SDavid van Moolenbroek }
356*00b67f09SDavid van Moolenbroek 
357*00b67f09SDavid van Moolenbroek #define	T1_SECONDS	2
358*00b67f09SDavid van Moolenbroek #define	T1_NANOSECONDS	500000000
359*00b67f09SDavid van Moolenbroek 
360*00b67f09SDavid van Moolenbroek static const char *a1 =
361*00b67f09SDavid van Moolenbroek 	"When type is isc_timertype_ticker, a call to isc_timer_create() "
362*00b67f09SDavid van Moolenbroek 	"creates a timer that posts an ISC_TIMEREVENT_TICK event to the "
363*00b67f09SDavid van Moolenbroek 	"specified task every 'interval' seconds and returns ISC_R_SUCCESS.";
364*00b67f09SDavid van Moolenbroek 
365*00b67f09SDavid van Moolenbroek static void
t1(void)366*00b67f09SDavid van Moolenbroek t1(void) {
367*00b67f09SDavid van Moolenbroek 	int		result;
368*00b67f09SDavid van Moolenbroek 	isc_time_t	expires;
369*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
370*00b67f09SDavid van Moolenbroek 
371*00b67f09SDavid van Moolenbroek 	t_assert("isc_timer_create", 1, T_REQUIRED, "%s", a1);
372*00b67f09SDavid van Moolenbroek 
373*00b67f09SDavid van Moolenbroek 	if (threaded) {
374*00b67f09SDavid van Moolenbroek 		Tx_nfails	= 0;
375*00b67f09SDavid van Moolenbroek 		Tx_nprobs	= 0;
376*00b67f09SDavid van Moolenbroek 		Tx_nevents	= 12;
377*00b67f09SDavid van Moolenbroek 		Tx_seconds	= T1_SECONDS;
378*00b67f09SDavid van Moolenbroek 		Tx_nanoseconds	= T1_NANOSECONDS;
379*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds);
380*00b67f09SDavid van Moolenbroek 		isc_time_settoepoch(&expires);
381*00b67f09SDavid van Moolenbroek 
382*00b67f09SDavid van Moolenbroek 		t_timers_x(isc_timertype_ticker, &expires, &interval, tx_te);
383*00b67f09SDavid van Moolenbroek 
384*00b67f09SDavid van Moolenbroek 		result = T_UNRESOLVED;
385*00b67f09SDavid van Moolenbroek 
386*00b67f09SDavid van Moolenbroek 		if ((Tx_nfails == 0) && (Tx_nprobs == 0))
387*00b67f09SDavid van Moolenbroek 			result = T_PASS;
388*00b67f09SDavid van Moolenbroek 		else if (Tx_nfails)
389*00b67f09SDavid van Moolenbroek 			result = T_FAIL;
390*00b67f09SDavid van Moolenbroek 
391*00b67f09SDavid van Moolenbroek 		t_result(result);
392*00b67f09SDavid van Moolenbroek 	} else
393*00b67f09SDavid van Moolenbroek 		require_threads();
394*00b67f09SDavid van Moolenbroek }
395*00b67f09SDavid van Moolenbroek 
396*00b67f09SDavid van Moolenbroek #define	T2_SECONDS	5
397*00b67f09SDavid van Moolenbroek #define	T2_NANOSECONDS	300000000;
398*00b67f09SDavid van Moolenbroek 
399*00b67f09SDavid van Moolenbroek static const char *a2 =
400*00b67f09SDavid van Moolenbroek 	"When type is isc_timertype_once, a call to isc_timer_create() "
401*00b67f09SDavid van Moolenbroek 	"creates a timer that posts an ISC_TIMEEVENT_LIFE event to the "
402*00b67f09SDavid van Moolenbroek 	"specified task when the current time reaches or exceeds the time "
403*00b67f09SDavid van Moolenbroek 	"specified by 'expires'.";
404*00b67f09SDavid van Moolenbroek 
405*00b67f09SDavid van Moolenbroek static void
t2(void)406*00b67f09SDavid van Moolenbroek t2(void) {
407*00b67f09SDavid van Moolenbroek 	int		result;
408*00b67f09SDavid van Moolenbroek 	int		isc_result;
409*00b67f09SDavid van Moolenbroek 	isc_time_t	expires;
410*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
411*00b67f09SDavid van Moolenbroek 
412*00b67f09SDavid van Moolenbroek 	t_assert("isc_timer_create", 2, T_REQUIRED, "%s", a2);
413*00b67f09SDavid van Moolenbroek 
414*00b67f09SDavid van Moolenbroek 	if (threaded) {
415*00b67f09SDavid van Moolenbroek 		Tx_nfails	= 0;
416*00b67f09SDavid van Moolenbroek 		Tx_nprobs	= 0;
417*00b67f09SDavid van Moolenbroek 		Tx_nevents	= 1;
418*00b67f09SDavid van Moolenbroek 		Tx_seconds	= T2_SECONDS;
419*00b67f09SDavid van Moolenbroek 		Tx_nanoseconds	= T2_NANOSECONDS;
420*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds);
421*00b67f09SDavid van Moolenbroek 
422*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_nowplusinterval(&expires, &interval);
423*00b67f09SDavid van Moolenbroek 		if (isc_result == ISC_R_SUCCESS) {
424*00b67f09SDavid van Moolenbroek 
425*00b67f09SDavid van Moolenbroek 			isc_interval_set(&interval, 0, 0);
426*00b67f09SDavid van Moolenbroek 			t_timers_x(isc_timertype_once, &expires, &interval,
427*00b67f09SDavid van Moolenbroek 				   tx_te);
428*00b67f09SDavid van Moolenbroek 
429*00b67f09SDavid van Moolenbroek 		} else {
430*00b67f09SDavid van Moolenbroek 			t_info("isc_time_nowplusinterval failed %s\n",
431*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
432*00b67f09SDavid van Moolenbroek 		}
433*00b67f09SDavid van Moolenbroek 
434*00b67f09SDavid van Moolenbroek 		result = T_UNRESOLVED;
435*00b67f09SDavid van Moolenbroek 
436*00b67f09SDavid van Moolenbroek 		if ((Tx_nfails == 0) && (Tx_nprobs == 0))
437*00b67f09SDavid van Moolenbroek 			result = T_PASS;
438*00b67f09SDavid van Moolenbroek 		else if (Tx_nfails)
439*00b67f09SDavid van Moolenbroek 			result = T_FAIL;
440*00b67f09SDavid van Moolenbroek 
441*00b67f09SDavid van Moolenbroek 		t_result(result);
442*00b67f09SDavid van Moolenbroek 	} else
443*00b67f09SDavid van Moolenbroek 		require_threads();
444*00b67f09SDavid van Moolenbroek }
445*00b67f09SDavid van Moolenbroek 
446*00b67f09SDavid van Moolenbroek static void
t3_te(isc_task_t * task,isc_event_t * event)447*00b67f09SDavid van Moolenbroek t3_te(isc_task_t *task, isc_event_t *event) {
448*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
449*00b67f09SDavid van Moolenbroek 	isc_time_t	now;
450*00b67f09SDavid van Moolenbroek 	isc_time_t	base;
451*00b67f09SDavid van Moolenbroek 	isc_time_t	ulim;
452*00b67f09SDavid van Moolenbroek 	isc_time_t	llim;
453*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
454*00b67f09SDavid van Moolenbroek 
455*00b67f09SDavid van Moolenbroek 	++Tx_eventcnt;
456*00b67f09SDavid van Moolenbroek 
457*00b67f09SDavid van Moolenbroek 	t_info("tick %d\n", Tx_eventcnt);
458*00b67f09SDavid van Moolenbroek 
459*00b67f09SDavid van Moolenbroek 	isc_result = isc_time_now(&now);
460*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
461*00b67f09SDavid van Moolenbroek 		t_info("isc_time_now failed %s\n",
462*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
463*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
464*00b67f09SDavid van Moolenbroek 	}
465*00b67f09SDavid van Moolenbroek 
466*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
467*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds);
468*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_add(&Tx_lasttime, &interval, &base);
469*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
470*00b67f09SDavid van Moolenbroek 			t_info("isc_time_add failed %s\n",
471*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
472*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
473*00b67f09SDavid van Moolenbroek 		}
474*00b67f09SDavid van Moolenbroek 	}
475*00b67f09SDavid van Moolenbroek 
476*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
477*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval,
478*00b67f09SDavid van Moolenbroek 				 Tx_FUDGE_SECONDS, Tx_FUDGE_NANOSECONDS);
479*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_add(&base, &interval, &ulim);
480*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
481*00b67f09SDavid van Moolenbroek 			t_info("isc_time_add failed %s\n",
482*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
483*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
484*00b67f09SDavid van Moolenbroek 		}
485*00b67f09SDavid van Moolenbroek 	}
486*00b67f09SDavid van Moolenbroek 
487*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
488*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_subtract(&base, &interval, &llim);
489*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
490*00b67f09SDavid van Moolenbroek 			t_info("isc_time_subtract failed %s\n",
491*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
492*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
493*00b67f09SDavid van Moolenbroek 		}
494*00b67f09SDavid van Moolenbroek 	}
495*00b67f09SDavid van Moolenbroek 
496*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
497*00b67f09SDavid van Moolenbroek 		if (isc_time_compare(&llim, &now) > 0) {
498*00b67f09SDavid van Moolenbroek 			t_info("timer range error: early by "
499*00b67f09SDavid van Moolenbroek 			       "%lu microseconds\n",
500*00b67f09SDavid van Moolenbroek 			       (unsigned long)isc_time_microdiff(&base, &now));
501*00b67f09SDavid van Moolenbroek 			++Tx_nfails;
502*00b67f09SDavid van Moolenbroek 		} else if (isc_time_compare(&ulim, &now) < 0) {
503*00b67f09SDavid van Moolenbroek 			t_info("timer range error: late by "
504*00b67f09SDavid van Moolenbroek 			       "%lu microseconds\n",
505*00b67f09SDavid van Moolenbroek 			       (unsigned long)isc_time_microdiff(&now, &base));
506*00b67f09SDavid van Moolenbroek 			++Tx_nfails;
507*00b67f09SDavid van Moolenbroek 		}
508*00b67f09SDavid van Moolenbroek 		Tx_lasttime = now;
509*00b67f09SDavid van Moolenbroek 	}
510*00b67f09SDavid van Moolenbroek 
511*00b67f09SDavid van Moolenbroek 	if (event->ev_type != ISC_TIMEREVENT_IDLE) {
512*00b67f09SDavid van Moolenbroek 		t_info("received event type %d, expected type %d\n",
513*00b67f09SDavid van Moolenbroek 		       event->ev_type, ISC_TIMEREVENT_IDLE);
514*00b67f09SDavid van Moolenbroek 		++Tx_nfails;
515*00b67f09SDavid van Moolenbroek 	}
516*00b67f09SDavid van Moolenbroek 
517*00b67f09SDavid van Moolenbroek 	isc_timer_detach(&Tx_timer);
518*00b67f09SDavid van Moolenbroek 	isc_task_shutdown(task);
519*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
520*00b67f09SDavid van Moolenbroek }
521*00b67f09SDavid van Moolenbroek 
522*00b67f09SDavid van Moolenbroek #define	T3_SECONDS	4
523*00b67f09SDavid van Moolenbroek #define	T3_NANOSECONDS	400000000
524*00b67f09SDavid van Moolenbroek 
525*00b67f09SDavid van Moolenbroek static const char *a3 =
526*00b67f09SDavid van Moolenbroek 	"When type is isc_timertype_once, a call to isc_timer_create() "
527*00b67f09SDavid van Moolenbroek 	"creates a timer that posts an ISC_TIMEEVENT_IDLE event to the "
528*00b67f09SDavid van Moolenbroek 	"specified task when the timer has been idle for 'interval' seconds.";
529*00b67f09SDavid van Moolenbroek 
530*00b67f09SDavid van Moolenbroek static void
t3(void)531*00b67f09SDavid van Moolenbroek t3(void) {
532*00b67f09SDavid van Moolenbroek 	int		result;
533*00b67f09SDavid van Moolenbroek 	int		isc_result;
534*00b67f09SDavid van Moolenbroek 	isc_time_t	expires;
535*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
536*00b67f09SDavid van Moolenbroek 
537*00b67f09SDavid van Moolenbroek 	t_assert("isc_timer_create", 3, T_REQUIRED, "%s", a3);
538*00b67f09SDavid van Moolenbroek 
539*00b67f09SDavid van Moolenbroek 	if (threaded) {
540*00b67f09SDavid van Moolenbroek 		Tx_nfails	= 0;
541*00b67f09SDavid van Moolenbroek 		Tx_nprobs	= 0;
542*00b67f09SDavid van Moolenbroek 		Tx_nevents	= 1;
543*00b67f09SDavid van Moolenbroek 		Tx_seconds	= T3_SECONDS;
544*00b67f09SDavid van Moolenbroek 		Tx_nanoseconds	= T3_NANOSECONDS;
545*00b67f09SDavid van Moolenbroek 
546*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval, Tx_seconds + 1, Tx_nanoseconds);
547*00b67f09SDavid van Moolenbroek 
548*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_nowplusinterval(&expires, &interval);
549*00b67f09SDavid van Moolenbroek 		if (isc_result == ISC_R_SUCCESS) {
550*00b67f09SDavid van Moolenbroek 			isc_interval_set(&interval, Tx_seconds,
551*00b67f09SDavid van Moolenbroek 					 Tx_nanoseconds);
552*00b67f09SDavid van Moolenbroek 			t_timers_x(isc_timertype_once, &expires, &interval,
553*00b67f09SDavid van Moolenbroek 				   t3_te);
554*00b67f09SDavid van Moolenbroek 		} else {
555*00b67f09SDavid van Moolenbroek 			t_info("isc_time_nowplusinterval failed %s\n",
556*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
557*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
558*00b67f09SDavid van Moolenbroek 		}
559*00b67f09SDavid van Moolenbroek 
560*00b67f09SDavid van Moolenbroek 		result = T_UNRESOLVED;
561*00b67f09SDavid van Moolenbroek 
562*00b67f09SDavid van Moolenbroek 		if ((Tx_nfails == 0) && (Tx_nprobs == 0))
563*00b67f09SDavid van Moolenbroek 			result = T_PASS;
564*00b67f09SDavid van Moolenbroek 		else if (Tx_nfails)
565*00b67f09SDavid van Moolenbroek 			result = T_FAIL;
566*00b67f09SDavid van Moolenbroek 
567*00b67f09SDavid van Moolenbroek 		t_result(result);
568*00b67f09SDavid van Moolenbroek 	} else
569*00b67f09SDavid van Moolenbroek 		require_threads();
570*00b67f09SDavid van Moolenbroek }
571*00b67f09SDavid van Moolenbroek 
572*00b67f09SDavid van Moolenbroek #define	T4_SECONDS	2
573*00b67f09SDavid van Moolenbroek #define	T4_NANOSECONDS	500000000
574*00b67f09SDavid van Moolenbroek 
575*00b67f09SDavid van Moolenbroek static void
t4_te(isc_task_t * task,isc_event_t * event)576*00b67f09SDavid van Moolenbroek t4_te(isc_task_t *task, isc_event_t *event) {
577*00b67f09SDavid van Moolenbroek 
578*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
579*00b67f09SDavid van Moolenbroek 	isc_time_t	now;
580*00b67f09SDavid van Moolenbroek 	isc_time_t	base;
581*00b67f09SDavid van Moolenbroek 	isc_time_t	ulim;
582*00b67f09SDavid van Moolenbroek 	isc_time_t	llim;
583*00b67f09SDavid van Moolenbroek 	isc_time_t	expires;
584*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
585*00b67f09SDavid van Moolenbroek 
586*00b67f09SDavid van Moolenbroek 	++Tx_eventcnt;
587*00b67f09SDavid van Moolenbroek 
588*00b67f09SDavid van Moolenbroek 	t_info("tick %d\n", Tx_eventcnt);
589*00b67f09SDavid van Moolenbroek 
590*00b67f09SDavid van Moolenbroek 	/*
591*00b67f09SDavid van Moolenbroek 	 * Check expired time.
592*00b67f09SDavid van Moolenbroek 	 */
593*00b67f09SDavid van Moolenbroek 
594*00b67f09SDavid van Moolenbroek 	isc_result = isc_time_now(&now);
595*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
596*00b67f09SDavid van Moolenbroek 		t_info("isc_time_now failed %s\n",
597*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
598*00b67f09SDavid van Moolenbroek 		++Tx_nprobs;
599*00b67f09SDavid van Moolenbroek 	}
600*00b67f09SDavid van Moolenbroek 
601*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
602*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds);
603*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_add(&Tx_lasttime, &interval, &base);
604*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
605*00b67f09SDavid van Moolenbroek 			t_info("isc_time_add failed %s\n",
606*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
607*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
608*00b67f09SDavid van Moolenbroek 		}
609*00b67f09SDavid van Moolenbroek 	}
610*00b67f09SDavid van Moolenbroek 
611*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
612*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval,
613*00b67f09SDavid van Moolenbroek 				 Tx_FUDGE_SECONDS, Tx_FUDGE_NANOSECONDS);
614*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_add(&base, &interval, &ulim);
615*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
616*00b67f09SDavid van Moolenbroek 			t_info("isc_time_add failed %s\n",
617*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
618*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
619*00b67f09SDavid van Moolenbroek 		}
620*00b67f09SDavid van Moolenbroek 	}
621*00b67f09SDavid van Moolenbroek 
622*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
623*00b67f09SDavid van Moolenbroek 		isc_result = isc_time_subtract(&base, &interval, &llim);
624*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
625*00b67f09SDavid van Moolenbroek 			t_info("isc_time_subtract failed %s\n",
626*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
627*00b67f09SDavid van Moolenbroek 			++Tx_nprobs;
628*00b67f09SDavid van Moolenbroek 		}
629*00b67f09SDavid van Moolenbroek 	}
630*00b67f09SDavid van Moolenbroek 
631*00b67f09SDavid van Moolenbroek 	if (isc_result == ISC_R_SUCCESS) {
632*00b67f09SDavid van Moolenbroek 		if (isc_time_compare(&llim, &now) > 0) {
633*00b67f09SDavid van Moolenbroek 			t_info("timer range error: early by "
634*00b67f09SDavid van Moolenbroek 			       "%lu microseconds\n",
635*00b67f09SDavid van Moolenbroek 			       (unsigned long)isc_time_microdiff(&base, &now));
636*00b67f09SDavid van Moolenbroek 			++Tx_nfails;
637*00b67f09SDavid van Moolenbroek 		} else if (isc_time_compare(&ulim, &now) < 0) {
638*00b67f09SDavid van Moolenbroek 			t_info("timer range error: late by "
639*00b67f09SDavid van Moolenbroek 			       "%lu microseconds\n",
640*00b67f09SDavid van Moolenbroek 			       (unsigned long)isc_time_microdiff(&now, &base));
641*00b67f09SDavid van Moolenbroek 			++Tx_nfails;
642*00b67f09SDavid van Moolenbroek 		}
643*00b67f09SDavid van Moolenbroek 		Tx_lasttime = now;
644*00b67f09SDavid van Moolenbroek 	}
645*00b67f09SDavid van Moolenbroek 
646*00b67f09SDavid van Moolenbroek 	if (Tx_eventcnt < 3) {
647*00b67f09SDavid van Moolenbroek 		if (event->ev_type != ISC_TIMEREVENT_TICK) {
648*00b67f09SDavid van Moolenbroek 			t_info("received event type %d, expected type %d\n",
649*00b67f09SDavid van Moolenbroek 			       event->ev_type, ISC_TIMEREVENT_IDLE);
650*00b67f09SDavid van Moolenbroek 			++Tx_nfails;
651*00b67f09SDavid van Moolenbroek 		}
652*00b67f09SDavid van Moolenbroek 		if (Tx_eventcnt == 2) {
653*00b67f09SDavid van Moolenbroek 			isc_interval_set(&interval, T4_SECONDS,
654*00b67f09SDavid van Moolenbroek 					 T4_NANOSECONDS);
655*00b67f09SDavid van Moolenbroek 			isc_result = isc_time_nowplusinterval(&expires,
656*00b67f09SDavid van Moolenbroek 							      &interval);
657*00b67f09SDavid van Moolenbroek 			if (isc_result == ISC_R_SUCCESS) {
658*00b67f09SDavid van Moolenbroek 				isc_interval_set(&interval, 0, 0);
659*00b67f09SDavid van Moolenbroek 				isc_result =
660*00b67f09SDavid van Moolenbroek 					isc_timer_reset(Tx_timer,
661*00b67f09SDavid van Moolenbroek 							isc_timertype_once,
662*00b67f09SDavid van Moolenbroek 							&expires, &interval,
663*00b67f09SDavid van Moolenbroek 							ISC_FALSE);
664*00b67f09SDavid van Moolenbroek 				if (isc_result != ISC_R_SUCCESS) {
665*00b67f09SDavid van Moolenbroek 					t_info("isc_timer_reset failed %s\n",
666*00b67f09SDavid van Moolenbroek 					       isc_result_totext(isc_result));
667*00b67f09SDavid van Moolenbroek 					++Tx_nfails;
668*00b67f09SDavid van Moolenbroek 				}
669*00b67f09SDavid van Moolenbroek 			} else {
670*00b67f09SDavid van Moolenbroek 				t_info("isc_time_nowplusinterval failed %s\n",
671*00b67f09SDavid van Moolenbroek 				       isc_result_totext(isc_result));
672*00b67f09SDavid van Moolenbroek 				++Tx_nprobs;
673*00b67f09SDavid van Moolenbroek 			}
674*00b67f09SDavid van Moolenbroek 		}
675*00b67f09SDavid van Moolenbroek 	} else {
676*00b67f09SDavid van Moolenbroek 		if (event->ev_type != ISC_TIMEREVENT_LIFE) {
677*00b67f09SDavid van Moolenbroek 			t_info("received event type %d, expected type %d\n",
678*00b67f09SDavid van Moolenbroek 			       event->ev_type, ISC_TIMEREVENT_IDLE);
679*00b67f09SDavid van Moolenbroek 			++Tx_nfails;
680*00b67f09SDavid van Moolenbroek 		}
681*00b67f09SDavid van Moolenbroek 
682*00b67f09SDavid van Moolenbroek 		isc_timer_detach(&Tx_timer);
683*00b67f09SDavid van Moolenbroek 		isc_task_shutdown(task);
684*00b67f09SDavid van Moolenbroek 	}
685*00b67f09SDavid van Moolenbroek 
686*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
687*00b67f09SDavid van Moolenbroek }
688*00b67f09SDavid van Moolenbroek 
689*00b67f09SDavid van Moolenbroek static const char *a4 =
690*00b67f09SDavid van Moolenbroek 	"A call to isc_timer_reset() changes the timer's type, expires and "
691*00b67f09SDavid van Moolenbroek 	"interval values to the given values.";
692*00b67f09SDavid van Moolenbroek 
693*00b67f09SDavid van Moolenbroek static void
t4(void)694*00b67f09SDavid van Moolenbroek t4(void) {
695*00b67f09SDavid van Moolenbroek 	int		result;
696*00b67f09SDavid van Moolenbroek 	isc_time_t	expires;
697*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
698*00b67f09SDavid van Moolenbroek 
699*00b67f09SDavid van Moolenbroek 	t_assert("isc_timer_reset", 4, T_REQUIRED, "%s", a4);
700*00b67f09SDavid van Moolenbroek 
701*00b67f09SDavid van Moolenbroek 	if (threaded) {
702*00b67f09SDavid van Moolenbroek 		Tx_nfails = 0;
703*00b67f09SDavid van Moolenbroek 		Tx_nprobs = 0;
704*00b67f09SDavid van Moolenbroek 		Tx_nevents = 3;
705*00b67f09SDavid van Moolenbroek 		Tx_seconds = T4_SECONDS;
706*00b67f09SDavid van Moolenbroek 		Tx_nanoseconds = T4_NANOSECONDS;
707*00b67f09SDavid van Moolenbroek 
708*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval, T4_SECONDS, T4_NANOSECONDS);
709*00b67f09SDavid van Moolenbroek 		isc_time_settoepoch(&expires);
710*00b67f09SDavid van Moolenbroek 		t_timers_x(isc_timertype_ticker, &expires, &interval, t4_te);
711*00b67f09SDavid van Moolenbroek 
712*00b67f09SDavid van Moolenbroek 		result = T_UNRESOLVED;
713*00b67f09SDavid van Moolenbroek 
714*00b67f09SDavid van Moolenbroek 		if ((Tx_nfails == 0) && (Tx_nprobs == 0))
715*00b67f09SDavid van Moolenbroek 			result = T_PASS;
716*00b67f09SDavid van Moolenbroek 		else if (Tx_nfails)
717*00b67f09SDavid van Moolenbroek 			result = T_FAIL;
718*00b67f09SDavid van Moolenbroek 
719*00b67f09SDavid van Moolenbroek 		t_result(result);
720*00b67f09SDavid van Moolenbroek 	} else
721*00b67f09SDavid van Moolenbroek 		require_threads();
722*00b67f09SDavid van Moolenbroek }
723*00b67f09SDavid van Moolenbroek 
724*00b67f09SDavid van Moolenbroek #define	T5_NTICKS	4
725*00b67f09SDavid van Moolenbroek #define	T5_SECONDS	3
726*00b67f09SDavid van Moolenbroek 
727*00b67f09SDavid van Moolenbroek static	int		T5_startflag;
728*00b67f09SDavid van Moolenbroek static	int		T5_shutdownflag;
729*00b67f09SDavid van Moolenbroek static	int		T5_eventcnt;
730*00b67f09SDavid van Moolenbroek static	isc_mutex_t	T5_mx;
731*00b67f09SDavid van Moolenbroek static	isc_condition_t	T5_cv;
732*00b67f09SDavid van Moolenbroek static	int		T5_nfails;
733*00b67f09SDavid van Moolenbroek static	int		T5_nprobs;
734*00b67f09SDavid van Moolenbroek static	isc_timer_t	*T5_tickertimer;
735*00b67f09SDavid van Moolenbroek static	isc_timer_t	*T5_oncetimer;
736*00b67f09SDavid van Moolenbroek static	isc_task_t	*T5_task1;
737*00b67f09SDavid van Moolenbroek static	isc_task_t	*T5_task2;
738*00b67f09SDavid van Moolenbroek 
739*00b67f09SDavid van Moolenbroek /*
740*00b67f09SDavid van Moolenbroek  * T5_task1 blocks on T5_mx while events accumulate
741*00b67f09SDavid van Moolenbroek  * in it's queue, until signaled by T5_task2.
742*00b67f09SDavid van Moolenbroek  */
743*00b67f09SDavid van Moolenbroek 
744*00b67f09SDavid van Moolenbroek static void
t5_start_event(isc_task_t * task,isc_event_t * event)745*00b67f09SDavid van Moolenbroek t5_start_event(isc_task_t *task, isc_event_t *event) {
746*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
747*00b67f09SDavid van Moolenbroek 
748*00b67f09SDavid van Moolenbroek 	UNUSED(task);
749*00b67f09SDavid van Moolenbroek 
750*00b67f09SDavid van Moolenbroek 	t_info("t5_start_event\n");
751*00b67f09SDavid van Moolenbroek 
752*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_lock(&T5_mx);
753*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
754*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_lock failed %s\n",
755*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
756*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
757*00b67f09SDavid van Moolenbroek 	}
758*00b67f09SDavid van Moolenbroek 
759*00b67f09SDavid van Moolenbroek 	while (! T5_startflag) {
760*00b67f09SDavid van Moolenbroek 		(void) isc_condition_wait(&T5_cv, &T5_mx);
761*00b67f09SDavid van Moolenbroek 	}
762*00b67f09SDavid van Moolenbroek 
763*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_unlock(&T5_mx);
764*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
765*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_unlock failed %s\n",
766*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
767*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
768*00b67f09SDavid van Moolenbroek 	}
769*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
770*00b67f09SDavid van Moolenbroek }
771*00b67f09SDavid van Moolenbroek 
772*00b67f09SDavid van Moolenbroek static void
t5_tick_event(isc_task_t * task,isc_event_t * event)773*00b67f09SDavid van Moolenbroek t5_tick_event(isc_task_t *task, isc_event_t *event) {
774*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
775*00b67f09SDavid van Moolenbroek 	isc_time_t	expires;
776*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
777*00b67f09SDavid van Moolenbroek 
778*00b67f09SDavid van Moolenbroek 	UNUSED(task);
779*00b67f09SDavid van Moolenbroek 
780*00b67f09SDavid van Moolenbroek 	++T5_eventcnt;
781*00b67f09SDavid van Moolenbroek 	t_info("t5_tick_event %d\n", T5_eventcnt);
782*00b67f09SDavid van Moolenbroek 
783*00b67f09SDavid van Moolenbroek 	/*
784*00b67f09SDavid van Moolenbroek 	 * On the first tick, purge all remaining tick events
785*00b67f09SDavid van Moolenbroek 	 * and then shut down the task.
786*00b67f09SDavid van Moolenbroek 	 */
787*00b67f09SDavid van Moolenbroek 	if (T5_eventcnt == 1) {
788*00b67f09SDavid van Moolenbroek 		isc_time_settoepoch(&expires);
789*00b67f09SDavid van Moolenbroek 		isc_interval_set(&interval, T5_SECONDS, 0);
790*00b67f09SDavid van Moolenbroek 		isc_result = isc_timer_reset(T5_tickertimer,
791*00b67f09SDavid van Moolenbroek 					     isc_timertype_ticker, &expires,
792*00b67f09SDavid van Moolenbroek 					     &interval, ISC_TRUE);
793*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
794*00b67f09SDavid van Moolenbroek 			t_info("isc_timer_reset failed %s\n",
795*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
796*00b67f09SDavid van Moolenbroek 			++T5_nfails;
797*00b67f09SDavid van Moolenbroek 		}
798*00b67f09SDavid van Moolenbroek 		isc_task_shutdown(task);
799*00b67f09SDavid van Moolenbroek 	}
800*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
801*00b67f09SDavid van Moolenbroek }
802*00b67f09SDavid van Moolenbroek 
803*00b67f09SDavid van Moolenbroek static void
t5_once_event(isc_task_t * task,isc_event_t * event)804*00b67f09SDavid van Moolenbroek t5_once_event(isc_task_t *task, isc_event_t *event) {
805*00b67f09SDavid van Moolenbroek 
806*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
807*00b67f09SDavid van Moolenbroek 
808*00b67f09SDavid van Moolenbroek 	t_info("t5_once_event\n");
809*00b67f09SDavid van Moolenbroek 
810*00b67f09SDavid van Moolenbroek 	/*
811*00b67f09SDavid van Moolenbroek 	 * Allow task1 to start processing events.
812*00b67f09SDavid van Moolenbroek 	 */
813*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_lock(&T5_mx);
814*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
815*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_lock failed %s\n",
816*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
817*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
818*00b67f09SDavid van Moolenbroek 	}
819*00b67f09SDavid van Moolenbroek 
820*00b67f09SDavid van Moolenbroek 	T5_startflag = 1;
821*00b67f09SDavid van Moolenbroek 
822*00b67f09SDavid van Moolenbroek 	isc_result = isc_condition_broadcast(&T5_cv);
823*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
824*00b67f09SDavid van Moolenbroek 		t_info("isc_condition_broadcast failed %s\n",
825*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
826*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
827*00b67f09SDavid van Moolenbroek 	}
828*00b67f09SDavid van Moolenbroek 
829*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_unlock(&T5_mx);
830*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
831*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_unlock failed %s\n",
832*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
833*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
834*00b67f09SDavid van Moolenbroek 	}
835*00b67f09SDavid van Moolenbroek 
836*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
837*00b67f09SDavid van Moolenbroek 	isc_task_shutdown(task);
838*00b67f09SDavid van Moolenbroek }
839*00b67f09SDavid van Moolenbroek 
840*00b67f09SDavid van Moolenbroek static void
t5_shutdown_event(isc_task_t * task,isc_event_t * event)841*00b67f09SDavid van Moolenbroek t5_shutdown_event(isc_task_t *task, isc_event_t *event) {
842*00b67f09SDavid van Moolenbroek 
843*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
844*00b67f09SDavid van Moolenbroek 
845*00b67f09SDavid van Moolenbroek 	UNUSED(task);
846*00b67f09SDavid van Moolenbroek 	UNUSED(event);
847*00b67f09SDavid van Moolenbroek 
848*00b67f09SDavid van Moolenbroek 	t_info("t5_shutdown_event\n");
849*00b67f09SDavid van Moolenbroek 
850*00b67f09SDavid van Moolenbroek 	/*
851*00b67f09SDavid van Moolenbroek 	 * Signal shutdown processing complete.
852*00b67f09SDavid van Moolenbroek 	 */
853*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_lock(&T5_mx);
854*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
855*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_lock failed %s\n",
856*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
857*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
858*00b67f09SDavid van Moolenbroek 	}
859*00b67f09SDavid van Moolenbroek 
860*00b67f09SDavid van Moolenbroek 	T5_shutdownflag = 1;
861*00b67f09SDavid van Moolenbroek 
862*00b67f09SDavid van Moolenbroek 	isc_result = isc_condition_signal(&T5_cv);
863*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
864*00b67f09SDavid van Moolenbroek 		t_info("isc_condition_signal failed %s\n",
865*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
866*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
867*00b67f09SDavid van Moolenbroek 	}
868*00b67f09SDavid van Moolenbroek 
869*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_unlock(&T5_mx);
870*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
871*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_unlock failed %s\n",
872*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
873*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
874*00b67f09SDavid van Moolenbroek 	}
875*00b67f09SDavid van Moolenbroek 	isc_event_free(&event);
876*00b67f09SDavid van Moolenbroek }
877*00b67f09SDavid van Moolenbroek 
878*00b67f09SDavid van Moolenbroek static int
t_timers5(void)879*00b67f09SDavid van Moolenbroek t_timers5(void) {
880*00b67f09SDavid van Moolenbroek 	char		*p;
881*00b67f09SDavid van Moolenbroek 	int		result;
882*00b67f09SDavid van Moolenbroek 	isc_mem_t	*mctx;
883*00b67f09SDavid van Moolenbroek 	isc_taskmgr_t	*tmgr;
884*00b67f09SDavid van Moolenbroek 	unsigned int	workers;
885*00b67f09SDavid van Moolenbroek 	isc_result_t	isc_result;
886*00b67f09SDavid van Moolenbroek 	isc_timermgr_t	*timermgr;
887*00b67f09SDavid van Moolenbroek 	isc_event_t	*event;
888*00b67f09SDavid van Moolenbroek 	isc_time_t	expires;
889*00b67f09SDavid van Moolenbroek 	isc_interval_t	interval;
890*00b67f09SDavid van Moolenbroek 
891*00b67f09SDavid van Moolenbroek 	T5_startflag = 0;
892*00b67f09SDavid van Moolenbroek 	T5_shutdownflag = 0;
893*00b67f09SDavid van Moolenbroek 	T5_eventcnt = 0;
894*00b67f09SDavid van Moolenbroek 
895*00b67f09SDavid van Moolenbroek 	workers = 2;
896*00b67f09SDavid van Moolenbroek 	p = t_getenv("ISC_TASK_WORKERS");
897*00b67f09SDavid van Moolenbroek 	if (p != NULL)
898*00b67f09SDavid van Moolenbroek 		workers = atoi(p);
899*00b67f09SDavid van Moolenbroek 
900*00b67f09SDavid van Moolenbroek 	mctx = NULL;
901*00b67f09SDavid van Moolenbroek 	isc_result = isc_mem_create(0, 0, &mctx);
902*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
903*00b67f09SDavid van Moolenbroek 		t_info("isc_mem_create failed %s\n",
904*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
905*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
906*00b67f09SDavid van Moolenbroek 	}
907*00b67f09SDavid van Moolenbroek 
908*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_init(&T5_mx);
909*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
910*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_init failed %s\n",
911*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
912*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
913*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
914*00b67f09SDavid van Moolenbroek 	}
915*00b67f09SDavid van Moolenbroek 
916*00b67f09SDavid van Moolenbroek 	isc_result = isc_condition_init(&T5_cv);
917*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
918*00b67f09SDavid van Moolenbroek 		t_info("isc_condition_init failed %s\n",
919*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
920*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
921*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
922*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
923*00b67f09SDavid van Moolenbroek 	}
924*00b67f09SDavid van Moolenbroek 
925*00b67f09SDavid van Moolenbroek 	tmgr = NULL;
926*00b67f09SDavid van Moolenbroek 	isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr);
927*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
928*00b67f09SDavid van Moolenbroek 		t_info("isc_taskmgr_create failed %s\n",
929*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
930*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
931*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
932*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
933*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
934*00b67f09SDavid van Moolenbroek 	}
935*00b67f09SDavid van Moolenbroek 
936*00b67f09SDavid van Moolenbroek 	timermgr = NULL;
937*00b67f09SDavid van Moolenbroek 	isc_result = isc_timermgr_create(mctx, &timermgr);
938*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
939*00b67f09SDavid van Moolenbroek 		t_info("isc_timermgr_create failed %s\n",
940*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
941*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
942*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
943*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
944*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
945*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
946*00b67f09SDavid van Moolenbroek 	}
947*00b67f09SDavid van Moolenbroek 
948*00b67f09SDavid van Moolenbroek 	T5_task1 = NULL;
949*00b67f09SDavid van Moolenbroek 	isc_result = isc_task_create(tmgr, 0, &T5_task1);
950*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
951*00b67f09SDavid van Moolenbroek 		t_info("isc_task_create failed %s\n",
952*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
953*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
954*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
955*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
956*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
957*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
958*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
959*00b67f09SDavid van Moolenbroek 	}
960*00b67f09SDavid van Moolenbroek 
961*00b67f09SDavid van Moolenbroek 	isc_result = isc_task_onshutdown(T5_task1, t5_shutdown_event, NULL);
962*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
963*00b67f09SDavid van Moolenbroek 		t_info("isc_task_onshutdown failed %s\n",
964*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
965*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
966*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&T5_task1);
967*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
968*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
969*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
970*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
971*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
972*00b67f09SDavid van Moolenbroek 	}
973*00b67f09SDavid van Moolenbroek 
974*00b67f09SDavid van Moolenbroek 	T5_task2 = NULL;
975*00b67f09SDavid van Moolenbroek 	isc_result = isc_task_create(tmgr, 0, &T5_task2);
976*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
977*00b67f09SDavid van Moolenbroek 		t_info("isc_task_create failed %s\n",
978*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
979*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
980*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&T5_task1);
981*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
982*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
983*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
984*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
985*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
986*00b67f09SDavid van Moolenbroek 	}
987*00b67f09SDavid van Moolenbroek 
988*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_lock(&T5_mx);
989*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
990*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_lock failed %s\n",
991*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
992*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
993*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
994*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
995*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
996*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
997*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
998*00b67f09SDavid van Moolenbroek 	}
999*00b67f09SDavid van Moolenbroek 
1000*00b67f09SDavid van Moolenbroek 	event = isc_event_allocate(mctx, (void *)1 , (isc_eventtype_t)1,
1001*00b67f09SDavid van Moolenbroek 				   t5_start_event, NULL, sizeof(*event));
1002*00b67f09SDavid van Moolenbroek 	isc_task_send(T5_task1, &event);
1003*00b67f09SDavid van Moolenbroek 
1004*00b67f09SDavid van Moolenbroek 	isc_time_settoepoch(&expires);
1005*00b67f09SDavid van Moolenbroek 	isc_interval_set(&interval, T5_SECONDS, 0);
1006*00b67f09SDavid van Moolenbroek 
1007*00b67f09SDavid van Moolenbroek 	T5_tickertimer = NULL;
1008*00b67f09SDavid van Moolenbroek 	isc_result = isc_timer_create(timermgr, isc_timertype_ticker,
1009*00b67f09SDavid van Moolenbroek 				      &expires, &interval, T5_task1,
1010*00b67f09SDavid van Moolenbroek 				      t5_tick_event, NULL, &T5_tickertimer);
1011*00b67f09SDavid van Moolenbroek 
1012*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
1013*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
1014*00b67f09SDavid van Moolenbroek 		(void) isc_condition_signal(&T5_cv);
1015*00b67f09SDavid van Moolenbroek 		(void) isc_mutex_unlock(&T5_mx);
1016*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&T5_task1);
1017*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&T5_task2);
1018*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
1019*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
1020*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
1021*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
1022*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
1023*00b67f09SDavid van Moolenbroek 	}
1024*00b67f09SDavid van Moolenbroek 
1025*00b67f09SDavid van Moolenbroek 	T5_oncetimer = NULL;
1026*00b67f09SDavid van Moolenbroek 	isc_interval_set(&interval, (T5_SECONDS * T5_NTICKS) + 2, 0);
1027*00b67f09SDavid van Moolenbroek 	isc_result = isc_time_nowplusinterval(&expires, &interval);
1028*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
1029*00b67f09SDavid van Moolenbroek 		isc_timer_detach(&T5_tickertimer);
1030*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
1031*00b67f09SDavid van Moolenbroek 		(void)isc_condition_signal(&T5_cv);
1032*00b67f09SDavid van Moolenbroek 		(void)isc_mutex_unlock(&T5_mx);
1033*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&T5_task1);
1034*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&T5_task2);
1035*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
1036*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
1037*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
1038*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
1039*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
1040*00b67f09SDavid van Moolenbroek 	}
1041*00b67f09SDavid van Moolenbroek 
1042*00b67f09SDavid van Moolenbroek 	isc_interval_set(&interval, 0, 0);
1043*00b67f09SDavid van Moolenbroek 	isc_result = isc_timer_create(timermgr, isc_timertype_once,
1044*00b67f09SDavid van Moolenbroek 				      &expires, &interval, T5_task2,
1045*00b67f09SDavid van Moolenbroek 				      t5_once_event, NULL, &T5_oncetimer);
1046*00b67f09SDavid van Moolenbroek 
1047*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
1048*00b67f09SDavid van Moolenbroek 		isc_timer_detach(&T5_tickertimer);
1049*00b67f09SDavid van Moolenbroek 		isc_timermgr_destroy(&timermgr);
1050*00b67f09SDavid van Moolenbroek 		(void) isc_condition_signal(&T5_cv);
1051*00b67f09SDavid van Moolenbroek 		(void) isc_mutex_unlock(&T5_mx);
1052*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&T5_task1);
1053*00b67f09SDavid van Moolenbroek 		isc_task_destroy(&T5_task2);
1054*00b67f09SDavid van Moolenbroek 		isc_taskmgr_destroy(&tmgr);
1055*00b67f09SDavid van Moolenbroek 		DESTROYLOCK(&T5_mx);
1056*00b67f09SDavid van Moolenbroek 		(void) isc_condition_destroy(&T5_cv);
1057*00b67f09SDavid van Moolenbroek 		isc_mem_destroy(&mctx);
1058*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
1059*00b67f09SDavid van Moolenbroek 		return(T_UNRESOLVED);
1060*00b67f09SDavid van Moolenbroek 	}
1061*00b67f09SDavid van Moolenbroek 
1062*00b67f09SDavid van Moolenbroek 	/*
1063*00b67f09SDavid van Moolenbroek 	 * Wait for shutdown processing to complete.
1064*00b67f09SDavid van Moolenbroek 	 */
1065*00b67f09SDavid van Moolenbroek 	while (! T5_shutdownflag) {
1066*00b67f09SDavid van Moolenbroek 		isc_result = isc_condition_wait(&T5_cv, &T5_mx);
1067*00b67f09SDavid van Moolenbroek 		if (isc_result != ISC_R_SUCCESS) {
1068*00b67f09SDavid van Moolenbroek 			t_info("isc_condition_waituntil failed %s\n",
1069*00b67f09SDavid van Moolenbroek 			       isc_result_totext(isc_result));
1070*00b67f09SDavid van Moolenbroek 			++T5_nprobs;
1071*00b67f09SDavid van Moolenbroek 		}
1072*00b67f09SDavid van Moolenbroek 	}
1073*00b67f09SDavid van Moolenbroek 
1074*00b67f09SDavid van Moolenbroek 	isc_result = isc_mutex_unlock(&T5_mx);
1075*00b67f09SDavid van Moolenbroek 	if (isc_result != ISC_R_SUCCESS) {
1076*00b67f09SDavid van Moolenbroek 		t_info("isc_mutex_unlock failed %s\n",
1077*00b67f09SDavid van Moolenbroek 		       isc_result_totext(isc_result));
1078*00b67f09SDavid van Moolenbroek 		++T5_nprobs;
1079*00b67f09SDavid van Moolenbroek 	}
1080*00b67f09SDavid van Moolenbroek 
1081*00b67f09SDavid van Moolenbroek 	if (T5_eventcnt != 1) {
1082*00b67f09SDavid van Moolenbroek 		t_info("processed %d events\n", T5_eventcnt);
1083*00b67f09SDavid van Moolenbroek 		++T5_nfails;
1084*00b67f09SDavid van Moolenbroek 	}
1085*00b67f09SDavid van Moolenbroek 
1086*00b67f09SDavid van Moolenbroek 	isc_timer_detach(&T5_tickertimer);
1087*00b67f09SDavid van Moolenbroek 	isc_timer_detach(&T5_oncetimer);
1088*00b67f09SDavid van Moolenbroek 	isc_timermgr_destroy(&timermgr);
1089*00b67f09SDavid van Moolenbroek 	isc_task_destroy(&T5_task1);
1090*00b67f09SDavid van Moolenbroek 	isc_task_destroy(&T5_task2);
1091*00b67f09SDavid van Moolenbroek 	isc_taskmgr_destroy(&tmgr);
1092*00b67f09SDavid van Moolenbroek 	DESTROYLOCK(&T5_mx);
1093*00b67f09SDavid van Moolenbroek 	(void) isc_condition_destroy(&T5_cv);
1094*00b67f09SDavid van Moolenbroek 	isc_mem_destroy(&mctx);
1095*00b67f09SDavid van Moolenbroek 
1096*00b67f09SDavid van Moolenbroek 	result = T_UNRESOLVED;
1097*00b67f09SDavid van Moolenbroek 
1098*00b67f09SDavid van Moolenbroek 	if ((T5_nfails == 0) && (T5_nprobs == 0))
1099*00b67f09SDavid van Moolenbroek 		result = T_PASS;
1100*00b67f09SDavid van Moolenbroek 	else if (T5_nfails)
1101*00b67f09SDavid van Moolenbroek 		result = T_FAIL;
1102*00b67f09SDavid van Moolenbroek 
1103*00b67f09SDavid van Moolenbroek 	return (result);
1104*00b67f09SDavid van Moolenbroek }
1105*00b67f09SDavid van Moolenbroek 
1106*00b67f09SDavid van Moolenbroek static const char *a5 =
1107*00b67f09SDavid van Moolenbroek 	"When 'purge' is TRUE, a call to isc_timer_reset() purges any pending "
1108*00b67f09SDavid van Moolenbroek 	"events from 'timer' from the task's event queue.";
1109*00b67f09SDavid van Moolenbroek 
1110*00b67f09SDavid van Moolenbroek static void
t5(void)1111*00b67f09SDavid van Moolenbroek t5(void) {
1112*00b67f09SDavid van Moolenbroek 	t_assert("isc_timer_reset", 5, T_REQUIRED, "%s", a5);
1113*00b67f09SDavid van Moolenbroek 
1114*00b67f09SDavid van Moolenbroek 	if (threaded)
1115*00b67f09SDavid van Moolenbroek 		t_result(t_timers5());
1116*00b67f09SDavid van Moolenbroek 	else
1117*00b67f09SDavid van Moolenbroek 		require_threads();
1118*00b67f09SDavid van Moolenbroek }
1119*00b67f09SDavid van Moolenbroek 
1120*00b67f09SDavid van Moolenbroek testspec_t	T_testlist[] = {
1121*00b67f09SDavid van Moolenbroek 	{	(PFV) t1,		"timer_create"		},
1122*00b67f09SDavid van Moolenbroek 	{	(PFV) t2,		"timer_create"		},
1123*00b67f09SDavid van Moolenbroek 	{	(PFV) t3,		"timer_create"		},
1124*00b67f09SDavid van Moolenbroek 	{	(PFV) t4,		"timer_reset"		},
1125*00b67f09SDavid van Moolenbroek 	{	(PFV) t5,		"timer_reset"		},
1126*00b67f09SDavid van Moolenbroek 	{	(PFV) NULL,		NULL			}
1127*00b67f09SDavid van Moolenbroek };
1128*00b67f09SDavid van Moolenbroek 
1129*00b67f09SDavid van Moolenbroek #ifdef WIN32
1130*00b67f09SDavid van Moolenbroek int
main(int argc,char ** argv)1131*00b67f09SDavid van Moolenbroek main(int argc, char **argv) {
1132*00b67f09SDavid van Moolenbroek 	t_settests(T_testlist);
1133*00b67f09SDavid van Moolenbroek 	return (t_main(argc, argv));
1134*00b67f09SDavid van Moolenbroek }
1135*00b67f09SDavid van Moolenbroek #endif
1136