From e460d83dbbab40cabc5e31882bcce6419c7be0b2 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Wed, 19 Aug 2020 18:45:38 +1000 Subject: [PATCH] isc_ratelimiter needs to hold a reference to its task to prevent the task subsystem shutting down before the ratelimiter is freed. (cherry picked from commit b8e4b6d30325168bee19e1f05e286c5d3592c4ff) --- lib/isc/ratelimiter.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c index 3c067ba752..6b51f465ad 100644 --- a/lib/isc/ratelimiter.c +++ b/lib/isc/ratelimiter.c @@ -92,6 +92,8 @@ isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, return (ISC_R_SUCCESS); free_mutex: + isc_refcount_decrementz(&rl->references); + isc_refcount_destroy(&rl->references); isc_mutex_destroy(&rl->lock); isc_mem_put(mctx, rl, sizeof(*rl)); return (result); @@ -237,6 +239,7 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) { void isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) { isc_event_t *ev; + isc_task_t *task; REQUIRE(rl != NULL); @@ -245,11 +248,13 @@ isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) { (void)isc_timer_reset(rl->timer, isc_timertype_inactive, NULL, NULL, false); while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) { - isc_task_t *task = ev->ev_sender; + task = ev->ev_sender; ISC_LIST_UNLINK(rl->pending, ev, ev_ratelink); ev->ev_attributes |= ISC_EVENTATTR_CANCELED; isc_task_send(task, &ev); } + task = NULL; + isc_task_attach(rl->task, &task); isc_timer_detach(&rl->timer); /* @@ -269,10 +274,12 @@ ratelimiter_shutdowncomplete(isc_task_t *task, isc_event_t *event) { UNUSED(task); isc_ratelimiter_detach(&rl); + isc_task_detach(&task); } static void ratelimiter_free(isc_ratelimiter_t *rl) { + isc_refcount_destroy(&rl->references); isc_mutex_destroy(&rl->lock); isc_mem_put(rl->mctx, rl, sizeof(*rl)); }