Lines Matching refs:timer
1 /* $NetBSD: timer.c,v 1.1 2024/02/18 20:57:50 christos Exp $ */
33 #include <isc/timer.h>
67 /*! Locked by timer lock. */
104 schedule(isc_timer_t *timer, isc_time_t *now, bool signal_ok) {
113 REQUIRE(timer->type != isc_timertype_inactive);
115 manager = timer->manager;
120 if (timer->type != isc_timertype_once) {
121 isc_result_t result = isc_time_add(now, &timer->interval, &due);
125 if (timer->type == isc_timertype_limited &&
126 isc_time_compare(&timer->expires, &due) < 0)
128 due = timer->expires;
131 if (isc_time_isepoch(&timer->idle)) {
132 due = timer->expires;
133 } else if (isc_time_isepoch(&timer->expires)) {
134 due = timer->idle;
135 } else if (isc_time_compare(&timer->idle, &timer->expires) < 0)
137 due = timer->idle;
139 due = timer->expires;
144 * Schedule the timer.
147 if (timer->index > 0) {
151 cmp = isc_time_compare(&due, &timer->due);
152 timer->due = due;
155 isc_heap_increased(manager->heap, timer->index);
158 isc_heap_decreased(manager->heap, timer->index);
165 timer->due = due;
166 isc_heap_insert(manager->heap, timer);
170 XTRACETIMER("schedule", timer, due);
173 * If this timer is at the head of the queue, we need to ensure
175 * the current "next" timer. We do this either by waking up the
179 if (timer->index == 1 && signal_ok) {
188 deschedule(isc_timer_t *timer) {
196 manager = timer->manager;
197 if (timer->index > 0) {
198 if (timer->index == 1) {
201 isc_heap_delete(manager->heap, timer->index);
202 timer->index = 0;
213 timerevent_unlink(isc_timer_t *timer, isc_timerevent_t *event) {
215 ISC_LIST_UNLINK(timer->active, event, ev_timerlink);
220 isc_timer_t *timer = event0->ev_destroy_arg;
223 LOCK(&timer->lock);
226 timerevent_unlink(timer, event);
228 UNLOCK(&timer->lock);
230 isc_mem_put(timer->manager->mctx, event, event0->ev_size);
234 timer_purge(isc_timer_t *timer) {
237 while ((event = ISC_LIST_HEAD(timer->active)) != NULL) {
238 timerevent_unlink(timer, event);
239 UNLOCK(&timer->lock);
240 (void)isc_task_purgeevent(timer->task, (isc_event_t *)event);
241 LOCK(&timer->lock);
254 isc_timer_t *timer;
259 * Create a new 'type' timer managed by 'manager'. The timers
262 * called with 'arg' as the arg value. The new timer is returned
291 timer = isc_mem_get(manager->mctx, sizeof(*timer));
293 timer->manager = manager;
296 result = isc_time_add(&now, interval, &timer->idle);
298 isc_mem_put(manager->mctx, timer, sizeof(*timer));
302 isc_time_settoepoch(&timer->idle);
305 timer->type = type;
306 timer->expires = *expires;
307 timer->interval = *interval;
308 timer->task = NULL;
309 isc_task_attach(task, &timer->task);
310 timer->action = action;
313 * evils here. If the timer->arg member is made const, then
314 * it affects a great many recipients of the timer event
321 DE_CONST(arg, timer->arg);
322 timer->index = 0;
323 isc_mutex_init(&timer->lock);
324 ISC_LINK_INIT(timer, link);
326 ISC_LIST_INIT(timer->active);
328 timer->magic = TIMER_MAGIC;
333 * Note we don't have to lock the timer like we normally would because
338 result = schedule(timer, &now, true);
343 *timerp = timer;
344 APPEND(manager->timers, timer, link);
350 timer->magic = 0;
351 isc_mutex_destroy(&timer->lock);
352 isc_task_detach(&timer->task);
353 isc_mem_put(manager->mctx, timer, sizeof(*timer));
361 isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
369 * Change the timer's type, expires, and interval values to the given
370 * values. If 'purge' is true, any pending events from this timer
374 REQUIRE(VALID_TIMER(timer));
375 manager = timer->manager;
404 LOCK(&timer->lock);
407 timer_purge(timer);
409 timer->type = type;
410 timer->expires = *expires;
411 timer->interval = *interval;
413 result = isc_time_add(&now, interval, &timer->idle);
415 isc_time_settoepoch(&timer->idle);
421 deschedule(timer);
424 result = schedule(timer, &now, true);
428 UNLOCK(&timer->lock);
435 isc_timer_gettype(isc_timer_t *timer) {
438 REQUIRE(VALID_TIMER(timer));
440 LOCK(&timer->lock);
441 t = timer->type;
442 UNLOCK(&timer->lock);
448 isc_timer_touch(isc_timer_t *timer) {
453 * Set the last-touched time of 'timer' to the current time.
456 REQUIRE(VALID_TIMER(timer));
458 LOCK(&timer->lock);
463 * REQUIRE(timer->type == isc_timertype_once);
470 result = isc_time_add(&now, &timer->interval, &timer->idle);
472 UNLOCK(&timer->lock);
479 isc_timer_t *timer = NULL;
484 timer = *timerp;
487 manager = timer->manager;
491 LOCK(&timer->lock);
492 timer_purge(timer);
493 deschedule(timer);
494 UNLOCK(&timer->lock);
496 UNLINK(manager->timers, timer, link);
500 isc_task_detach(&timer->task);
501 isc_mutex_destroy(&timer->lock);
502 timer->magic = 0;
503 isc_mem_put(manager->mctx, timer, sizeof(*timer));
507 timer_post_event(isc_timermgr_t *manager, isc_timer_t *timer,
510 XTRACEID("posting", timer);
513 manager->mctx, timer, type, timer->action, timer->arg,
518 ((isc_event_t *)event)->ev_destroy_arg = timer;
520 event->due = timer->due;
522 LOCK(&timer->lock);
523 ISC_LIST_APPEND(timer->active, event, ev_timerlink);
524 UNLOCK(&timer->lock);
526 isc_task_send(timer->task, ISC_EVENT_PTR(&event));
533 isc_timer_t *timer;
542 timer = isc_heap_element(manager->heap, 1);
543 INSIST(timer != NULL && timer->type != isc_timertype_inactive);
544 if (isc_time_compare(now, &timer->due) >= 0) {
545 if (timer->type == isc_timertype_ticker) {
549 } else if (timer->type == isc_timertype_limited) {
551 cmp = isc_time_compare(now, &timer->expires);
561 } else if (!isc_time_isepoch(&timer->expires) &&
562 isc_time_compare(now, &timer->expires) >= 0)
570 LOCK(&timer->lock);
571 if (!isc_time_isepoch(&timer->idle) &&
572 isc_time_compare(now, &timer->idle) >= 0)
576 UNLOCK(&timer->lock);
583 * Idle timer has been touched;
586 XTRACEID("idle reschedule", timer);
593 timer_post_event(manager, timer, type);
596 timer->index = 0;
601 result = schedule(timer, now, false);
606 "timer",
611 manager->due = timer->due;
672 isc_timer_t *timer;
675 timer = what;
677 timer->index = index;
685 * Create a timer manager.
704 isc_thread_setname(manager->thread, "timer");
723 * Destroy a timer manager.