From 48b2a5df97b3aaa15d610dc546f8f51ecf7cf1dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Sur=C3=BD?= Date: Thu, 31 Mar 2022 21:59:57 +0200 Subject: [PATCH] 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. --- lib/dns/include/dns/events.h | 3 -- lib/isc/include/isc/app.h | 4 +- lib/isc/include/isc/event.h | 3 -- lib/isc/include/isc/task.h | 6 +-- lib/isc/include/isc/timer.h | 13 ++++--- lib/isc/timer.c | 66 +++++++++++++++++++++++--------- lib/isccc/include/isccc/events.h | 3 -- 7 files changed, 57 insertions(+), 41 deletions(-) diff --git a/lib/dns/include/dns/events.h b/lib/dns/include/dns/events.h index d3d08e088a..a38effdf03 100644 --- a/lib/dns/include/dns/events.h +++ b/lib/dns/include/dns/events.h @@ -82,6 +82,3 @@ #define DNS_EVENT_TRYSTALE (ISC_EVENTCLASS_DNS + 59) #define DNS_EVENT_ZONEFLUSH (ISC_EVENTCLASS_DNS + 60) #define DNS_EVENT_CHECKDSSENDTOADDR (ISC_EVENTCLASS_DNS + 61) - -#define DNS_EVENT_FIRSTEVENT (ISC_EVENTCLASS_DNS + 0) -#define DNS_EVENT_LASTEVENT (ISC_EVENTCLASS_DNS + 65535) diff --git a/lib/isc/include/isc/app.h b/lib/isc/include/isc/app.h index 1a42bd0e27..5f5f04b08f 100644 --- a/lib/isc/include/isc/app.h +++ b/lib/isc/include/isc/app.h @@ -91,9 +91,7 @@ typedef isc_event_t isc_appevent_t; -#define ISC_APPEVENT_FIRSTEVENT (ISC_EVENTCLASS_APP + 0) -#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 1) -#define ISC_APPEVENT_LASTEVENT (ISC_EVENTCLASS_APP + 65535) +#define ISC_APPEVENT_SHUTDOWN (ISC_EVENTCLASS_APP + 0) ISC_LANG_BEGINDECLS diff --git a/lib/isc/include/isc/event.h b/lib/isc/include/isc/event.h index 811bcd8862..75a528e4e9 100644 --- a/lib/isc/include/isc/event.h +++ b/lib/isc/include/isc/event.h @@ -76,9 +76,6 @@ struct isc_event { ISC_EVENT_COMMON(struct isc_event); }; -#define ISC_EVENTTYPE_FIRSTEVENT 0x00000000 -#define ISC_EVENTTYPE_LASTEVENT 0xffffffff - #define ISC_EVENT_PTR(p) ((isc_event_t **)(void *)(p)) ISC_LANG_BEGINDECLS diff --git a/lib/isc/include/isc/task.h b/lib/isc/include/isc/task.h index efc50992c9..1d995083c7 100644 --- a/lib/isc/include/isc/task.h +++ b/lib/isc/include/isc/task.h @@ -68,10 +68,8 @@ #include #include -#define ISC_TASKEVENT_FIRSTEVENT (ISC_EVENTCLASS_TASK + 0) -#define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 1) -#define ISC_TASKEVENT_TEST (ISC_EVENTCLASS_TASK + 1) -#define ISC_TASKEVENT_LASTEVENT (ISC_EVENTCLASS_TASK + 65535) +#define ISC_TASKEVENT_SHUTDOWN (ISC_EVENTCLASS_TASK + 0) +#define ISC_TASKEVENT_TEST (ISC_EVENTCLASS_TASK + 1) /***** ***** Tasks. diff --git a/lib/isc/include/isc/timer.h b/lib/isc/include/isc/timer.h index 1457d796f9..cbe2372878 100644 --- a/lib/isc/include/isc/timer.h +++ b/lib/isc/include/isc/timer.h @@ -81,15 +81,16 @@ 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) -#define ISC_TIMEREVENT_ONCE (ISC_EVENTCLASS_TIMER + 2) -#define ISC_TIMEREVENT_LASTEVENT (ISC_EVENTCLASS_TIMER + 65535) +#define ISC_TIMEREVENT_TICK (ISC_EVENTCLASS_TIMER + 0) +#define ISC_TIMEREVENT_ONCE (ISC_EVENTCLASS_TIMER + 1) /*** *** Timer and Timer Manager Functions diff --git a/lib/isc/timer.c b/lib/isc/timer.c index 5d54e3843a..136ed3276a 100644 --- a/lib/isc/timer.c +++ b/lib/isc/timer.c @@ -70,6 +70,7 @@ struct isc_timer { void *arg; unsigned int index; isc_time_t due; + ISC_LIST(isc_timerevent_t) active; LINK(isc_timer_t) link; }; @@ -189,18 +190,44 @@ 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 +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); @@ -248,6 +275,8 @@ isc_timer_create(isc_timermgr_t *manager, isc_task_t *task, isc_mutex_init(&timer->lock); ISC_LINK_INIT(timer, link); + ISC_LIST_INIT(timer->active); + timer->magic = TIMER_MAGIC; /* @@ -303,9 +332,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->interval = *interval; @@ -376,20 +403,21 @@ static void 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 diff --git a/lib/isccc/include/isccc/events.h b/lib/isccc/include/isccc/events.h index 0461a8a96f..ddbfbcd79d 100644 --- a/lib/isccc/include/isccc/events.h +++ b/lib/isccc/include/isccc/events.h @@ -38,6 +38,3 @@ */ #define ISCCC_EVENT_CCMSG (ISC_EVENTCLASS_ISCCC + 0) - -#define ISCCC_EVENT_FIRSTEVENT (ISC_EVENTCLASS_ISCCC + 0) -#define ISCCC_EVENT_LASTEVENT (ISC_EVENTCLASS_ISCCC + 65535)