2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-09-03 08:05:21 +00:00

Convert more reference counting to isc_refcount API

This commit is contained in:
Ondřej Surý
2019-07-15 10:27:11 +02:00
parent 7c3e342935
commit e711b0304f
4 changed files with 87 additions and 128 deletions

View File

@@ -32,6 +32,7 @@
#include <isc/lang.h> #include <isc/lang.h>
#include <isc/magic.h> #include <isc/magic.h>
#include <isc/netaddr.h> #include <isc/netaddr.h>
#include <isc/refcount.h>
#include <dns/types.h> #include <dns/types.h>
@@ -47,7 +48,7 @@
struct dns_peerlist { struct dns_peerlist {
unsigned int magic; unsigned int magic;
uint32_t refs; isc_refcount_t refs;
isc_mem_t *mem; isc_mem_t *mem;
@@ -56,7 +57,7 @@ struct dns_peerlist {
struct dns_peer { struct dns_peer {
unsigned int magic; unsigned int magic;
uint32_t refs; isc_refcount_t refs;
isc_mem_t *mem; isc_mem_t *mem;

View File

@@ -62,7 +62,7 @@ dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) {
ISC_LIST_INIT(l->elements); ISC_LIST_INIT(l->elements);
l->mem = mem; l->mem = mem;
l->refs = 1; isc_refcount_init(&l->refs, 1);
l->magic = DNS_PEERLIST_MAGIC; l->magic = DNS_PEERLIST_MAGIC;
*list = l; *list = l;
@@ -76,9 +76,7 @@ dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) {
REQUIRE(target != NULL); REQUIRE(target != NULL);
REQUIRE(*target == NULL); REQUIRE(*target == NULL);
source->refs++; isc_refcount_increment(&source->refs);
ENSURE(source->refs != 0xffffffffU);
*target = source; *target = source;
} }
@@ -94,13 +92,10 @@ dns_peerlist_detach(dns_peerlist_t **list) {
plist = *list; plist = *list;
*list = NULL; *list = NULL;
REQUIRE(plist->refs > 0); if (isc_refcount_decrement(&plist->refs) == 1) {
plist->refs--;
if (plist->refs == 0)
peerlist_delete(&plist); peerlist_delete(&plist);
} }
}
static void static void
peerlist_delete(dns_peerlist_t **list) { peerlist_delete(dns_peerlist_t **list) {
@@ -112,7 +107,7 @@ peerlist_delete(dns_peerlist_t **list) {
l = *list; l = *list;
REQUIRE(l->refs == 0); isc_refcount_destroy(&l->refs);
server = ISC_LIST_HEAD(l->elements); server = ISC_LIST_HEAD(l->elements);
while (server != NULL) { while (server != NULL) {
@@ -218,26 +213,19 @@ dns_peer_newprefix(isc_mem_t *mem, const isc_netaddr_t *addr,
{ {
dns_peer_t *peer; dns_peer_t *peer;
REQUIRE(peerptr != NULL); REQUIRE(peerptr != NULL && *peerptr == NULL);
peer = isc_mem_get(mem, sizeof(*peer)); peer = isc_mem_get(mem, sizeof(*peer));
peer->magic = DNS_PEER_MAGIC; *peer = (dns_peer_t){
peer->address = *addr; .magic = DNS_PEER_MAGIC,
peer->prefixlen = prefixlen; .address = *addr,
peer->mem = mem; .prefixlen = prefixlen,
peer->bogus = false; .mem = mem,
peer->transfer_format = dns_one_answer; .transfer_format = dns_one_answer,
peer->transfers = 0; };
peer->request_ixfr = false;
peer->provide_ixfr = false;
peer->key = NULL;
peer->refs = 1;
peer->transfer_source = NULL;
peer->notify_source = NULL;
peer->query_source = NULL;
memset(&peer->bitflags, 0x0, sizeof(peer->bitflags)); isc_refcount_init(&peer->refs, 1);
ISC_LINK_INIT(peer, next); ISC_LINK_INIT(peer, next);
@@ -252,9 +240,7 @@ dns_peer_attach(dns_peer_t *source, dns_peer_t **target) {
REQUIRE(target != NULL); REQUIRE(target != NULL);
REQUIRE(*target == NULL); REQUIRE(*target == NULL);
source->refs++; isc_refcount_increment(&source->refs);
ENSURE(source->refs != 0xffffffffU);
*target = source; *target = source;
} }
@@ -268,15 +254,12 @@ dns_peer_detach(dns_peer_t **peer) {
REQUIRE(DNS_PEER_VALID(*peer)); REQUIRE(DNS_PEER_VALID(*peer));
p = *peer; p = *peer;
REQUIRE(p->refs > 0);
*peer = NULL; *peer = NULL;
p->refs--;
if (p->refs == 0) if (isc_refcount_decrement(&p->refs) == 1) {
peer_delete(&p); peer_delete(&p);
} }
}
static void static void
peer_delete(dns_peer_t **peer) { peer_delete(dns_peer_t **peer) {
@@ -288,7 +271,7 @@ peer_delete(dns_peer_t **peer) {
p = *peer; p = *peer;
REQUIRE(p->refs == 0); isc_refcount_destroy(&p->refs);
mem = p->mem; mem = p->mem;
p->mem = NULL; p->mem = NULL;

View File

@@ -205,7 +205,7 @@ struct dns_zone {
dns_zonemgr_t *zmgr; dns_zonemgr_t *zmgr;
ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ ISC_LINK(dns_zone_t) link; /* Used by zmgr. */
isc_timer_t *timer; isc_timer_t *timer;
unsigned int irefs; isc_refcount_t irefs;
dns_name_t origin; dns_name_t origin;
char *masterfile; char *masterfile;
ISC_LIST(dns_include_t) includes; /* Include files */ ISC_LIST(dns_include_t) includes; /* Include files */
@@ -529,7 +529,7 @@ struct dns_unreachable {
struct dns_zonemgr { struct dns_zonemgr {
unsigned int magic; unsigned int magic;
isc_mem_t * mctx; isc_mem_t * mctx;
int refs; /* Locked by rwlock */ isc_refcount_t refs;
isc_taskmgr_t * taskmgr; isc_taskmgr_t * taskmgr;
isc_timermgr_t * timermgr; isc_timermgr_t * timermgr;
isc_socketmgr_t * socketmgr; isc_socketmgr_t * socketmgr;
@@ -921,8 +921,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
zone->db = NULL; zone->db = NULL;
zone->zmgr = NULL; zone->zmgr = NULL;
ISC_LINK_INIT(zone, link); ISC_LINK_INIT(zone, link);
isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ isc_refcount_init(&zone->erefs, 1);
zone->irefs = 0; isc_refcount_init(&zone->irefs, 0);
dns_name_init(&zone->origin, NULL); dns_name_init(&zone->origin, NULL);
zone->strnamerd = NULL; zone->strnamerd = NULL;
zone->strname = NULL; zone->strname = NULL;
@@ -1073,7 +1073,7 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
result = isc_stats_create(mctx, &zone->gluecachestats, result = isc_stats_create(mctx, &zone->gluecachestats,
dns_gluecachestatscounter_max); dns_gluecachestatscounter_max);
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
goto free_erefs; goto free_refs;
} }
/* Must be after magic is set. */ /* Must be after magic is set. */
@@ -1085,9 +1085,10 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) {
*zonep = zone; *zonep = zone;
return (ISC_R_SUCCESS); return (ISC_R_SUCCESS);
free_erefs: free_refs:
INSIST(isc_refcount_decrement(&zone->erefs) > 0); INSIST(isc_refcount_decrement(&zone->erefs) > 0);
isc_refcount_destroy(&zone->erefs); isc_refcount_destroy(&zone->erefs);
isc_refcount_destroy(&zone->irefs);
ZONEDB_DESTROYLOCK(&zone->dblock); ZONEDB_DESTROYLOCK(&zone->dblock);
@@ -1111,7 +1112,7 @@ zone_free(dns_zone_t *zone) {
REQUIRE(DNS_ZONE_VALID(zone)); REQUIRE(DNS_ZONE_VALID(zone));
REQUIRE(isc_refcount_current(&zone->erefs) == 0); REQUIRE(isc_refcount_current(&zone->erefs) == 0);
REQUIRE(zone->irefs == 0); REQUIRE(isc_refcount_current(&zone->irefs) == 0);
REQUIRE(!LOCKED_ZONE(zone)); REQUIRE(!LOCKED_ZONE(zone));
REQUIRE(zone->timer == NULL); REQUIRE(zone->timer == NULL);
REQUIRE(zone->zmgr == NULL); REQUIRE(zone->zmgr == NULL);
@@ -5110,7 +5111,9 @@ static bool
exit_check(dns_zone_t *zone) { exit_check(dns_zone_t *zone) {
REQUIRE(LOCKED_ZONE(zone)); REQUIRE(LOCKED_ZONE(zone));
if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) && zone->irefs == 0) { if (DNS_ZONE_FLAG(zone, DNS_ZONEFLG_SHUTDOWN) &&
isc_refcount_current(&zone->irefs) == 0)
{
/* /*
* DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0. * DNS_ZONEFLG_SHUTDOWN can only be set if erefs == 0.
*/ */
@@ -5483,9 +5486,8 @@ zone_iattach(dns_zone_t *source, dns_zone_t **target) {
REQUIRE(DNS_ZONE_VALID(source)); REQUIRE(DNS_ZONE_VALID(source));
REQUIRE(LOCKED_ZONE(source)); REQUIRE(LOCKED_ZONE(source));
REQUIRE(target != NULL && *target == NULL); REQUIRE(target != NULL && *target == NULL);
INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0); INSIST(isc_refcount_increment0(&source->irefs) +
source->irefs++; isc_refcount_current(&source->erefs) > 0);
INSIST(source->irefs != 0);
*target = source; *target = source;
} }
@@ -5501,9 +5503,8 @@ zone_idetach(dns_zone_t **zonep) {
REQUIRE(LOCKED_ZONE(*zonep)); REQUIRE(LOCKED_ZONE(*zonep));
*zonep = NULL; *zonep = NULL;
INSIST(zone->irefs > 0); INSIST(isc_refcount_decrement(&zone->irefs) - 1 +
zone->irefs--; isc_refcount_current(&zone->erefs) > 0);
INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0);
} }
void void
@@ -5515,14 +5516,15 @@ dns_zone_idetach(dns_zone_t **zonep) {
zone = *zonep; zone = *zonep;
*zonep = NULL; *zonep = NULL;
if (isc_refcount_decrement(&zone->irefs) == 1) {
LOCK_ZONE(zone); LOCK_ZONE(zone);
INSIST(zone->irefs > 0);
zone->irefs--;
free_needed = exit_check(zone); free_needed = exit_check(zone);
UNLOCK_ZONE(zone); UNLOCK_ZONE(zone);
if (free_needed) if (free_needed) {
zone_free(zone); zone_free(zone);
} }
}
}
isc_mem_t * isc_mem_t *
dns_zone_getmctx(dns_zone_t *zone) { dns_zone_getmctx(dns_zone_t *zone) {
@@ -10405,8 +10407,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) {
cleanup: cleanup:
dns_db_detach(&kfetch->db); dns_db_detach(&kfetch->db);
INSIST(zone->irefs > 0); isc_refcount_decrement(&zone->irefs);
zone->irefs--;
kfetch->zone = NULL; kfetch->zone = NULL;
if (dns_rdataset_isassociated(keydataset)) { if (dns_rdataset_isassociated(keydataset)) {
@@ -10537,8 +10539,7 @@ zone_refreshkeys(dns_zone_t *zone) {
zone->refreshkeycount++; zone->refreshkeycount++;
kfetch->zone = zone; kfetch->zone = zone;
zone->irefs++; isc_refcount_increment0(&zone->irefs);
INSIST(zone->irefs != 0);
kname = dns_fixedname_initname(&kfetch->name); kname = dns_fixedname_initname(&kfetch->name);
dns_name_dup(name, zone->mctx, kname); dns_name_dup(name, zone->mctx, kname);
dns_rdataset_init(&kfetch->dnskeyset); dns_rdataset_init(&kfetch->dnskeyset);
@@ -10592,7 +10593,7 @@ zone_refreshkeys(dns_zone_t *zone) {
fetching = true; fetching = true;
} else { } else {
zone->refreshkeycount--; zone->refreshkeycount--;
zone->irefs--; isc_refcount_decrement(&zone->irefs);
dns_db_detach(&kfetch->db); dns_db_detach(&kfetch->db);
dns_rdataset_disassociate(&kfetch->keydataset); dns_rdataset_disassociate(&kfetch->keydataset);
dns_name_free(kname, zone->mctx); dns_name_free(kname, zone->mctx);
@@ -13583,8 +13584,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
LOCK_ZONE(zone); LOCK_ZONE(zone);
INSIST(zone != zone->raw); INSIST(zone != zone->raw);
if (linked) { if (linked) {
INSIST(zone->irefs > 0); isc_refcount_decrement(&zone->irefs);
zone->irefs--;
} }
if (zone->request != NULL) { if (zone->request != NULL) {
dns_request_cancel(zone->request); dns_request_cancel(zone->request);
@@ -13611,8 +13611,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) {
if (zone->timer != NULL) { if (zone->timer != NULL) {
isc_timer_detach(&zone->timer); isc_timer_detach(&zone->timer);
INSIST(zone->irefs > 0); isc_refcount_decrement(&zone->irefs);
zone->irefs--;
} }
/* /*
@@ -15208,8 +15207,7 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) {
if (event != NULL) { if (event != NULL) {
LOCK_ZONE(zone); LOCK_ZONE(zone);
INSIST(zone->irefs > 1); isc_refcount_decrement(&zone->irefs);
zone->irefs--;
ISC_LIST_UNLINK(zone->rss_events, event, ev_link); ISC_LIST_UNLINK(zone->rss_events, event, ev_link);
goto nextevent; goto nextevent;
} }
@@ -16215,8 +16213,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) {
if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING))
queue_soa_query(zone); queue_soa_query(zone);
INSIST(zone->irefs > 0); isc_refcount_decrement(&zone->irefs);
zone->irefs--;
free_needed = exit_check(zone); free_needed = exit_check(zone);
UNLOCK_ZONE(zone); UNLOCK_ZONE(zone);
if (free_needed) if (free_needed)
@@ -16380,9 +16377,7 @@ queue_xfrin(dns_zone_t *zone) {
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); RWLOCK(&zmgr->rwlock, isc_rwlocktype_write);
ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink);
LOCK_ZONE(zone); isc_refcount_increment0(&zone->irefs);
zone->irefs++;
UNLOCK_ZONE(zone);
zone->statelist = &zmgr->waiting_for_xfrin; zone->statelist = &zmgr->waiting_for_xfrin;
result = zmgr_start_xfrin_ifquota(zmgr, zone); result = zmgr_start_xfrin_ifquota(zmgr, zone);
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
@@ -16850,7 +16845,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr,
zmgr = isc_mem_get(mctx, sizeof(*zmgr)); zmgr = isc_mem_get(mctx, sizeof(*zmgr));
zmgr->mctx = NULL; zmgr->mctx = NULL;
zmgr->refs = 1; isc_refcount_init(&zmgr->refs, 1);
isc_mem_attach(mctx, &zmgr->mctx); isc_mem_attach(mctx, &zmgr->mctx);
zmgr->taskmgr = taskmgr; zmgr->taskmgr = taskmgr;
zmgr->timermgr = timermgr; zmgr->timermgr = timermgr;
@@ -17012,12 +17007,11 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
/* /*
* The timer "holds" a iref. * The timer "holds" a iref.
*/ */
zone->irefs++; isc_refcount_increment0(&zone->irefs);
INSIST(zone->irefs != 0);
ISC_LIST_APPEND(zmgr->zones, zone, link); ISC_LIST_APPEND(zmgr->zones, zone, link);
zone->zmgr = zmgr; zone->zmgr = zmgr;
zmgr->refs++; isc_refcount_increment(&zmgr->refs);
goto unlock; goto unlock;
@@ -17044,9 +17038,10 @@ dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) {
ISC_LIST_UNLINK(zmgr->zones, zone, link); ISC_LIST_UNLINK(zmgr->zones, zone, link);
zone->zmgr = NULL; zone->zmgr = NULL;
zmgr->refs--;
if (zmgr->refs == 0) if (isc_refcount_decrement(&zmgr->refs) == 1) {
free_now = true; free_now = true;
}
UNLOCK_ZONE(zone); UNLOCK_ZONE(zone);
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
@@ -17061,31 +17056,23 @@ dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) {
REQUIRE(DNS_ZONEMGR_VALID(source)); REQUIRE(DNS_ZONEMGR_VALID(source));
REQUIRE(target != NULL && *target == NULL); REQUIRE(target != NULL && *target == NULL);
RWLOCK(&source->rwlock, isc_rwlocktype_write); isc_refcount_increment(&source->refs);
REQUIRE(source->refs > 0);
source->refs++;
INSIST(source->refs > 0);
RWUNLOCK(&source->rwlock, isc_rwlocktype_write);
*target = source; *target = source;
} }
void void
dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { dns_zonemgr_detach(dns_zonemgr_t **zmgrp) {
dns_zonemgr_t *zmgr; dns_zonemgr_t *zmgr;
bool free_now = false;
REQUIRE(zmgrp != NULL); REQUIRE(zmgrp != NULL);
zmgr = *zmgrp; zmgr = *zmgrp;
REQUIRE(DNS_ZONEMGR_VALID(zmgr)); REQUIRE(DNS_ZONEMGR_VALID(zmgr));
RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); if (isc_refcount_decrement(&zmgr->refs) == 1) {
zmgr->refs--;
if (zmgr->refs == 0)
free_now = true;
RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write);
if (free_now)
zonemgr_free(zmgr); zonemgr_free(zmgr);
}
*zmgrp = NULL; *zmgrp = NULL;
} }
@@ -17256,11 +17243,11 @@ static void
zonemgr_free(dns_zonemgr_t *zmgr) { zonemgr_free(dns_zonemgr_t *zmgr) {
isc_mem_t *mctx; isc_mem_t *mctx;
INSIST(zmgr->refs == 0);
INSIST(ISC_LIST_EMPTY(zmgr->zones)); INSIST(ISC_LIST_EMPTY(zmgr->zones));
zmgr->magic = 0; zmgr->magic = 0;
isc_refcount_destroy(&zmgr->refs);
isc_mutex_destroy(&zmgr->iolock); isc_mutex_destroy(&zmgr->iolock);
isc_ratelimiter_detach(&zmgr->notifyrl); isc_ratelimiter_detach(&zmgr->notifyrl);
isc_ratelimiter_detach(&zmgr->refreshrl); isc_ratelimiter_detach(&zmgr->refreshrl);
@@ -19514,9 +19501,7 @@ dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
/* /*
* The timer "holds" a iref. * The timer "holds" a iref.
*/ */
raw->irefs++; isc_refcount_increment0(&raw->irefs);
INSIST(raw->irefs != 0);
/* dns_zone_attach(raw, &zone->raw); */ /* dns_zone_attach(raw, &zone->raw); */
isc_refcount_increment(&raw->erefs); isc_refcount_increment(&raw->erefs);
@@ -19530,7 +19515,7 @@ dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) {
ISC_LIST_APPEND(zmgr->zones, raw, link); ISC_LIST_APPEND(zmgr->zones, raw, link);
raw->zmgr = zmgr; raw->zmgr = zmgr;
zmgr->refs++; isc_refcount_increment(&zmgr->refs);
unlock: unlock:
UNLOCK_ZONE(raw); UNLOCK_ZONE(raw);

View File

@@ -17,6 +17,7 @@
#include <isc/mem.h> #include <isc/mem.h>
#include <isc/ratelimiter.h> #include <isc/ratelimiter.h>
#include <isc/refcount.h>
#include <isc/task.h> #include <isc/task.h>
#include <isc/time.h> #include <isc/time.h>
#include <isc/timer.h> #include <isc/timer.h>
@@ -32,7 +33,7 @@ typedef enum {
struct isc_ratelimiter { struct isc_ratelimiter {
isc_mem_t * mctx; isc_mem_t * mctx;
isc_mutex_t lock; isc_mutex_t lock;
int refs; isc_refcount_t references;
isc_task_t * task; isc_task_t * task;
isc_timer_t * timer; isc_timer_t * timer;
isc_interval_t interval; isc_interval_t interval;
@@ -60,14 +61,15 @@ isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
INSIST(ratelimiterp != NULL && *ratelimiterp == NULL); INSIST(ratelimiterp != NULL && *ratelimiterp == NULL);
rl = isc_mem_get(mctx, sizeof(*rl)); rl = isc_mem_get(mctx, sizeof(*rl));
rl->mctx = mctx; *rl = (isc_ratelimiter_t){
rl->refs = 1; .mctx = mctx,
rl->task = task; .task = task,
.pertic = 1,
.state = isc_ratelimiter_idle,
};
isc_refcount_init(&rl->references, 1);
isc_interval_set(&rl->interval, 0, 0); isc_interval_set(&rl->interval, 0, 0);
rl->timer = NULL;
rl->pertic = 1;
rl->pushpop = false;
rl->state = isc_ratelimiter_idle;
ISC_LIST_INIT(rl->pending); ISC_LIST_INIT(rl->pending);
isc_mutex_init(&rl->lock); isc_mutex_init(&rl->lock);
@@ -82,7 +84,7 @@ isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr,
* Increment the reference count to indicate that we may * Increment the reference count to indicate that we may
* (soon) have events outstanding. * (soon) have events outstanding.
*/ */
rl->refs++; isc_refcount_increment(&rl->references);
ISC_EVENT_INIT(&rl->shutdownevent, ISC_EVENT_INIT(&rl->shutdownevent,
sizeof(isc_event_t), sizeof(isc_event_t),
@@ -213,12 +215,12 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) {
*/ */
ISC_LIST_UNLINK(rl->pending, p, ev_ratelink); ISC_LIST_UNLINK(rl->pending, p, ev_ratelink);
} else { } else {
isc_result_t result;
/* /*
* No work left to do. Stop the timer so that we don't * No work left to do. Stop the timer so that we don't
* waste resources by having it fire periodically. * waste resources by having it fire periodically.
*/ */
result = isc_timer_reset(rl->timer, isc_result_t result =
isc_timer_reset(rl->timer,
isc_timertype_inactive, isc_timertype_inactive,
NULL, NULL, false); NULL, NULL, false);
RUNTIME_CHECK(result == ISC_R_SUCCESS); RUNTIME_CHECK(result == ISC_R_SUCCESS);
@@ -237,7 +239,6 @@ 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;
REQUIRE(rl != NULL); REQUIRE(rl != NULL);
@@ -246,9 +247,9 @@ isc_ratelimiter_shutdown(isc_ratelimiter_t *rl) {
(void)isc_timer_reset(rl->timer, isc_timertype_inactive, (void)isc_timer_reset(rl->timer, isc_timertype_inactive,
NULL, NULL, false); NULL, NULL, false);
while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) { while ((ev = ISC_LIST_HEAD(rl->pending)) != NULL) {
isc_task_t *task = ev->ev_sender;
ISC_LIST_UNLINK(rl->pending, ev, ev_ratelink); ISC_LIST_UNLINK(rl->pending, ev, ev_ratelink);
ev->ev_attributes |= ISC_EVENTATTR_CANCELED; ev->ev_attributes |= ISC_EVENTATTR_CANCELED;
task = ev->ev_sender;
isc_task_send(task, &ev); isc_task_send(task, &ev);
} }
isc_timer_detach(&rl->timer); isc_timer_detach(&rl->timer);
@@ -280,36 +281,25 @@ ratelimiter_free(isc_ratelimiter_t *rl) {
void void
isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target) { isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target) {
REQUIRE(source != NULL); REQUIRE(source != NULL);
REQUIRE(target != NULL && *target == NULL); REQUIRE(target != NULL && *target == NULL);
LOCK(&source->lock); isc_refcount_increment(&source->references);
REQUIRE(source->refs > 0);
source->refs++;
INSIST(source->refs > 0);
UNLOCK(&source->lock);
*target = source; *target = source;
} }
void void
isc_ratelimiter_detach(isc_ratelimiter_t **rlp) { isc_ratelimiter_detach(isc_ratelimiter_t **rlp) {
isc_ratelimiter_t *rl; isc_ratelimiter_t *rl;
bool free_now = false;
REQUIRE(rlp != NULL && *rlp != NULL); REQUIRE(rlp != NULL && *rlp != NULL);
rl = *rlp; rl = *rlp;
LOCK(&rl->lock); if (isc_refcount_decrement(&rl->references) == 1) {
REQUIRE(rl->refs > 0);
rl->refs--;
if (rl->refs == 0)
free_now = true;
UNLOCK(&rl->lock);
if (free_now)
ratelimiter_free(rl); ratelimiter_free(rl);
}
*rlp = NULL; *rlp = NULL;
} }