void isc__timer_attach(isc_timer_t *timer0, isc_timer_t **timerp) { isc__timer_t *timer = (isc__timer_t *)timer0; /* * Attach *timerp to timer. */ REQUIRE(VALID_TIMER(timer)); REQUIRE(timerp != NULL && *timerp == NULL); LOCK(&timer->lock); timer->references++; UNLOCK(&timer->lock); *timerp = (isc_timer_t *)timer; }
ISC_TIMERFUNC_SCOPE isc_result_t isc__timer_reset(isc_timer_t *timer0, isc_timertype_t type, isc_time_t *expires, isc_interval_t *interval, isc_boolean_t purge) { isc__timer_t *timer = (isc__timer_t *)timer0; isc_time_t now; isc__timermgr_t *manager; isc_result_t result; /* * Change the timer's type, expires, and interval values to the given * values. If 'purge' is ISC_TRUE, any pending events from this timer * are purged from its task's event queue. */ REQUIRE(VALID_TIMER(timer)); manager = timer->manager; REQUIRE(VALID_MANAGER(manager)); if (expires == NULL) expires = isc_time_epoch; if (interval == NULL) interval = isc_interval_zero; REQUIRE(type == isc_timertype_inactive || !(isc_time_isepoch(expires) && isc_interval_iszero(interval))); REQUIRE(type != isc_timertype_limited || !(isc_time_isepoch(expires) || isc_interval_iszero(interval))); /* * Get current time. */ if (type != isc_timertype_inactive) { TIME_NOW(&now); } else { /* * We don't have to do this, but it keeps the compiler from * complaining about "now" possibly being used without being * set, even though it will never actually happen. */ isc_time_settoepoch(&now); } LOCK(&manager->lock); LOCK(&timer->lock); if (purge) (void)isc_task_purgerange(timer->task, timer, ISC_TIMEREVENT_FIRSTEVENT, ISC_TIMEREVENT_LASTEVENT, NULL); timer->type = type; timer->expires = *expires; timer->interval = *interval; if (type == isc_timertype_once && !isc_interval_iszero(interval)) { result = isc_time_add(&now, interval, &timer->idle); } else { isc_time_settoepoch(&timer->idle); result = ISC_R_SUCCESS; } if (result == ISC_R_SUCCESS) { if (type == isc_timertype_inactive) { deschedule(timer); result = ISC_R_SUCCESS; } else result = schedule(timer, &now, ISC_TRUE); } UNLOCK(&timer->lock); UNLOCK(&manager->lock); return (result); }