Keep the list of scheduled events on the timer

Instead of searching for the events to purge, keep the list of scheduled
events on the timer list and purge the events that we have scheduled.

(cherry picked from commit 3f8024b4a2f12fcd28a9dd813b6f1f3f11d506f2)
This commit is contained in:
Ondřej Surý 2022-03-31 21:59:57 +02:00
parent be99507488
commit 5f141e2c7f
No known key found for this signature in database
GPG key ID: 2820F37E873DEA41
2 changed files with 29 additions and 11 deletions

View file

@ -87,10 +87,13 @@ typedef enum {
isc_timertype_inactive = 3 /*%< Inactive */
} isc_timertype_t;
typedef struct isc_timerevent {
typedef struct isc_timerevent isc_timerevent_t;
struct isc_timerevent {
struct isc_event common;
isc_time_t due;
} isc_timerevent_t;
ISC_LINK(isc_timerevent_t) ev_timerlink;
};
#define ISC_TIMEREVENT_FIRSTEVENT (ISC_EVENTCLASS_TIMER + 0)
#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 1)

View file

@ -72,6 +72,7 @@ struct isc_timer {
void *arg;
unsigned int index;
isc_time_t due;
ISC_LIST(isc_timerevent_t) active;
LINK(isc_timer_t) link;
};
@ -204,18 +205,31 @@ deschedule(isc_timer_t *timer) {
}
}
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
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);
@ -309,6 +323,9 @@ isc_timer_create(isc_timermgr_t *manager, isc_timertype_t type,
timer->index = 0;
isc_mutex_init(&timer->lock);
ISC_LINK_INIT(timer, link);
ISC_LIST_INIT(timer->active);
timer->magic = TIMER_MAGIC;
LOCK(&manager->lock);
@ -388,9 +405,7 @@ isc_timer_reset(isc_timer_t *timer, isc_timertype_t type,
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->expires = *expires;