void *arg;
unsigned int index;
isc_time_t due;
+ ISC_LIST(isc_timerevent_t) active;
LINK(isc_timer_t) link;
};
}
}
+static void
+timerevent_unlink(isc_timer_t *timer, isc_timerevent_t *event) {
+ fprintf(stderr, "unlinking %p from %p\n", event, &timer->active);
+
+ REQUIRE(ISC_LINK_LINKED(event, ev_timerlink));
+ ISC_LIST_UNLINK(timer->active, event, ev_timerlink);
+}
+
+static void
+timerevent_destroy(isc_event_t *event0) {
+ isc_timer_t *timer = event0->ev_destroy_arg;
+ isc_timerevent_t *event = (isc_timerevent_t *)event0;
+
+ if (ISC_LINK_LINKED(event, ev_timerlink)) {
+ timerevent_unlink(timer, event);
+ }
+
+ isc_mem_put(timer->manager->mctx, event, event0->ev_size);
+ isc_timer_detach(&timer);
+}
+
+static void
+timer_purge(isc_timer_t *timer) {
+ isc_timerevent_t *event = NULL;
+
+ while ((event = ISC_LIST_HEAD(timer->active)) != NULL) {
+ (void)isc_task_purgeevent(timer->task, (isc_event_t *)event);
+ timerevent_unlink(timer, event);
+ }
+}
+
static void
destroy(isc_timer_t *timer) {
isc_timermgr_t *manager = timer->manager;
- /*
- * The caller must ensure it is safe to destroy the timer.
- */
-
LOCK(&manager->lock);
- (void)isc_task_purgerange(timer->task, timer, ISC_TIMEREVENT_FIRSTEVENT,
- ISC_TIMEREVENT_LASTEVENT, NULL);
+ timer_purge(timer);
deschedule(timer);
UNLINK(manager->timers, timer, link);
isc_mutex_init(&timer->lock);
ISC_LINK_INIT(timer, link);
+ ISC_LIST_INIT(timer->active);
+
timer->magic = TIMER_MAGIC;
/*
LOCK(&timer->lock);
if (purge) {
- (void)isc_task_purgerange(timer->task, timer,
- ISC_TIMEREVENT_FIRSTEVENT,
- ISC_TIMEREVENT_LASTEVENT, NULL);
+ timer_purge(timer);
}
timer->type = type;
timer->interval = *interval;
post_event(isc_timermgr_t *manager, isc_timer_t *timer, isc_eventtype_t type) {
isc_timerevent_t *event;
XTRACEID("posting", timer);
- /*
- * XXX We could preallocate this event.
- */
+
event = (isc_timerevent_t *)isc_event_allocate(
manager->mctx, timer, type, timer->action, timer->arg,
sizeof(*event));
- if (event != NULL) {
- event->due = timer->due;
- isc_task_send(timer->task, ISC_EVENT_PTR(&event));
- } else {
- UNEXPECTED_ERROR(__FILE__, __LINE__, "%s",
- "couldn't allocate event");
- }
+ ISC_LINK_INIT(event, ev_timerlink);
+ ((isc_event_t *)event)->ev_destroy = timerevent_destroy;
+
+ isc_timer_attach(timer, &(isc_timer_t *){ NULL });
+ ((isc_event_t *)event)->ev_destroy_arg = timer;
+
+ event->due = timer->due;
+ ISC_LIST_APPEND(timer->active, event, ev_timerlink);
+
+ isc_task_send(timer->task, ISC_EVENT_PTR(&event));
}
static void