2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-01 06:55:30 +00:00

187. [func] isc_ratelimter_enqueue() has an additional arguement

'task'.

 checkpoint zone maintence / notify work.
This commit is contained in:
Mark Andrews
2000-05-18 04:43:00 +00:00
parent 59abb512d3
commit 1aae402fc3
3 changed files with 149 additions and 72 deletions

View File

@@ -15,7 +15,7 @@
* SOFTWARE. * SOFTWARE.
*/ */
/* $Id: zone.c,v 1.117 2000/05/18 02:59:16 marka Exp $ */ /* $Id: zone.c,v 1.118 2000/05/18 04:43:00 marka Exp $ */
#include <config.h> #include <config.h>
@@ -48,9 +48,6 @@
#include <dns/xfrin.h> #include <dns/xfrin.h>
#include <dns/zone.h> #include <dns/zone.h>
/* XXX remove once config changes are in place */
#define dns_zone_uptodate(x) zone_log(x, me, ISC_LOG_INFO, "dns_zone_uptodate")
#define ZONE_MAGIC 0x5a4f4e45U /* ZONE */ #define ZONE_MAGIC 0x5a4f4e45U /* ZONE */
#define NOTIFY_MAGIC 0x4e746679U /* Ntfy */ #define NOTIFY_MAGIC 0x4e746679U /* Ntfy */
@@ -223,7 +220,7 @@ static void zone_expire(dns_zone_t *zone);
static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db, static isc_result_t zone_replacedb(dns_zone_t *zone, dns_db_t *db,
isc_boolean_t dump); isc_boolean_t dump);
static isc_result_t default_journal(dns_zone_t *zone); static isc_result_t default_journal(dns_zone_t *zone);
static void xfrdone(dns_zone_t *zone, isc_result_t result); static void zone_xfrdone(dns_zone_t *zone, isc_result_t result);
static void zone_shutdown(isc_task_t *, isc_event_t *); static void zone_shutdown(isc_task_t *, isc_event_t *);
#if 0 #if 0
@@ -1264,7 +1261,8 @@ dns_zone_maintenance(dns_zone_t *zone) {
default: default:
break; break;
} }
(void) zone_settimer(zone, now); /*XXX*/ if (!DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
(void) zone_settimer(zone, now);
} }
void void
@@ -1303,6 +1301,9 @@ dns_zone_refresh(dns_zone_t *zone) {
isc_stdtime_get(&now); isc_stdtime_get(&now);
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING))
return;
/* /*
* Set DNS_ZONE_F_REFRESH so that there is only one refresh operation * Set DNS_ZONE_F_REFRESH so that there is only one refresh operation
* in progress at the one time. * in progress at the one time.
@@ -1454,6 +1455,22 @@ dns_zone_setrefresh(dns_zone_t *zone, isc_uint32_t refresh,
zone->retry = retry; zone->retry = retry;
} }
static isc_boolean_t
notify_isqueued(dns_zone_t *zone, dns_name_t *name, isc_sockaddr_t *addr) {
notify_t *notify;
for (notify = ISC_LIST_HEAD(zone->notifies);
notify != NULL;
notify = ISC_LIST_NEXT(notify, link)) {
if (name != NULL && dns_name_dynamic(&notify->ns) &&
dns_name_equal(name, &notify->ns))
return (ISC_TRUE);
if (addr != NULL && isc_sockaddr_equal(addr, &notify->dst))
return (ISC_TRUE);
}
return (ISC_FALSE);
}
static void static void
notify_destroy(notify_t *notify) { notify_destroy(notify_t *notify) {
isc_mem_t *mctx; isc_mem_t *mctx;
@@ -1495,6 +1512,7 @@ notify_create(isc_mem_t *mctx, notify_t **notifyp) {
notify->zone = NULL; notify->zone = NULL;
notify->find = NULL; notify->find = NULL;
notify->request = NULL; notify->request = NULL;
isc_sockaddr_any(&notify->dst);
dns_name_init(&notify->ns, NULL); dns_name_init(&notify->ns, NULL);
ISC_LINK_INIT(notify, link); ISC_LINK_INIT(notify, link);
notify->magic = NOTIFY_MAGIC; notify->magic = NOTIFY_MAGIC;
@@ -1585,8 +1603,9 @@ notify_send_queue(notify_t *notify) {
if (e == NULL) if (e == NULL)
return (ISC_R_NOMEMORY); return (ISC_R_NOMEMORY);
e->ev_arg = notify; e->ev_arg = notify;
e->ev_sender = notify; e->ev_sender = NULL;
result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl, &e); result = isc_ratelimiter_enqueue(notify->zone->zmgr->rl,
notify->zone->task, &e);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
isc_event_free(&e); isc_event_free(&e);
return (result); return (result);
@@ -1645,11 +1664,14 @@ notify_send(notify_t *notify) {
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
return; return;
ai = ISC_LIST_HEAD(notify->find->list); for (ai = ISC_LIST_HEAD(notify->find->list);
while (ai != NULL) { ai != NULL;
ai = ISC_LIST_NEXT(ai, publink)) {
dst = *ai->sockaddr; dst = *ai->sockaddr;
if (isc_sockaddr_getport(&dst) == 0) if (isc_sockaddr_getport(&dst) == 0)
isc_sockaddr_setport(&dst, 53); /* XXX */ isc_sockaddr_setport(&dst, 53); /* XXX */
if (notify_isqueued(notify->zone, NULL, &dst))
continue;
new = NULL; new = NULL;
result = notify_create(notify->mctx, &new); result = notify_create(notify->mctx, &new);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
@@ -1661,7 +1683,6 @@ notify_send(notify_t *notify) {
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto cleanup; goto cleanup;
new = NULL; new = NULL;
ai = ISC_LIST_NEXT(ai, publink);
} }
cleanup: cleanup:
@@ -1675,7 +1696,6 @@ void
dns_zone_notify(dns_zone_t *zone) { dns_zone_notify(dns_zone_t *zone) {
dns_dbnode_t *node = NULL; dns_dbnode_t *node = NULL;
dns_dbversion_t *version = NULL; dns_dbversion_t *version = NULL;
dns_message_t *message = NULL;
dns_name_t *origin = NULL; dns_name_t *origin = NULL;
dns_name_t master; dns_name_t master;
dns_rdata_ns_t ns; dns_rdata_ns_t ns;
@@ -1686,49 +1706,48 @@ dns_zone_notify(dns_zone_t *zone) {
isc_result_t result; isc_result_t result;
notify_t *notify = NULL; notify_t *notify = NULL;
unsigned int i; unsigned int i;
isc_sockaddr_t dst;
isc_boolean_t isqueued;
REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(DNS_ZONE_VALID(zone));
if (!DNS_ZONE_OPTION(zone, DNS_ZONE_O_NOTIFY)) {
LOCK(&zone->lock);
zone->flags &= ~DNS_ZONE_F_NEEDNOTIFY;
UNLOCK(&zone->lock);
return;
}
origin = &zone->origin;
result = notify_createmessage(zone, &message);
if (result != ISC_R_SUCCESS)
return;
LOCK(&zone->lock); LOCK(&zone->lock);
zone->flags &= ~DNS_ZONE_F_NEEDNOTIFY; zone->flags &= ~DNS_ZONE_F_NEEDNOTIFY;
UNLOCK(&zone->lock); UNLOCK(&zone->lock);
if (!DNS_ZONE_OPTION(zone, DNS_ZONE_O_NOTIFY)) {
return;
}
origin = &zone->origin;
/* /*
* Enqueue notify request. * Enqueue notify request.
*/ */
LOCK(&zone->lock);
for (i = 0; i < zone->notifycnt; i++) { for (i = 0; i < zone->notifycnt; i++) {
dst = zone->notify[i];
if (isc_sockaddr_getport(&dst) == 0)
isc_sockaddr_setport(&dst, 53); /* XXX */
if (notify_isqueued(zone, NULL, &dst))
continue;
result = notify_create(zone->mctx, &notify); result = notify_create(zone->mctx, &notify);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS) {
goto cleanup0; UNLOCK(&zone->lock);
dns_zone_attach(zone, &notify->zone); return;
notify->dst = zone->notify[i]; }
if (isc_sockaddr_getport(&notify->dst) == 0) zone_attach(zone, &notify->zone);
isc_sockaddr_setport(&notify->dst, 53); /* XXX */ notify->dst = dst;
LOCK(&zone->lock);
ISC_LIST_APPEND(zone->notifies, notify, link); ISC_LIST_APPEND(zone->notifies, notify, link);
UNLOCK(&zone->lock);
result = notify_send_queue(notify); result = notify_send_queue(notify);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
LOCK(&zone->lock);
notify_destroy(notify); notify_destroy(notify);
UNLOCK(&zone->lock); UNLOCK(&zone->lock);
goto cleanup0; return;
} }
notify = NULL; notify = NULL;
} }
UNLOCK(&zone->lock);
/* /*
* Process NS RRset to generate notifies. * Process NS RRset to generate notifies.
@@ -1789,6 +1808,11 @@ dns_zone_notify(dns_zone_t *zone) {
result = dns_rdataset_next(&nsrdset); result = dns_rdataset_next(&nsrdset);
continue; continue;
} }
LOCK(&zone->lock);
isqueued = notify_isqueued(zone, &ns.name, NULL);
UNLOCK(&zone->lock);
if (isqueued)
continue;
result = notify_create(zone->mctx, &notify); result = notify_create(zone->mctx, &notify);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
dns_rdata_freestruct(&ns); dns_rdata_freestruct(&ns);
@@ -1819,8 +1843,6 @@ dns_zone_notify(dns_zone_t *zone) {
dns_db_detachnode(zone->db, &node); dns_db_detachnode(zone->db, &node);
cleanup1: cleanup1:
dns_db_closeversion(zone->db, &version, ISC_FALSE); dns_db_closeversion(zone->db, &version, ISC_FALSE);
cleanup0:
dns_message_destroy(&message);
} }
/*** /***
@@ -1835,9 +1857,7 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
dns_message_t *msg = NULL; dns_message_t *msg = NULL;
isc_uint32_t soacnt, cnamecnt, soacount, nscount; isc_uint32_t soacnt, cnamecnt, soacount, nscount;
isc_stdtime_t now; isc_stdtime_t now;
char *master; char master[ISC_SOCKADDR_FORMATSIZE];
isc_buffer_t masterbuf;
char mastermem[256];
dns_rdataset_t *rdataset; dns_rdataset_t *rdataset;
dns_rdata_t rdata; dns_rdata_t rdata;
dns_rdata_soa_t soa; dns_rdata_soa_t soa;
@@ -1855,12 +1875,9 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
* if timeout log and next master; * if timeout log and next master;
*/ */
isc_buffer_init(&masterbuf, mastermem, sizeof(mastermem)); isc_sockaddr_format(&zone->masteraddr, master, sizeof(master));
result = isc_sockaddr_totext(&zone->masteraddr, &masterbuf);
if (result == ISC_R_SUCCESS) isc_stdtime_get(&now);
master = (char *) masterbuf.base;
else
master = "<UNKNOWN>";
if (revent->result != ISC_R_SUCCESS) { if (revent->result != ISC_R_SUCCESS) {
zone_log(zone, me, ISC_LOG_INFO, "failure for %s: %s", zone_log(zone, me, ISC_LOG_INFO, "failure for %s: %s",
@@ -1991,7 +2008,18 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
dns_request_destroy(&zone->request); dns_request_destroy(&zone->request);
queue_xfrin(zone); queue_xfrin(zone);
} else if (isc_serial_eq(soa.serial, zone->serial)) { } else if (isc_serial_eq(soa.serial, zone->serial)) {
dns_zone_uptodate(zone); if (zone->dbname != NULL) {
isc_time_t t;
isc_time_set(&t, now, 0);
result = isc_file_settime(zone->dbname, &t);
if (result != ISC_R_SUCCESS)
zone_log(zone, me, ISC_LOG_ERROR,
"isc_file_settime(%s): %s",
zone->dbname,
dns_result_totext(result));
}
zone->refreshtime = now + zone->refresh;
zone->expiretime = now + zone->expire;
goto next_master; goto next_master;
} else { } else {
ZONE_LOG(1, "ahead"); ZONE_LOG(1, "ahead");
@@ -2009,7 +2037,6 @@ refresh_callback(isc_task_t *task, isc_event_t *event) {
if (zone->curmaster >= zone->masterscnt) { if (zone->curmaster >= zone->masterscnt) {
zone->flags &= ~DNS_ZONE_F_REFRESH; zone->flags &= ~DNS_ZONE_F_REFRESH;
isc_stdtime_get(&now);
zone_settimer(zone, now); zone_settimer(zone, now);
UNLOCK(&zone->lock); UNLOCK(&zone->lock);
return; return;
@@ -2028,6 +2055,11 @@ queue_soa_query(dns_zone_t *zone) {
DNS_ENTER; DNS_ENTER;
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_EXITING)) {
cancel_refresh(zone);
return;
}
e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE, e = isc_event_allocate(zone->mctx, NULL, DNS_EVENT_ZONE,
soa_query, zone, sizeof(isc_event_t)); soa_query, zone, sizeof(isc_event_t));
if (e == NULL) { if (e == NULL) {
@@ -2039,8 +2071,8 @@ queue_soa_query(dns_zone_t *zone) {
* until the event is delivered. * until the event is delivered.
*/ */
e->ev_arg = zone; e->ev_arg = zone;
e->ev_sender = zone; e->ev_sender = NULL;
result = isc_ratelimiter_enqueue(zone->zmgr->rl, &e); result = isc_ratelimiter_enqueue(zone->zmgr->rl, zone->task, &e);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
dns_zone_detach(&dummy); dns_zone_detach(&dummy);
isc_event_free(&e); isc_event_free(&e);
@@ -2147,6 +2179,7 @@ static void
zone_shutdown(isc_task_t *task, isc_event_t *event) { zone_shutdown(isc_task_t *task, isc_event_t *event) {
dns_zone_t *zone = (dns_zone_t *) event->ev_arg; dns_zone_t *zone = (dns_zone_t *) event->ev_arg;
notify_t *notify; notify_t *notify;
isc_result_t result;
UNUSED(task); UNUSED(task);
REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(DNS_ZONE_VALID(zone));
@@ -2183,6 +2216,12 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
dns_request_cancel(notify->request); dns_request_cancel(notify->request);
} }
if (zone->timer != NULL) {
result = isc_timer_reset(zone->timer, isc_timertype_inactive,
NULL, NULL, ISC_TRUE);
RUNTIME_CHECK(result == ISC_R_SUCCESS);
}
if (zone->view != NULL) if (zone->view != NULL)
dns_view_weakdetach(&zone->view); dns_view_weakdetach(&zone->view);
@@ -3022,8 +3061,8 @@ zone_replacedb(dns_zone_t *zone, dns_db_t *db, isc_boolean_t dump) {
} }
static void static void
xfrdone(dns_zone_t *zone, isc_result_t result) { zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
const char me[] = "xfrdone"; const char me[] = "zone_xfrdone";
isc_stdtime_t now; isc_stdtime_t now;
isc_boolean_t again = ISC_FALSE; isc_boolean_t again = ISC_FALSE;
@@ -3039,13 +3078,30 @@ xfrdone(dns_zone_t *zone, isc_result_t result) {
switch (result) { switch (result) {
case ISC_R_SUCCESS: case ISC_R_SUCCESS:
zone->flags |= DNS_ZONE_F_NEEDNOTIFY; zone->flags |= DNS_ZONE_F_NEEDNOTIFY;
/* FALLTHROUGH */
case DNS_R_UPTODATE: case DNS_R_UPTODATE:
/*
* This is not neccessary if we just performed a AXFR
* however it is necessary for an IXFR / UPTODATE and
* won't hurt with an AXFR.
*/
if (zone->dbname != NULL) {
isc_time_t t;
isc_time_set(&t, now, 0);
result = isc_file_settime(zone->dbname, &t);
if (result != ISC_R_SUCCESS)
zone_log(zone, me, ISC_LOG_ERROR,
"isc_file_settime(%s): %s",
zone->dbname,
dns_result_totext(result));
}
if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_NEEDREFRESH)) { if (DNS_ZONE_FLAG(zone, DNS_ZONE_F_NEEDREFRESH)) {
zone->flags &= ~DNS_ZONE_F_NEEDREFRESH; zone->flags &= ~DNS_ZONE_F_NEEDREFRESH;
zone->refreshtime = now; zone->refreshtime = now;
} else zone->expire = now + zone->expire;
} else {
zone->refreshtime = now + zone->refresh; zone->refreshtime = now + zone->refresh;
zone->expire = now + zone->expire;
}
break; break;
default: default:
@@ -3213,7 +3269,7 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
result = dns_xfrin_create(zone, xfrtype, &zone->masteraddr, result = dns_xfrin_create(zone, xfrtype, &zone->masteraddr,
tsigkey, zone->mctx, tsigkey, zone->mctx,
zone->zmgr->timermgr, zone->zmgr->socketmgr, zone->zmgr->timermgr, zone->zmgr->socketmgr,
zone->task, xfrdone, &zone->xfr); zone->task, zone_xfrdone, &zone->xfr);
cleanup: cleanup:
/* /*
* Any failure in this function is handled like a failed * Any failure in this function is handled like a failed
@@ -3221,7 +3277,7 @@ got_transfer_quota(isc_task_t *task, isc_event_t *event) {
* zmgr->xfrin_in_progress. * zmgr->xfrin_in_progress.
*/ */
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
xfrdone(zone, result); zone_xfrdone(zone, result);
isc_event_free(&event); isc_event_free(&event);
@@ -3293,8 +3349,8 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
&zmgr->rl); &zmgr->rl);
if (result != ISC_R_SUCCESS) if (result != ISC_R_SUCCESS)
goto free_task; goto free_task;
/* 100 refresh queries / notifies per second. */ /* 20 refresh queries / notifies per second. */
isc_interval_set(&interval, 0, 1000000000/10); isc_interval_set(&interval, 0, 1000000000/2);
result = isc_ratelimiter_setinterval(zmgr->rl, &interval); result = isc_ratelimiter_setinterval(zmgr->rl, &interval);
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
isc_ratelimiter_setpertic(zmgr->rl, 10); isc_ratelimiter_setpertic(zmgr->rl, 10);
@@ -3518,7 +3574,7 @@ zmgr_resume_xfrs(dns_zonemgr_t *zmgr) {
* *
* Returns: * Returns:
* ISC_R_SUCCESS There was enough quota and we attempted to * ISC_R_SUCCESS There was enough quota and we attempted to
* start a transfer. xfrdone() has been or will * start a transfer. zone_xfrdone() has been or will
* be called. * be called.
* ISC_R_QUOTA Not enough quota. * ISC_R_QUOTA Not enough quota.
* Others Failure. * Others Failure.

View File

@@ -67,16 +67,23 @@ isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t perint);
*/ */
isc_result_t isc_result_t
isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_event_t **eventp); isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
isc_event_t **eventp);
/* /*
* Queue an event for rate-limited execution. This is similar * Queue an event for rate-limited execution. This is similar
* to doing an isc_task_send() to the rate limiter's task, except * to doing an isc_task_send() to the 'task', except that the
* that the execution may be delayed to achieve the desired rate * execution may be delayed to achieve the desired rate of
* of execution. * execution.
*
* '(*eventp)->ev_sender' is used to hold the task. The caller
* must ensure that the task exists until the event is delivered.
* *
* Requires: * Requires:
* An interval has been set by calling * An interval has been set by calling
* isc_ratelimiter_setinterval(). * isc_ratelimiter_setinterval().
*
* 'task' to be non NULL.
* '(*eventp)->ev_sender' to be NULL.
*/ */
void void

View File

@@ -122,27 +122,37 @@ isc_ratelimiter_setpertic(isc_ratelimiter_t *rl, isc_uint32_t pertic) {
} }
isc_result_t isc_result_t
isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_event_t **eventp) { isc_ratelimiter_enqueue(isc_ratelimiter_t *rl, isc_task_t *task,
isc_event_t **eventp)
{
isc_result_t result = ISC_R_SUCCESS; isc_result_t result = ISC_R_SUCCESS;
INSIST(eventp != NULL && *eventp != NULL); isc_event_t *ev;
REQUIRE(eventp != NULL && *eventp != NULL);
REQUIRE(task != NULL);
ev = *eventp;
REQUIRE(ev->ev_sender == NULL);
LOCK(&rl->lock); LOCK(&rl->lock);
if (rl->state == isc_ratelimiter_ratelimited) { if (rl->state == isc_ratelimiter_ratelimited) {
isc_event_t *ev = *eventp; isc_event_t *ev = *eventp;
ev->ev_sender = task;
ISC_LIST_APPEND(rl->pending, ev, ev_link); ISC_LIST_APPEND(rl->pending, ev, ev_link);
*eventp = NULL; *eventp = NULL;
} else if (rl->state == isc_ratelimiter_worklimited) { } else if (rl->state == isc_ratelimiter_worklimited) {
result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL, result = isc_timer_reset(rl->timer, isc_timertype_ticker, NULL,
&rl->interval, ISC_FALSE); &rl->interval, ISC_FALSE);
if (result == ISC_R_SUCCESS) if (result == ISC_R_SUCCESS) {
ev->ev_sender = task;
rl->state = isc_ratelimiter_ratelimited; rl->state = isc_ratelimiter_ratelimited;
}
} else { } else {
INSIST(rl->state == isc_ratelimiter_shuttingdown); INSIST(rl->state == isc_ratelimiter_shuttingdown);
result = ISC_R_SHUTTINGDOWN; result = ISC_R_SHUTTINGDOWN;
} }
UNLOCK(&rl->lock); UNLOCK(&rl->lock);
if (*eventp != NULL) if (*eventp != NULL && result == ISC_R_SUCCESS)
isc_task_send(rl->task, eventp); isc_task_send(task, eventp);
ENSURE(*eventp == NULL);
return (result); return (result);
} }
@@ -179,8 +189,10 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
pertic = 0; /* Force the loop to exit. */ pertic = 0; /* Force the loop to exit. */
} }
UNLOCK(&rl->lock); UNLOCK(&rl->lock);
if (p != NULL) if (p != NULL) {
isc_task_send(rl->task, &p); isc_task_t *evtask = p->ev_sender;
isc_task_send(evtask, &p);
}
INSIST(p == NULL); INSIST(p == NULL);
} }
} }
@@ -188,6 +200,7 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
void void
isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) { isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
isc_event_t *ev; isc_event_t *ev;
isc_task_t *task;
LOCK(&rl->lock); LOCK(&rl->lock);
rl->state = isc_ratelimiter_shuttingdown; rl->state = isc_ratelimiter_shuttingdown;
(void) isc_timer_reset(rl->timer, isc_timertype_inactive, (void) isc_timer_reset(rl->timer, isc_timertype_inactive,
@@ -195,7 +208,8 @@ isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) { while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) {
ISC_LIST_UNLINK(rl->pending, ev, ev_link); ISC_LIST_UNLINK(rl->pending, ev, ev_link);
ev->ev_attributes |= ISC_EVENTATTR_CANCELED; ev->ev_attributes |= ISC_EVENTATTR_CANCELED;
isc_task_send(rl->task, &ev); task = ev->ev_sender;
isc_task_send(task, &ev);
} }
UNLOCK(&rl->lock); UNLOCK(&rl->lock);
} }