/* * Copyright (C) 1999, 2000 Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define Tx_FUDGE_SECONDS 0 /* in absence of clock_getres() */ #define Tx_FUDGE_NANOSECONDS 500000000 /* in absence of clock_getres() */ static isc_time_t Tx_endtime; static isc_time_t Tx_lasttime; static int Tx_shutdownflag; static int Tx_eventcnt; static int Tx_nevents; static isc_mutex_t Tx_mx; static isc_condition_t Tx_cv; static int Tx_nfails; static int Tx_nprobs; static isc_timer_t *Tx_timer; static int Tx_seconds; static int Tx_nanoseconds; static void tx_sde(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; task = task; event = event; /* signal shutdown processing complete */ isc_result = isc_mutex_lock(&Tx_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } isc_result = isc_condition_signal(&Tx_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_signal failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } isc_result = isc_mutex_unlock(&Tx_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } isc_event_free(&event); } static void tx_te(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; isc_time_t now; isc_time_t base; isc_time_t ulim; isc_time_t llim; isc_interval_t interval; isc_eventtype_t expected_event_type; ++Tx_eventcnt; t_info("tick %d\n", Tx_eventcnt); expected_event_type = ISC_TIMEREVENT_LIFE; if ((isc_timertype_t) event->arg == isc_timertype_ticker) expected_event_type = ISC_TIMEREVENT_TICK; if (event->type != expected_event_type) { t_info("expected event type %d, got %d\n", expected_event_type, (int) event->type); ++Tx_nfails; } isc_result = isc_time_now(&now); if (isc_result == ISC_R_SUCCESS) { interval.seconds = Tx_seconds; interval.nanoseconds = Tx_nanoseconds; isc_time_add(&Tx_lasttime, &interval, &base); interval.seconds = Tx_FUDGE_SECONDS; interval.nanoseconds = Tx_FUDGE_NANOSECONDS; isc_time_add(&base, &interval, &ulim); isc_time_subtract(&base, &interval, &llim); if ((isc_time_compare(&llim, &now) > 0) || (isc_time_compare(&ulim, &now) < 0)) { t_info("timer range error\n"); ++Tx_nfails; } Tx_lasttime = now; } else { t_info("isc_time_now failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } if (Tx_eventcnt == Tx_nevents) { isc_result = isc_time_now(&Tx_endtime); if (isc_result != ISC_R_SUCCESS) { t_info("isc_time_now failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } isc_timer_detach(&Tx_timer); isc_task_shutdown(task); } isc_event_free(&event); } 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 *)) { char *p; isc_mem_t *mctx; isc_taskmgr_t *tmgr; isc_task_t *task; unsigned int workers; isc_result_t isc_result; isc_timermgr_t *timermgr; Tx_shutdownflag = 0; Tx_eventcnt = 0; isc_time_settoepoch(&Tx_endtime); workers = 2; p = t_getenv("ISC_TASK_WORKERS"); if (p != NULL) workers = atoi(p); mctx = NULL; isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; return; } isc_result = isc_mutex_init(&Tx_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_init failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } isc_result = isc_condition_init(&Tx_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_init failed %s\n", isc_result_totext(isc_result)); isc_mutex_destroy(&Tx_mx); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } tmgr = NULL; isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr); if (isc_result != ISC_R_SUCCESS) { t_info("isc_taskmgr_create failed %s\n", isc_result_totext(isc_result)); isc_mutex_destroy(&Tx_mx); isc_condition_destroy(&Tx_cv); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } timermgr = NULL; isc_result = isc_timermgr_create(mctx, &timermgr); if (isc_result != ISC_R_SUCCESS) { t_info("isc_timermgr_create failed %s\n", isc_result_totext(isc_result)); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&Tx_mx); isc_condition_destroy(&Tx_cv); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } isc_mutex_lock(&Tx_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); isc_timermgr_destroy(&timermgr); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&Tx_mx); isc_condition_destroy(&Tx_cv); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } task = NULL; isc_result = isc_task_create(tmgr, mctx, 0, &task); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %s\n", isc_result_totext(isc_result)); isc_timermgr_destroy(&timermgr); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&Tx_mx); isc_condition_destroy(&Tx_cv); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } isc_result = isc_task_onshutdown(task, tx_sde, NULL); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_onshutdown failed %s\n", isc_result_totext(isc_result)); isc_timermgr_destroy(&timermgr); isc_task_destroy(&task); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&Tx_mx); isc_condition_destroy(&Tx_cv); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } isc_result = isc_time_now(&Tx_lasttime); if (isc_result != ISC_R_SUCCESS) { isc_timermgr_destroy(&timermgr); isc_task_destroy(&task); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&Tx_mx); isc_condition_destroy(&Tx_cv); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } Tx_timer = NULL; isc_result = isc_timer_create( timermgr, timertype, expires, interval, task, action, (void *) timertype, &Tx_timer); if (isc_result != ISC_R_SUCCESS) { isc_timermgr_destroy(&timermgr); isc_task_destroy(&task); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&Tx_mx); isc_condition_destroy(&Tx_cv); isc_mem_destroy(&mctx); ++Tx_nprobs; return; } /* wait for shutdown processing to complete */ while (Tx_eventcnt != Tx_nevents) { isc_result = isc_condition_wait(&Tx_cv, &Tx_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_waituntil failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } } isc_result = isc_mutex_unlock(&Tx_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } isc_task_detach(&task); isc_taskmgr_destroy(&tmgr); isc_timermgr_destroy(&timermgr); isc_mutex_destroy(&Tx_mx); isc_condition_destroy(&Tx_cv); isc_mem_destroy(&mctx); } #define T1_SECONDS 2 #define T1_NANOSECONDS 500000000 static char *a1 = "When type is isc_timertype_ticker, a call to isc_timer_create() creates " "a timer that posts an ISC_TIMEREVENT_TICK event to the specified " "task every 'interval' seconds and returns ISC_R_SUCCESS."; static void t1() { int result; isc_time_t expires; isc_interval_t interval; t_assert("isc_timer_create", 1, T_REQUIRED, a1); Tx_nfails = 0; Tx_nprobs = 0; Tx_nevents = 12; Tx_seconds = T1_SECONDS; Tx_nanoseconds = T1_NANOSECONDS; isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds); isc_time_settoepoch(&expires); t_timers_x(isc_timertype_ticker, &expires, &interval, tx_te); result = T_UNRESOLVED; if ((Tx_nfails == 0) && (Tx_nprobs == 0)) result = T_PASS; else if (Tx_nfails) result = T_FAIL; t_result(result); } #define T2_SECONDS 5 #define T2_NANOSECONDS 300000000; static char *a2 = "When type is isc_timertype_once, a call to isc_timer_create() creates " "a timer that posts an ISC_TIMEEVENT_LIFE event to the specified " "task when the current time reaches or exceeds the time specified by 'expires'."; static void t2() { int result; int isc_result; isc_time_t expires; isc_interval_t interval; t_assert("isc_timer_create", 2, T_REQUIRED, a2); Tx_nfails = 0; Tx_nprobs = 0; Tx_nevents = 1; Tx_seconds = T2_SECONDS; Tx_nanoseconds = T2_NANOSECONDS; isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds); isc_result = isc_time_nowplusinterval(&expires, &interval); if (isc_result == ISC_R_SUCCESS) { isc_interval_set(&interval, 0, 0); t_timers_x(isc_timertype_once, &expires, &interval, tx_te); } else { t_info("isc_time_nowplusinterval failed %s\n", isc_result_totext(isc_result)); } result = T_UNRESOLVED; if ((Tx_nfails == 0) && (Tx_nprobs == 0)) result = T_PASS; else if (Tx_nfails) result = T_FAIL; t_result(result); } static void t3_te(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; isc_time_t now; isc_time_t base; isc_time_t ulim; isc_time_t llim; isc_interval_t interval; ++Tx_eventcnt; t_info("tick %d\n", Tx_eventcnt); isc_result = isc_time_now(&now); if (isc_result == ISC_R_SUCCESS) { interval.seconds = Tx_seconds; interval.nanoseconds = Tx_nanoseconds; isc_time_add(&Tx_lasttime, &interval, &base); interval.seconds = Tx_FUDGE_SECONDS; interval.nanoseconds = Tx_FUDGE_NANOSECONDS; isc_time_add(&base, &interval, &ulim); isc_time_subtract(&base, &interval, &llim); if ((isc_time_compare(&llim, &now) > 0) || (isc_time_compare(&ulim, &now) < 0)) { t_info("timer range error\n"); ++Tx_nfails; } Tx_lasttime = now; } else { t_info("isc_time_now failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } if (event->type != ISC_TIMEREVENT_IDLE) { t_info("received event type %d, expected type %d\n", event->type, ISC_TIMEREVENT_IDLE); ++Tx_nfails; } isc_timer_detach(&Tx_timer); isc_task_shutdown(task); isc_event_free(&event); } #define T3_SECONDS 4 #define T3_NANOSECONDS 400000000 static char *a3 = "When type is isc_timertype_once, a call to isc_timer_create() creates " "a timer that posts an ISC_TIMEEVENT_IDLE event to the specified " "task when the timer has been idle for 'interval' seconds."; static void t3() { int result; int isc_result; isc_time_t expires; isc_interval_t interval; t_assert("isc_timer_create", 3, T_REQUIRED, a3); Tx_nfails = 0; Tx_nprobs = 0; Tx_nevents = 1; Tx_seconds = T3_SECONDS; Tx_nanoseconds = T3_NANOSECONDS; isc_interval_set(&interval, Tx_seconds + 1, Tx_nanoseconds); isc_result = isc_time_nowplusinterval(&expires, &interval); if (isc_result == ISC_R_SUCCESS) { isc_interval_set(&interval, Tx_seconds, Tx_nanoseconds); t_timers_x(isc_timertype_once, &expires, &interval, t3_te); } else { t_info("isc_time_nowplusinterval failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } result = T_UNRESOLVED; if ((Tx_nfails == 0) && (Tx_nprobs == 0)) result = T_PASS; else if (Tx_nfails) result = T_FAIL; t_result(result); } #define T4_SECONDS 2 #define T4_NANOSECONDS 500000000 static void t4_te(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; isc_time_t now; isc_time_t base; isc_time_t ulim; isc_time_t llim; isc_time_t expires; isc_interval_t interval; ++Tx_eventcnt; t_info("tick %d\n", Tx_eventcnt); /* check expired time */ isc_result = isc_time_now(&now); if (isc_result == ISC_R_SUCCESS) { interval.seconds = Tx_seconds; interval.nanoseconds = Tx_nanoseconds; isc_time_add(&Tx_lasttime, &interval, &base); interval.seconds = Tx_FUDGE_SECONDS; interval.nanoseconds = Tx_FUDGE_NANOSECONDS; isc_time_add(&base, &interval, &ulim); isc_time_subtract(&base, &interval, &llim); if ((isc_time_compare(&llim, &now) > 0) || (isc_time_compare(&ulim, &now) < 0)) { t_info("timer range error\n"); ++Tx_nfails; } Tx_lasttime = now; } else { t_info("isc_time_now failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } if (Tx_eventcnt < 3) { if (event->type != ISC_TIMEREVENT_TICK) { t_info("received event type %d, expected type %d\n", event->type, ISC_TIMEREVENT_IDLE); ++Tx_nfails; } if (Tx_eventcnt == 2) { isc_interval_set(&interval, T4_SECONDS, T4_NANOSECONDS); isc_result = isc_time_nowplusinterval(&expires, &interval); if (isc_result == ISC_R_SUCCESS) { isc_interval_set(&interval, 0, 0); isc_result = isc_timer_reset(Tx_timer, isc_timertype_once, &expires, &interval, ISC_FALSE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_timer_reset failed %s\n", isc_result_totext(isc_result)); ++Tx_nfails; } } else { t_info("isc_time_nowplusinterval failed %s\n", isc_result_totext(isc_result)); ++Tx_nprobs; } } } else { if (event->type != ISC_TIMEREVENT_LIFE) { t_info("received event type %d, expected type %d\n", event->type, ISC_TIMEREVENT_IDLE); ++Tx_nfails; } isc_timer_detach(&Tx_timer); isc_task_shutdown(task); } isc_event_free(&event); } static char *a4 = "A call to isc_timer_reset() changes the timer's type, expires and " "interval values to the given values."; static void t4() { int result; isc_time_t expires; isc_interval_t interval; Tx_nfails = 0; Tx_nprobs = 0; Tx_nevents = 3; Tx_seconds = T4_SECONDS; Tx_nanoseconds = T4_NANOSECONDS; t_assert("isc_timer_reset", 4, T_REQUIRED, a4); isc_interval_set(&interval, T4_SECONDS, T4_NANOSECONDS); isc_time_settoepoch(&expires); t_timers_x(isc_timertype_ticker, &expires, &interval, t4_te); result = T_UNRESOLVED; if ((Tx_nfails == 0) && (Tx_nprobs == 0)) result = T_PASS; else if (Tx_nfails) result = T_FAIL; t_result(result); } #define T5_NTICKS 4 #define T5_SECONDS 3 static int T5_startflag; static int T5_shutdownflag; static int T5_eventcnt; static isc_mutex_t T5_mx; static isc_condition_t T5_cv; static int T5_nfails; static int T5_nprobs; static isc_timer_t *T5_tickertimer; static isc_timer_t *T5_oncetimer; static isc_task_t *T5_task1; static isc_task_t *T5_task2; /* * T5_task1 blocks on T5_mx while events accumulate * in it's queue, until signaled by T5_task2 */ static void t5_start_event(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; task = task; t_info("t5_start_event\n"); isc_result = isc_mutex_lock(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } while (! T5_startflag) { (void) isc_condition_wait(&T5_cv, &T5_mx); } isc_result = isc_mutex_unlock(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } isc_event_free(&event); } static void t5_tick_event(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; isc_time_t expires; isc_interval_t interval; task = task; ++T5_eventcnt; t_info("t5_tick_event %d\n", T5_eventcnt); /* * on the first tick, purge all remaining tick events * and then shut down the task */ if (T5_eventcnt == 1) { isc_time_settoepoch(&expires); isc_interval_set(&interval, T5_SECONDS, 0); isc_result = isc_timer_reset(T5_tickertimer, isc_timertype_ticker, &expires, &interval, ISC_TRUE); if (isc_result != ISC_R_SUCCESS) { t_info("isc_timer_reset failed %d\n", isc_result_totext(isc_result)); ++T5_nfails; } isc_task_shutdown(task); } isc_event_free(&event); } static void t5_once_event(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; t_info("t5_once_event\n"); /* * allow task1 to start processing events */ isc_result = isc_mutex_lock(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } T5_startflag = 1; isc_result = isc_condition_broadcast(&T5_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_broadcast failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } isc_result = isc_mutex_unlock(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } isc_event_free(&event); isc_task_shutdown(task); } static void t5_shutdown_event(isc_task_t *task, isc_event_t *event) { isc_result_t isc_result; task = task; event = event; t_info("t5_shutdown_event\n"); /* * signal shutdown processing complete */ isc_result = isc_mutex_lock(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } T5_shutdownflag = 1; isc_result = isc_condition_signal(&T5_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_signal failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } isc_result = isc_mutex_unlock(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } isc_event_free(&event); } static int t_timers5() { char *p; int result; isc_mem_t *mctx; isc_taskmgr_t *tmgr; unsigned int workers; isc_result_t isc_result; isc_timermgr_t *timermgr; isc_event_t *event; isc_time_t expires; isc_interval_t interval; T5_startflag = 0; T5_shutdownflag = 0; T5_eventcnt = 0; workers = 2; p = t_getenv("ISC_TASK_WORKERS"); if (p != NULL) workers = atoi(p); mctx = NULL; isc_result = isc_mem_create(0, 0, &mctx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mem_create failed %s\n", isc_result_totext(isc_result)); return(T_UNRESOLVED); } isc_result = isc_mutex_init(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_init failed %s\n", isc_result_totext(isc_result)); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_condition_init(&T5_cv); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_init failed %s\n", isc_result_totext(isc_result)); isc_mutex_destroy(&T5_mx); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } tmgr = NULL; isc_result = isc_taskmgr_create(mctx, workers, 0, &tmgr); if (isc_result != ISC_R_SUCCESS) { t_info("isc_taskmgr_create failed %s\n", isc_result_totext(isc_result)); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } timermgr = NULL; isc_result = isc_timermgr_create(mctx, &timermgr); if (isc_result != ISC_R_SUCCESS) { t_info("isc_timermgr_create failed %s\n", isc_result_totext(isc_result)); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } T5_task1 = NULL; isc_result = isc_task_create(tmgr, mctx, 0, &T5_task1); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %s\n", isc_result_totext(isc_result)); isc_timermgr_destroy(&timermgr); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_task_onshutdown(T5_task1, t5_shutdown_event, NULL); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_onshutdown failed %s\n", isc_result_totext(isc_result)); isc_timermgr_destroy(&timermgr); isc_task_destroy(&T5_task1); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } T5_task2 = NULL; isc_result = isc_task_create(tmgr, mctx, 0, &T5_task2); if (isc_result != ISC_R_SUCCESS) { t_info("isc_task_create failed %s\n", isc_result_totext(isc_result)); isc_timermgr_destroy(&timermgr); isc_task_destroy(&T5_task1); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_result = isc_mutex_lock(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_lock failed %s\n", isc_result_totext(isc_result)); isc_timermgr_destroy(&timermgr); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } event = isc_event_allocate(mctx, (void *) 1 , (isc_eventtype_t) 1, t5_start_event, NULL, sizeof(*event)); isc_task_send(T5_task1, &event); isc_time_settoepoch(&expires); isc_interval_set(&interval, T5_SECONDS, 0); T5_tickertimer = NULL; isc_result = isc_timer_create( timermgr, isc_timertype_ticker, &expires, &interval, T5_task1, t5_tick_event, NULL, &T5_tickertimer); if (isc_result != ISC_R_SUCCESS) { isc_timermgr_destroy(&timermgr); (void) isc_condition_signal(&T5_cv); (void) isc_mutex_unlock(&T5_mx); isc_task_destroy(&T5_task1); isc_task_destroy(&T5_task2); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } T5_oncetimer = NULL; isc_interval_set(&interval, (T5_SECONDS * T5_NTICKS) + 2, 0); isc_result = isc_time_nowplusinterval(&expires, &interval); if (isc_result != ISC_R_SUCCESS) { isc_timer_detach(&T5_tickertimer); isc_timermgr_destroy(&timermgr); (void) isc_condition_signal(&T5_cv); (void) isc_mutex_unlock(&T5_mx); isc_task_destroy(&T5_task1); isc_task_destroy(&T5_task2); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); return(T_UNRESOLVED); } isc_interval_set(&interval, 0, 0); isc_result = isc_timer_create( timermgr, isc_timertype_once, &expires, &interval, T5_task2, t5_once_event, NULL, &T5_oncetimer); if (isc_result != ISC_R_SUCCESS) { isc_timer_detach(&T5_tickertimer); isc_timermgr_destroy(&timermgr); (void) isc_condition_signal(&T5_cv); (void) isc_mutex_unlock(&T5_mx); isc_task_destroy(&T5_task1); isc_task_destroy(&T5_task2); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); ++T5_nprobs; return(T_UNRESOLVED); } /* wait for shutdown processing to complete */ while (! T5_shutdownflag) { isc_result = isc_condition_wait(&T5_cv, &T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_condition_waituntil failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } } isc_result = isc_mutex_unlock(&T5_mx); if (isc_result != ISC_R_SUCCESS) { t_info("isc_mutex_unlock failed %s\n", isc_result_totext(isc_result)); ++T5_nprobs; } if (T5_eventcnt != 1) { t_info("processed %d events\n", T5_eventcnt); ++T5_nfails; } isc_timer_detach(&T5_tickertimer); isc_timer_detach(&T5_oncetimer); isc_timermgr_destroy(&timermgr); isc_task_destroy(&T5_task1); isc_task_destroy(&T5_task2); isc_taskmgr_destroy(&tmgr); isc_mutex_destroy(&T5_mx); isc_condition_destroy(&T5_cv); isc_mem_destroy(&mctx); result = T_UNRESOLVED; if ((T5_nfails == 0) && (T5_nprobs == 0)) result = T_PASS; else if (T5_nfails) result = T_FAIL; return(result); } static char *a5 = "When 'purge' is TRUE, a call to isc_timer_reset() purges any pending " "events from 'timer' from the task's event queue."; static void t5() { int result; t_assert("isc_timer_reset", 5, T_REQUIRED, a5); result = t_timers5(); t_result(result); } testspec_t T_testlist[] = { { t1, "timer_create" }, { t2, "timer_create" }, { t3, "timer_create" }, { t4, "timer_reset" }, { t5, "timer_reset" }, { NULL, NULL } };