diff --git a/bin/rndc/rndc.c b/bin/rndc/rndc.c index cc91793859..099592657c 100644 --- a/bin/rndc/rndc.c +++ b/bin/rndc/rndc.c @@ -75,7 +75,9 @@ static isccc_region_t secret; static bool failed = false; static bool c_flag = false; static isc_mem_t *rndc_mctx; -static isc_refcount_t sends, recvs, connects; +static atomic_uint_fast32_t sends = ATOMIC_VAR_INIT(0); +static atomic_uint_fast32_t recvs = ATOMIC_VAR_INIT(0); +static atomic_uint_fast32_t connects = ATOMIC_VAR_INIT(0); static char *command; static char *args; static char program[256]; @@ -277,8 +279,8 @@ rndc_senddone(isc_task_t *task, isc_event_t *event) { fatal("send failed: %s", isc_result_totext(sevent->result)); } isc_event_free(&event); - if (isc_refcount_decrement(&sends) == 1 && - isc_refcount_current(&recvs) == 0) + if (atomic_fetch_sub_release(&sends, 1) == 1 && + atomic_load_acquire(&recvs) == 0) { isc_socket_detach(&sock); isc_task_shutdown(task); @@ -295,7 +297,7 @@ rndc_recvdone(isc_task_t *task, isc_event_t *event) { char *textmsg = NULL; isc_result_t result; - isc_refcount_decrement(&recvs); + atomic_fetch_sub_release(&recvs, 1); if (ccmsg.result == ISC_R_EOF) fatal("connection to remote host closed\n" @@ -348,8 +350,8 @@ rndc_recvdone(isc_task_t *task, isc_event_t *event) { isc_event_free(&event); isccc_sexpr_free(&response); - if (isc_refcount_current(&sends) == 0 - && isc_refcount_current(&recvs) == 0) { + if (atomic_load_acquire(&sends) == 0 + && atomic_load_acquire(&recvs) == 0) { isc_socket_detach(&sock); isc_task_shutdown(task); isc_app_shutdown(); @@ -369,7 +371,7 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) { isccc_sexpr_t *data; isc_buffer_t b; - isc_refcount_decrement(&recvs); + atomic_fetch_sub_release(&recvs, 1); if (ccmsg.result == ISC_R_EOF) fatal("connection to remote host closed\n" @@ -430,10 +432,10 @@ rndc_recvnonce(isc_task_t *task, isc_event_t *event) { isccc_ccmsg_cancelread(&ccmsg); DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task, rndc_recvdone, NULL)); - isc_refcount_increment(&recvs); + atomic_fetch_add_relaxed(&recvs, 1); DO("send message", isc_socket_send(sock, &r, task, rndc_senddone, NULL)); - isc_refcount_increment(&sends); + atomic_fetch_add_relaxed(&sends, 1); isc_event_free(&event); isccc_sexpr_free(&response); @@ -452,7 +454,7 @@ rndc_connected(isc_task_t *task, isc_event_t *event) { isc_buffer_t b; isc_result_t result; - isc_refcount_decrement(&connects); + atomic_fetch_sub_release(&connects, 1); if (sevent->result != ISC_R_SUCCESS) { isc_sockaddr_format(&serveraddrs[currentaddr], socktext, @@ -498,10 +500,10 @@ rndc_connected(isc_task_t *task, isc_event_t *event) { DO("schedule recv", isccc_ccmsg_readmessage(&ccmsg, task, rndc_recvnonce, NULL)); - isc_refcount_increment(&recvs); + atomic_fetch_add_relaxed(&recvs, 1); DO("send message", isc_socket_send(sock, &r, task, rndc_senddone, NULL)); - isc_refcount_increment(&sends); + atomic_fetch_add_relaxed(&sends, 1); isc_event_free(&event); isccc_sexpr_free(&request); } @@ -536,7 +538,7 @@ rndc_startconnect(isc_sockaddr_t *addr, isc_task_t *task) { } DO("connect", isc_socket_connect(sock, addr, task, rndc_connected, NULL)); - isc_refcount_increment(&connects); + atomic_fetch_add_relaxed(&connects, 1); } static void @@ -1003,9 +1005,9 @@ main(int argc, char **argv) { if (result != ISC_R_SUCCESS) fatal("isc_app_run() failed: %s", isc_result_totext(result)); - if (isc_refcount_current(&connects) > 0 || - isc_refcount_current(&sends) > 0 || - isc_refcount_current(&recvs) > 0) + if (atomic_load_acquire(&connects) > 0 || + atomic_load_acquire(&sends) > 0 || + atomic_load_acquire(&recvs) > 0) { isc_socket_cancel(sock, task, ISC_SOCKCANCEL_ALL); } diff --git a/lib/dns/cache.c b/lib/dns/cache.c index df7184c667..f20c1de8a6 100644 --- a/lib/dns/cache.c +++ b/lib/dns/cache.c @@ -314,8 +314,6 @@ cleanup_filelock: static void cache_free(dns_cache_t *cache) { - int i; - REQUIRE(VALID_CACHE(cache)); isc_refcount_destroy(&cache->references); @@ -359,10 +357,9 @@ cache_free(dns_cache_t *cache) { if (strcmp(cache->db_type, "rbt") == 0) { extra = 1; } - for (i = extra; i < cache->db_argc; i++) { + for (int i = extra; i < cache->db_argc; i++) { if (cache->db_argv[i] != NULL) { - isc_mem_free(cache->mctx, - cache->db_argv[i]); + isc_mem_free(cache->mctx, cache->db_argv[i]); } } isc_mem_put(cache->mctx, cache->db_argv, diff --git a/lib/dns/dispatch.c b/lib/dns/dispatch.c index c70ee9fa25..47ff2bc9bc 100644 --- a/lib/dns/dispatch.c +++ b/lib/dns/dispatch.c @@ -598,8 +598,7 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { dns_qid_t *qid; REQUIRE(disp->port_table != NULL); - REQUIRE(portentry != NULL && - isc_refcount_current(&portentry->refs) > 0); + REQUIRE(portentry != NULL); if (isc_refcount_decrement(&portentry->refs) == 1) { qid = DNS_QID(disp); @@ -617,7 +616,6 @@ deref_portentry(dns_dispatch_t *disp, dispportentry_t **portentryp) { * dispsock->portentry does not change in socket_search. */ *portentryp = NULL; - } /*% diff --git a/lib/dns/include/dns/peer.h b/lib/dns/include/dns/peer.h index 7a25511226..de648e10e7 100644 --- a/lib/dns/include/dns/peer.h +++ b/lib/dns/include/dns/peer.h @@ -32,6 +32,7 @@ #include #include #include +#include #include @@ -47,7 +48,7 @@ struct dns_peerlist { unsigned int magic; - uint32_t refs; + isc_refcount_t refs; isc_mem_t *mem; @@ -56,7 +57,7 @@ struct dns_peerlist { struct dns_peer { unsigned int magic; - uint32_t refs; + isc_refcount_t refs; isc_mem_t *mem; diff --git a/lib/dns/include/dns/resolver.h b/lib/dns/include/dns/resolver.h index 57fa237e58..c6b26914ed 100644 --- a/lib/dns/include/dns/resolver.h +++ b/lib/dns/include/dns/resolver.h @@ -440,16 +440,6 @@ dns_resolver_setlamettl(dns_resolver_t *resolver, uint32_t lame_ttl); *\li 'resolver' to be valid. */ -unsigned int -dns_resolver_nrunning(dns_resolver_t *resolver); -/*%< - * Return the number of currently running resolutions in this - * resolver. This is may be less than the number of outstanding - * fetches due to multiple identical fetches, or more than the - * number of of outstanding fetches due to the fact that resolution - * can continue even though a fetch has been canceled. - */ - isc_result_t dns_resolver_addalternate(dns_resolver_t *resolver, const isc_sockaddr_t *alt, const dns_name_t *name, in_port_t port); diff --git a/lib/dns/keytable.c b/lib/dns/keytable.c index cdc54071e7..60c3275f50 100644 --- a/lib/dns/keytable.c +++ b/lib/dns/keytable.c @@ -40,7 +40,7 @@ struct dns_keytable { /* Unlocked. */ unsigned int magic; isc_mem_t *mctx; - isc_refcount_t active_nodes; + atomic_uint_fast32_t active_nodes; isc_refcount_t references; isc_rwlock_t rwlock; /* Locked by rwlock. */ @@ -90,7 +90,7 @@ dns_keytable_create(isc_mem_t *mctx, dns_keytable_t **keytablep) { goto cleanup_rbt; } - isc_refcount_init(&keytable->active_nodes, 0); + atomic_init(&keytable->active_nodes, 0); isc_refcount_init(&keytable->references, 1); keytable->mctx = NULL; @@ -132,7 +132,7 @@ dns_keytable_detach(dns_keytable_t **keytablep) { if (isc_refcount_decrement(&keytable->references) == 1) { isc_refcount_destroy(&keytable->references); - isc_refcount_destroy(&keytable->active_nodes); + REQUIRE(atomic_load_acquire(&keytable->active_nodes) == 0); dns_rbt_destroy(&keytable->table); isc_rwlock_destroy(&keytable->rwlock); keytable->magic = 0; @@ -481,12 +481,14 @@ dns_keytable_find(dns_keytable_t *keytable, const dns_name_t *keyname, DNS_RBTFIND_NOOPTIONS, NULL, NULL); if (result == ISC_R_SUCCESS) { if (node->data != NULL) { - isc_refcount_increment0(&keytable->active_nodes); - dns_keynode_attach(node->data, keynodep); - } else + dns_keytable_attachkeynode(keytable, node->data, + keynodep); + } else { result = ISC_R_NOTFOUND; - } else if (result == DNS_R_PARTIALMATCH) + } + } else if (result == DNS_R_PARTIALMATCH) { result = ISC_R_NOTFOUND; + } RWUNLOCK(&keytable->rwlock, isc_rwlocktype_read); return (result); @@ -509,8 +511,7 @@ dns_keytable_nextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, return (ISC_R_NOTFOUND); } - dns_keynode_attach(keynode->next, nextnodep); - isc_refcount_increment(&keytable->active_nodes); + dns_keytable_attachkeynode(keytable, keynode->next, nextnodep); return (ISC_R_SUCCESS); } @@ -560,8 +561,7 @@ dns_keytable_findkeynode(dns_keytable_t *keytable, const dns_name_t *name, } } if (knode != NULL) { - isc_refcount_increment0(&keytable->active_nodes); - dns_keynode_attach(knode, keynodep); + dns_keytable_attachkeynode(keytable, knode, keynodep); } else { result = DNS_R_PARTIALMATCH; } @@ -602,9 +602,8 @@ dns_keytable_findnextkeynode(dns_keytable_t *keytable, dns_keynode_t *keynode, } } if (knode != NULL) { - isc_refcount_increment(&keytable->active_nodes); + dns_keytable_attachkeynode(keytable, knode, nextnodep); result = ISC_R_SUCCESS; - dns_keynode_attach(knode, nextnodep); } else { result = ISC_R_NOTFOUND; } @@ -653,7 +652,7 @@ dns_keytable_attachkeynode(dns_keytable_t *keytable, dns_keynode_t *source, REQUIRE(VALID_KEYNODE(source)); REQUIRE(target != NULL && *target == NULL); - isc_refcount_increment(&keytable->active_nodes); + REQUIRE(atomic_fetch_add_relaxed(&keytable->active_nodes, 1) < UINT32_MAX); dns_keynode_attach(source, target); } @@ -668,7 +667,8 @@ dns_keytable_detachkeynode(dns_keytable_t *keytable, dns_keynode_t **keynodep) REQUIRE(VALID_KEYTABLE(keytable)); REQUIRE(keynodep != NULL && VALID_KEYNODE(*keynodep)); - INSIST(isc_refcount_decrement(&keytable->active_nodes) > 0); + REQUIRE(atomic_fetch_sub_release(&keytable->active_nodes, 1) > 0); + dns_keynode_detach(keytable->mctx, keynodep); } @@ -891,7 +891,8 @@ dns_keytable_forall(dns_keytable_t *keytable, } goto cleanup; } - isc_refcount_increment0(&keytable->active_nodes); + REQUIRE(atomic_fetch_add_relaxed(&keytable->active_nodes, 1) + < UINT32_MAX); for (;;) { dns_rbtnodechain_current(&chain, foundname, origin, &node); if (node->data != NULL) { @@ -908,7 +909,7 @@ dns_keytable_forall(dns_keytable_t *keytable, break; } } - INSIST(isc_refcount_decrement(&keytable->active_nodes) > 0); + REQUIRE(atomic_fetch_sub_release(&keytable->active_nodes, 1) > 0); cleanup: dns_rbtnodechain_invalidate(&chain); diff --git a/lib/dns/lib.c b/lib/dns/lib.c index 629d2151dc..1df93d2e61 100644 --- a/lib/dns/lib.c +++ b/lib/dns/lib.c @@ -91,7 +91,7 @@ dns_lib_init(void) { if (!initialize_done) return (ISC_R_FAILURE); - isc_refcount_increment(&references); + isc_refcount_increment0(&references); return (ISC_R_SUCCESS); } diff --git a/lib/dns/master.c b/lib/dns/master.c index fbb13389e1..e7ccc0e04b 100644 --- a/lib/dns/master.c +++ b/lib/dns/master.c @@ -431,16 +431,17 @@ incctx_destroy(isc_mem_t *mctx, dns_incctx_t *ictx) { static void loadctx_destroy(dns_loadctx_t *lctx) { - isc_result_t result; - REQUIRE(DNS_LCTX_VALID(lctx)); + isc_refcount_destroy(&lctx->references); + lctx->magic = 0; - if (lctx->inc != NULL) + if (lctx->inc != NULL) { incctx_destroy(lctx->mctx, lctx->inc); + } if (lctx->f != NULL) { - result = isc_stdio_close(lctx->f); + isc_result_t result = isc_stdio_close(lctx->f); if (result != ISC_R_SUCCESS) { UNEXPECTED_ERROR(__FILE__, __LINE__, "isc_stdio_close() failed: %s", @@ -449,8 +450,9 @@ loadctx_destroy(dns_loadctx_t *lctx) { } /* isc_lex_destroy() will close all open streams */ - if (lctx->lex != NULL && !lctx->keep_lex) + if (lctx->lex != NULL && !lctx->keep_lex) { isc_lex_destroy(&lctx->lex); + } if (lctx->task != NULL) { isc_task_detach(&lctx->task); diff --git a/lib/dns/masterdump.c b/lib/dns/masterdump.c index f8c3b12206..662652bf8a 100644 --- a/lib/dns/masterdump.c +++ b/lib/dns/masterdump.c @@ -234,7 +234,7 @@ struct dns_dumpctx { unsigned int nodes; /* dns_master_dumpinc() */ char *file; - char *tmpfile; + char *tmpfile; dns_masterformat_t format; dns_masterrawheader_t header; isc_result_t (*dumpsets)(isc_mem_t *mctx, diff --git a/lib/dns/peer.c b/lib/dns/peer.c index bcd6d71f0e..bf1ef07d99 100644 --- a/lib/dns/peer.c +++ b/lib/dns/peer.c @@ -62,7 +62,7 @@ dns_peerlist_new(isc_mem_t *mem, dns_peerlist_t **list) { ISC_LIST_INIT(l->elements); l->mem = mem; - l->refs = 1; + isc_refcount_init(&l->refs, 1); l->magic = DNS_PEERLIST_MAGIC; *list = l; @@ -76,9 +76,7 @@ dns_peerlist_attach(dns_peerlist_t *source, dns_peerlist_t **target) { REQUIRE(target != NULL); REQUIRE(*target == NULL); - source->refs++; - - ENSURE(source->refs != 0xffffffffU); + isc_refcount_increment(&source->refs); *target = source; } @@ -94,12 +92,9 @@ dns_peerlist_detach(dns_peerlist_t **list) { plist = *list; *list = NULL; - REQUIRE(plist->refs > 0); - - plist->refs--; - - if (plist->refs == 0) + if (isc_refcount_decrement(&plist->refs) == 1) { peerlist_delete(&plist); + } } static void @@ -112,7 +107,7 @@ peerlist_delete(dns_peerlist_t **list) { l = *list; - REQUIRE(l->refs == 0); + isc_refcount_destroy(&l->refs); server = ISC_LIST_HEAD(l->elements); while (server != NULL) { @@ -218,26 +213,19 @@ dns_peer_newprefix(isc_mem_t *mem, const isc_netaddr_t *addr, { dns_peer_t *peer; - REQUIRE(peerptr != NULL); + REQUIRE(peerptr != NULL && *peerptr == NULL); peer = isc_mem_get(mem, sizeof(*peer)); - peer->magic = DNS_PEER_MAGIC; - peer->address = *addr; - peer->prefixlen = prefixlen; - peer->mem = mem; - peer->bogus = false; - peer->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; + *peer = (dns_peer_t){ + .magic = DNS_PEER_MAGIC, + .address = *addr, + .prefixlen = prefixlen, + .mem = mem, + .transfer_format = dns_one_answer, + }; - memset(&peer->bitflags, 0x0, sizeof(peer->bitflags)); + isc_refcount_init(&peer->refs, 1); 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); - source->refs++; - - ENSURE(source->refs != 0xffffffffU); + isc_refcount_increment(&source->refs); *target = source; } @@ -268,14 +254,11 @@ dns_peer_detach(dns_peer_t **peer) { REQUIRE(DNS_PEER_VALID(*peer)); p = *peer; - - REQUIRE(p->refs > 0); - *peer = NULL; - p->refs--; - if (p->refs == 0) + if (isc_refcount_decrement(&p->refs) == 1) { peer_delete(&p); + } } static void @@ -288,7 +271,7 @@ peer_delete(dns_peer_t **peer) { p = *peer; - REQUIRE(p->refs == 0); + isc_refcount_destroy(&p->refs); mem = p->mem; p->mem = NULL; diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 97084c7af3..266e0213dd 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -1818,7 +1818,7 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { static inline void new_reference(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) { INSIST(!ISC_LINK_LINKED(node, deadlink)); - if (isc_refcount_increment(&node->references) == 0) { + if (isc_refcount_increment0(&node->references) == 0) { /* this is the first reference to the node */ isc_refcount_increment0(&rbtdb->node_locks[node->locknum].references); } @@ -8322,7 +8322,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type, rbtdb->next_serial = 2; rbtdb->current_version = allocate_version(mctx, 1, 1, false); if (rbtdb->current_version == NULL) { - INSIST(isc_refcount_decrement(&rbtdb->references) > 0); + isc_refcount_decrement(&rbtdb->references); free_rbtdb(rbtdb, false, NULL); return (ISC_R_NOMEMORY); } @@ -8343,7 +8343,7 @@ dns_rbtdb_create(isc_mem_t *mctx, const dns_name_t *origin, dns_dbtype_t type, isc_mem_put(mctx, rbtdb->current_version, sizeof(*rbtdb->current_version)); rbtdb->current_version = NULL; - INSIST(isc_refcount_decrement(&rbtdb->references) > 0); + isc_refcount_decrement(&rbtdb->references); free_rbtdb(rbtdb, false, NULL); return (result); } diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index 6fce5cd6c9..c56d320445 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -539,7 +539,7 @@ struct dns_resolver { dns_fetch_t * primefetch; /* Atomic. */ - isc_refcount_t nfctx; + atomic_uint_fast32_t nfctx; }; #define RES_MAGIC ISC_MAGIC('R', 'e', 's', '!') @@ -4322,7 +4322,7 @@ fctx_unlink(fetchctx_t *fctx) { ISC_LIST_UNLINK(res->buckets[bucketnum].fctxs, fctx, link); - isc_refcount_decrement(&res->nfctx); + REQUIRE(atomic_fetch_sub_release(&res->nfctx, 1) > 0); dec_stats(res, dns_resstatscounter_nfetch); @@ -4650,7 +4650,7 @@ fctx_start(isc_task_t *task, isc_event_t *event) { else fctx_try(fctx, false, false); } else if (dodestroy) { - fctx_destroy(fctx); + fctx_destroy(fctx); if (bucket_empty) empty_bucket(res); } @@ -5015,7 +5015,7 @@ fctx_create(dns_resolver_t *res, const dns_name_t *name, dns_rdatatype_t type, ISC_LIST_APPEND(res->buckets[bucketnum].fctxs, fctx, link); - isc_refcount_increment(&res->nfctx); + REQUIRE(atomic_fetch_add_relaxed(&res->nfctx, 1) < UINT32_MAX); inc_stats(res, dns_resstatscounter_nfetch); @@ -6986,7 +6986,7 @@ static void fctx_increference(fetchctx_t *fctx) { REQUIRE(VALID_FCTX(fctx)); - isc_refcount_increment(&fctx->references); + isc_refcount_increment0(&fctx->references); } /* @@ -9799,7 +9799,7 @@ destroy(dns_resolver_t *res) { RTRACE("destroy"); - isc_refcount_destroy(&res->nfctx); + REQUIRE(atomic_load_acquire(&res->nfctx) == 0); isc_mutex_destroy(&res->primelock); isc_mutex_destroy(&res->lock); @@ -10045,7 +10045,7 @@ dns_resolver_create(dns_view_t *view, res->priming = false; res->primefetch = NULL; - isc_refcount_init(&res->nfctx, 0); + atomic_init(&res->nfctx, 0); isc_mutex_init(&res->lock); isc_mutex_init(&res->primelock); @@ -10805,11 +10805,6 @@ dns_resolver_setlamettl(dns_resolver_t *resolver, uint32_t lame_ttl) { resolver->lame_ttl = lame_ttl; } -unsigned int -dns_resolver_nrunning(dns_resolver_t *resolver) { - return (isc_refcount_current(&resolver->nfctx)); -} - isc_result_t dns_resolver_addalternate(dns_resolver_t *resolver, const isc_sockaddr_t *alt, const dns_name_t *name, in_port_t port) { diff --git a/lib/dns/rpz.c b/lib/dns/rpz.c index 5ee338f7c3..018ab5c16a 100644 --- a/lib/dns/rpz.c +++ b/lib/dns/rpz.c @@ -1484,9 +1484,9 @@ cleanup_task: dns_rbt_destroy(&zones->rbt); cleanup_rbt: - INSIST(isc_refcount_decrement(&zones->irefs) == 1); + isc_refcount_decrement(&zones->irefs); isc_refcount_destroy(&zones->irefs); - INSIST(isc_refcount_decrement(&zones->refs) == 1); + isc_refcount_decrement(&zones->refs); isc_refcount_destroy(&zones->refs); isc_mutex_destroy(&zones->maint_lock); @@ -1567,7 +1567,7 @@ cleanup_ht: isc_timer_detach(&zone->updatetimer); cleanup_timer: - INSIST(isc_refcount_decrement(&zone->refs) > 0); + isc_refcount_decrement(&zone->refs); isc_refcount_destroy(&zone->refs); isc_mem_put(rpzs->mctx, zone, sizeof(*zone)); diff --git a/lib/dns/sdb.c b/lib/dns/sdb.c index 64f0112218..fa30944450 100644 --- a/lib/dns/sdb.c +++ b/lib/dns/sdb.c @@ -517,6 +517,8 @@ static void destroy(dns_sdb_t *sdb) { dns_sdbimplementation_t *imp = sdb->implementation; + isc_refcount_destroy(&sdb->references); + if (imp->methods->destroy != NULL) { MAYBE_LOCK(sdb); imp->methods->destroy(sdb->zone, imp->driverdata, diff --git a/lib/dns/sdlz.c b/lib/dns/sdlz.c index ae35ac5ae3..3fa7f5bc5d 100644 --- a/lib/dns/sdlz.c +++ b/lib/dns/sdlz.c @@ -480,6 +480,8 @@ destroynode(dns_sdlznode_t *node) { dns_db_t *db; isc_mem_t *mctx; + isc_refcount_destroy(&node->references); + sdlz = node->sdlz; mctx = sdlz->common.mctx; @@ -504,7 +506,6 @@ destroynode(dns_sdlznode_t *node) { dns_name_free(node->name, mctx); isc_mem_put(mctx, node->name, sizeof(dns_name_t)); } - isc_refcount_destroy(&node->references); node->magic = 0; isc_mem_put(mctx, node, sizeof(dns_sdlznode_t)); diff --git a/lib/dns/stats.c b/lib/dns/stats.c index 11d30e90eb..c05e287dc1 100644 --- a/lib/dns/stats.c +++ b/lib/dns/stats.c @@ -125,6 +125,7 @@ dns_stats_detach(dns_stats_t **statsp) { *statsp = NULL; if (isc_refcount_decrement(&stats->references) == 1) { + isc_refcount_destroy(&stats->references); isc_stats_detach(&stats->counters); isc_mem_putanddetach(&stats->mctx, stats, sizeof(*stats)); } diff --git a/lib/dns/tests/dispatch_test.c b/lib/dns/tests/dispatch_test.c index 3467fa6923..e9b175f260 100644 --- a/lib/dns/tests/dispatch_test.c +++ b/lib/dns/tests/dispatch_test.c @@ -215,7 +215,7 @@ static dns_dispatch_t *dispatch = NULL; static dns_dispentry_t *dispentry = NULL; static atomic_bool first = ATOMIC_VAR_INIT(true); static isc_sockaddr_t local; -static isc_refcount_t responses; +static atomic_uint_fast32_t responses; static void response(isc_task_t *task, isc_event_t *event) { @@ -224,7 +224,7 @@ response(isc_task_t *task, isc_event_t *event) { UNUSED(task); - isc_refcount_increment(&responses); + atomic_fetch_add_relaxed(&responses, 1); if (atomic_compare_exchange_strong(&first, &exp_true, false)) { isc_result_t result = dns_dispatch_getnext(dispentry, &devent); assert_int_equal(result, ISC_R_SUCCESS); @@ -261,7 +261,7 @@ dispatch_getnext(void **state) { UNUSED(state); - isc_refcount_init(&responses, 0); + atomic_init(&responses, 0); result = isc_task_create(taskmgr, 0, &task); assert_int_equal(result, ISC_R_SUCCESS); @@ -313,7 +313,7 @@ dispatch_getnext(void **state) { result = isc_app_run(); assert_int_equal(result, ISC_R_SUCCESS); - assert_int_equal(isc_refcount_current(&responses), 2); + assert_int_equal(atomic_load_acquire(&responses), 2); /* * Shutdown nameserver. diff --git a/lib/dns/tests/zt_test.c b/lib/dns/tests/zt_test.c index 77d36a94f2..b534b4190d 100644 --- a/lib/dns/tests/zt_test.c +++ b/lib/dns/tests/zt_test.c @@ -165,12 +165,14 @@ asyncload_zone(void **state) { dns_db_t *db = NULL; FILE* zonefile, *origfile; char buf[4096]; - atomic_bool done = ATOMIC_VAR_INIT(false); + atomic_bool done; int i = 0; struct args args; UNUSED(state); + atomic_init(&done, false); + result = dns_test_makezone("foo", &zone, NULL, true); assert_int_equal(result, ISC_R_SUCCESS); @@ -266,12 +268,14 @@ asyncload_zt(void **state) { dns_view_t *view; dns_zt_t *zt = NULL; dns_db_t *db = NULL; - atomic_bool done = ATOMIC_VAR_INIT(false); + atomic_bool done; int i = 0; struct args args; UNUSED(state); + atomic_init(&done, false); + result = dns_test_makezone("foo", &zone1, NULL, true); assert_int_equal(result, ISC_R_SUCCESS); dns_zone_setfile(zone1, "testdata/zt/zone1.db", diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c index 6fa7dd4b4a..83f76b97dd 100644 --- a/lib/dns/tsig.c +++ b/lib/dns/tsig.c @@ -349,7 +349,7 @@ dns_tsigkey_createfromkey(const dns_name_t *name, const dns_name_t *algorithm, cleanup_refs: tkey->magic = 0; while (refs-- > 0) { - INSIST(isc_refcount_decrement(&tkey->refs) > 0); + isc_refcount_decrement(&tkey->refs); } isc_refcount_destroy(&tkey->refs); @@ -431,6 +431,7 @@ cleanup_ring(dns_tsig_keyring_t *ring) static void destroyring(dns_tsig_keyring_t *ring) { + isc_refcount_destroy(&ring->references); dns_rbt_destroy(&ring->keys); isc_rwlock_destroy(&ring->lock); isc_mem_putanddetach(&ring->mctx, ring, sizeof(dns_tsig_keyring_t)); @@ -614,14 +615,16 @@ dns_tsigkeyring_dumpanddetach(dns_tsig_keyring_t **ringp, FILE *fp) { node = NULL; dns_rbtnodechain_current(&chain, &foundname, origin, &node); tkey = node->data; - if (tkey != NULL && tkey->generated && tkey->expire >= now) + if (tkey != NULL && tkey->generated && tkey->expire >= now) { dump_key(tkey, fp); + } result = dns_rbtnodechain_next(&chain, &foundname, origin); if (result != ISC_R_SUCCESS && result != DNS_R_NEWORIGIN) { dns_rbtnodechain_invalidate(&chain); - if (result == ISC_R_NOMORE) + if (result == ISC_R_NOMORE) { result = ISC_R_SUCCESS; + } goto destroy; } } diff --git a/lib/dns/win32/libdns.def.in b/lib/dns/win32/libdns.def.in index d77368debb..65c4a7ddec 100644 --- a/lib/dns/win32/libdns.def.in +++ b/lib/dns/win32/libdns.def.in @@ -933,7 +933,6 @@ dns_resolver_gettimeout dns_resolver_getudpsize dns_resolver_getzeronosoattl dns_resolver_logfetch -dns_resolver_nrunning dns_resolver_prime dns_resolver_printbadcache dns_resolver_reset_algorithms diff --git a/lib/dns/zone.c b/lib/dns/zone.c index aeb58365f6..1de8b8283e 100644 --- a/lib/dns/zone.c +++ b/lib/dns/zone.c @@ -205,7 +205,7 @@ struct dns_zone { dns_zonemgr_t *zmgr; ISC_LINK(dns_zone_t) link; /* Used by zmgr. */ isc_timer_t *timer; - unsigned int irefs; + isc_refcount_t irefs; dns_name_t origin; char *masterfile; ISC_LIST(dns_include_t) includes; /* Include files */ @@ -529,7 +529,7 @@ struct dns_unreachable { struct dns_zonemgr { unsigned int magic; isc_mem_t * mctx; - int refs; /* Locked by rwlock */ + isc_refcount_t refs; isc_taskmgr_t * taskmgr; isc_timermgr_t * timermgr; isc_socketmgr_t * socketmgr; @@ -921,8 +921,8 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { zone->db = NULL; zone->zmgr = NULL; ISC_LINK_INIT(zone, link); - isc_refcount_init(&zone->erefs, 1); /* Implicit attach. */ - zone->irefs = 0; + isc_refcount_init(&zone->erefs, 1); + isc_refcount_init(&zone->irefs, 0); dns_name_init(&zone->origin, NULL); zone->strnamerd = 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, dns_gluecachestatscounter_max); if (result != ISC_R_SUCCESS) { - goto free_erefs; + goto free_refs; } /* Must be after magic is set. */ @@ -1085,9 +1085,10 @@ dns_zone_create(dns_zone_t **zonep, isc_mem_t *mctx) { *zonep = zone; return (ISC_R_SUCCESS); - free_erefs: - INSIST(isc_refcount_decrement(&zone->erefs) > 0); + free_refs: + isc_refcount_decrement(&zone->erefs); isc_refcount_destroy(&zone->erefs); + isc_refcount_destroy(&zone->irefs); ZONEDB_DESTROYLOCK(&zone->dblock); @@ -1110,8 +1111,8 @@ zone_free(dns_zone_t *zone) { dns_include_t *include; REQUIRE(DNS_ZONE_VALID(zone)); - REQUIRE(isc_refcount_current(&zone->erefs) == 0); - REQUIRE(zone->irefs == 0); + isc_refcount_destroy(&zone->erefs); + isc_refcount_destroy(&zone->irefs); REQUIRE(!LOCKED_ZONE(zone)); REQUIRE(zone->timer == NULL); REQUIRE(zone->zmgr == NULL); @@ -5110,7 +5111,9 @@ static bool exit_check(dns_zone_t *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. */ @@ -5468,7 +5471,7 @@ dns_zone_detach(dns_zone_t **zonep) { void dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { REQUIRE(DNS_ZONE_VALID(source)); - REQUIRE(target != NULL && *target == NULL); + LOCK_ZONE(source); zone_iattach(source, target); UNLOCK_ZONE(source); @@ -5476,19 +5479,15 @@ dns_zone_iattach(dns_zone_t *source, dns_zone_t **target) { static void zone_iattach(dns_zone_t *source, dns_zone_t **target) { - - /* - * 'source' locked by caller. - */ REQUIRE(DNS_ZONE_VALID(source)); REQUIRE(LOCKED_ZONE(source)); REQUIRE(target != NULL && *target == NULL); - INSIST(source->irefs + isc_refcount_current(&source->erefs) > 0); - source->irefs++; - INSIST(source->irefs != 0); + INSIST(isc_refcount_increment0(&source->irefs) + + isc_refcount_current(&source->erefs) > 0); *target = source; } + static void zone_idetach(dns_zone_t **zonep) { dns_zone_t *zone; @@ -5497,13 +5496,13 @@ zone_idetach(dns_zone_t **zonep) { * 'zone' locked by caller. */ REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); - zone = *zonep; REQUIRE(LOCKED_ZONE(*zonep)); + + zone = *zonep; *zonep = NULL; - INSIST(zone->irefs > 0); - zone->irefs--; - INSIST(zone->irefs + isc_refcount_current(&zone->erefs) > 0); + INSIST(isc_refcount_decrement(&zone->irefs) - 1 + + isc_refcount_current(&zone->erefs) > 0); } void @@ -5512,16 +5511,18 @@ dns_zone_idetach(dns_zone_t **zonep) { bool free_needed; REQUIRE(zonep != NULL && DNS_ZONE_VALID(*zonep)); + zone = *zonep; *zonep = NULL; - LOCK_ZONE(zone); - INSIST(zone->irefs > 0); - zone->irefs--; - free_needed = exit_check(zone); - UNLOCK_ZONE(zone); - if (free_needed) - zone_free(zone); + if (isc_refcount_decrement(&zone->irefs) == 1) { + LOCK_ZONE(zone); + free_needed = exit_check(zone); + UNLOCK_ZONE(zone); + if (free_needed) { + zone_free(zone); + } + } } isc_mem_t * @@ -10405,8 +10406,8 @@ keyfetch_done(isc_task_t *task, isc_event_t *event) { cleanup: dns_db_detach(&kfetch->db); - INSIST(zone->irefs > 0); - zone->irefs--; + isc_refcount_decrement(&zone->irefs); + kfetch->zone = NULL; if (dns_rdataset_isassociated(keydataset)) { @@ -10537,8 +10538,7 @@ zone_refreshkeys(dns_zone_t *zone) { zone->refreshkeycount++; kfetch->zone = zone; - zone->irefs++; - INSIST(zone->irefs != 0); + isc_refcount_increment0(&zone->irefs); kname = dns_fixedname_initname(&kfetch->name); dns_name_dup(name, zone->mctx, kname); dns_rdataset_init(&kfetch->dnskeyset); @@ -10592,7 +10592,7 @@ zone_refreshkeys(dns_zone_t *zone) { fetching = true; } else { zone->refreshkeycount--; - zone->irefs--; + isc_refcount_decrement(&zone->irefs); dns_db_detach(&kfetch->db); dns_rdataset_disassociate(&kfetch->keydataset); dns_name_free(kname, zone->mctx); @@ -13583,8 +13583,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { LOCK_ZONE(zone); INSIST(zone != zone->raw); if (linked) { - INSIST(zone->irefs > 0); - zone->irefs--; + isc_refcount_decrement(&zone->irefs); } if (zone->request != NULL) { dns_request_cancel(zone->request); @@ -13611,8 +13610,7 @@ zone_shutdown(isc_task_t *task, isc_event_t *event) { if (zone->timer != NULL) { isc_timer_detach(&zone->timer); - INSIST(zone->irefs > 0); - zone->irefs--; + isc_refcount_decrement(&zone->irefs); } /* @@ -15208,8 +15206,7 @@ receive_secure_serial(isc_task_t *task, isc_event_t *event) { if (event != NULL) { LOCK_ZONE(zone); - INSIST(zone->irefs > 1); - zone->irefs--; + isc_refcount_decrement(&zone->irefs); ISC_LIST_UNLINK(zone->rss_events, event, ev_link); goto nextevent; } @@ -16215,8 +16212,7 @@ zone_xfrdone(dns_zone_t *zone, isc_result_t result) { if (again && !DNS_ZONE_FLAG(zone, DNS_ZONEFLG_EXITING)) queue_soa_query(zone); - INSIST(zone->irefs > 0); - zone->irefs--; + isc_refcount_decrement(&zone->irefs); free_needed = exit_check(zone); UNLOCK_ZONE(zone); if (free_needed) @@ -16380,9 +16376,7 @@ queue_xfrin(dns_zone_t *zone) { RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); ISC_LIST_APPEND(zmgr->waiting_for_xfrin, zone, statelink); - LOCK_ZONE(zone); - zone->irefs++; - UNLOCK_ZONE(zone); + isc_refcount_increment0(&zone->irefs); zone->statelist = &zmgr->waiting_for_xfrin; result = zmgr_start_xfrin_ifquota(zmgr, zone); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); @@ -16850,7 +16844,7 @@ dns_zonemgr_create(isc_mem_t *mctx, isc_taskmgr_t *taskmgr, zmgr = isc_mem_get(mctx, sizeof(*zmgr)); zmgr->mctx = NULL; - zmgr->refs = 1; + isc_refcount_init(&zmgr->refs, 1); isc_mem_attach(mctx, &zmgr->mctx); zmgr->taskmgr = taskmgr; zmgr->timermgr = timermgr; @@ -17012,12 +17006,11 @@ dns_zonemgr_managezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { /* * The timer "holds" a iref. */ - zone->irefs++; - INSIST(zone->irefs != 0); + isc_refcount_increment0(&zone->irefs); ISC_LIST_APPEND(zmgr->zones, zone, link); zone->zmgr = zmgr; - zmgr->refs++; + isc_refcount_increment(&zmgr->refs); goto unlock; @@ -17044,9 +17037,10 @@ dns_zonemgr_releasezone(dns_zonemgr_t *zmgr, dns_zone_t *zone) { ISC_LIST_UNLINK(zmgr->zones, zone, link); zone->zmgr = NULL; - zmgr->refs--; - if (zmgr->refs == 0) + + if (isc_refcount_decrement(&zmgr->refs) == 1) { free_now = true; + } UNLOCK_ZONE(zone); RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); @@ -17061,31 +17055,23 @@ dns_zonemgr_attach(dns_zonemgr_t *source, dns_zonemgr_t **target) { REQUIRE(DNS_ZONEMGR_VALID(source)); REQUIRE(target != NULL && *target == NULL); - RWLOCK(&source->rwlock, isc_rwlocktype_write); - REQUIRE(source->refs > 0); - source->refs++; - INSIST(source->refs > 0); - RWUNLOCK(&source->rwlock, isc_rwlocktype_write); + isc_refcount_increment(&source->refs); + *target = source; } void dns_zonemgr_detach(dns_zonemgr_t **zmgrp) { dns_zonemgr_t *zmgr; - bool free_now = false; REQUIRE(zmgrp != NULL); zmgr = *zmgrp; REQUIRE(DNS_ZONEMGR_VALID(zmgr)); - RWLOCK(&zmgr->rwlock, isc_rwlocktype_write); - zmgr->refs--; - if (zmgr->refs == 0) - free_now = true; - RWUNLOCK(&zmgr->rwlock, isc_rwlocktype_write); - - if (free_now) + if (isc_refcount_decrement(&zmgr->refs) == 1) { zonemgr_free(zmgr); + } + *zmgrp = NULL; } @@ -17256,11 +17242,11 @@ static void zonemgr_free(dns_zonemgr_t *zmgr) { isc_mem_t *mctx; - INSIST(zmgr->refs == 0); INSIST(ISC_LIST_EMPTY(zmgr->zones)); zmgr->magic = 0; + isc_refcount_destroy(&zmgr->refs); isc_mutex_destroy(&zmgr->iolock); isc_ratelimiter_detach(&zmgr->notifyrl); isc_ratelimiter_detach(&zmgr->refreshrl); @@ -19514,9 +19500,7 @@ dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { /* * The timer "holds" a iref. */ - raw->irefs++; - INSIST(raw->irefs != 0); - + isc_refcount_increment0(&raw->irefs); /* dns_zone_attach(raw, &zone->raw); */ isc_refcount_increment(&raw->erefs); @@ -19530,7 +19514,7 @@ dns_zone_link(dns_zone_t *zone, dns_zone_t *raw) { ISC_LIST_APPEND(zmgr->zones, raw, link); raw->zmgr = zmgr; - zmgr->refs++; + isc_refcount_increment(&zmgr->refs); unlock: UNLOCK_ZONE(raw); diff --git a/lib/dns/zt.c b/lib/dns/zt.c index 5b410b1831..43120c75d4 100644 --- a/lib/dns/zt.c +++ b/lib/dns/zt.c @@ -371,15 +371,12 @@ asyncload(dns_zone_t *zone, void *zt_) { result = dns_zone_asyncload(zone, zt->loadparams->newonly, *zt->loadparams->dl, zt); if (result != ISC_R_SUCCESS) { - uint_fast32_t oldref; /* * Caller is holding a reference to zt->loads_pending * and zt->references so these can't decrement to zero. */ - oldref = isc_refcount_decrement(&zt->loads_pending); - INSIST(oldref > 1); - oldref = isc_refcount_decrement(&zt->references); - INSIST(oldref > 1); + INSIST(isc_refcount_decrement(&zt->loads_pending) > 1); + INSIST(isc_refcount_decrement(&zt->references) > 1); } return (ISC_R_SUCCESS); } diff --git a/lib/isc/include/isc/refcount.h b/lib/isc/include/isc/refcount.h index 4e7f4d439f..32ac95a76e 100644 --- a/lib/isc/include/isc/refcount.h +++ b/lib/isc/include/isc/refcount.h @@ -52,15 +52,15 @@ typedef atomic_uint_fast32_t isc_refcount_t; * atomic_load_explicit() by casting to uint_fast32_t. */ -#define isc_refcount_current(target) \ - (uint_fast32_t)atomic_load_explicit(target, memory_order_acquire) +#define isc_refcount_current(target) \ + (uint_fast32_t)atomic_load_acquire(target) /** \def isc_refcount_destroy(ref) * \brief a destructor that makes sure that all references were cleared. * \param[in] ref pointer to reference counter. * \returns nothing. */ -#define isc_refcount_destroy(target) \ +#define isc_refcount_destroy(target) \ ISC_REQUIRE(isc_refcount_current(target) == 0) /** \def isc_refcount_increment0(ref) @@ -68,23 +68,71 @@ typedef atomic_uint_fast32_t isc_refcount_t; * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_increment0(target) \ - isc_refcount_increment(target) +#if _MSC_VER +static inline uint_fast32_t +isc_refcount_increment0(isc_refcount_t *target) { + uint_fast32_t __v; + __v = (uint_fast32_t)atomic_fetch_add_relaxed(target, 1); + INSIST(__v < UINT32_MAX); + return (__v); +} +#else /* _MSC_VER */ +#define isc_refcount_increment0(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_add_relaxed(target, 1); \ + INSIST(__v < UINT32_MAX); \ + __v; \ + }) +#endif /* _MSC_VER */ /** \def isc_refcount_increment(ref) * \brief increases reference counter by 1. * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_increment(target) \ - atomic_fetch_add_explicit(target, 1, memory_order_relaxed) +#if _MSC_VER +static inline uint_fast32_t +isc_refcount_increment(isc_refcount_t *target) { + uint_fast32_t __v; + __v = (uint_fast32_t)atomic_fetch_add_relaxed(target, 1); + INSIST(__v > 0 && __v < UINT32_MAX); + return(__v); +} +#else /* _MSC_VER */ +#define isc_refcount_increment(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_add_relaxed(target, 1); \ + INSIST(__v > 0 && __v < UINT32_MAX); \ + __v; \ + }) +#endif /* _MSC_VER */ /** \def isc_refcount_decrement(ref) * \brief decreases reference counter by 1. * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_decrement(target) \ - atomic_fetch_sub_explicit(target, 1, memory_order_release) +#if _MSC_VER +static inline uint_fast32_t +isc_refcount_decrement(isc_refcount_t *target) { + uint_fast32_t __v; + __v = (uint_fast32_t)atomic_fetch_sub_release(target, 1); + INSIST(__v > 0); + return(__v); +} +#else /* _MSC_VER */ +#define isc_refcount_decrement(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_sub_release(target, 1); \ + INSIST(__v > 0); \ + __v; \ + }) +#endif /* _MSC_VER */ ISC_LANG_ENDDECLS diff --git a/lib/isc/log.c b/lib/isc/log.c index cb6238562d..65c56774a8 100644 --- a/lib/isc/log.c +++ b/lib/isc/log.c @@ -1448,8 +1448,8 @@ isc_log_open(isc_logchannel_t *channel) { return (result); } -bool -isc_log_wouldlog(isc_log_t *lctx, int level) ISC_NO_SANITIZE { +bool ISC_NO_SANITIZE +isc_log_wouldlog(isc_log_t *lctx, int level) { /* * Try to avoid locking the mutex for messages which can't * possibly be logged to any channels -- primarily debugging diff --git a/lib/isc/mem.c b/lib/isc/mem.c index fc7a68e31a..d471891033 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -982,11 +982,11 @@ isc_mem_destroy(isc_mem_t **ctxp) { REQUIRE(VALID_CONTEXT(ctx)); #if ISC_MEM_TRACKLINES - if (isc_refcount_decrement(&ctx->references) != 1) { + if (isc_refcount_decrement(&ctx->references) > 1) { print_active(ctx, stderr); } #else - INSIST(isc_refcount_decrement(&ctx->references) == 1); + isc_refcount_decrement(&ctx->references); #endif isc_refcount_destroy(&ctx->references); destroy(ctx); diff --git a/lib/isc/netmgr/netmgr.c b/lib/isc/netmgr/netmgr.c index 80af9f09b3..ffde1a2157 100644 --- a/lib/isc/netmgr/netmgr.c +++ b/lib/isc/netmgr/netmgr.c @@ -356,13 +356,10 @@ isc_nm_resume(isc_nm_t *mgr) { void isc_nm_attach(isc_nm_t *mgr, isc_nm_t **dst) { - int refs; - REQUIRE(VALID_NM(mgr)); REQUIRE(dst != NULL && *dst == NULL); - refs = isc_refcount_increment(&mgr->references); - INSIST(refs > 0); + isc_refcount_increment(&mgr->references); *dst = mgr; } @@ -370,7 +367,6 @@ isc_nm_attach(isc_nm_t *mgr, isc_nm_t **dst) { void isc_nm_detach(isc_nm_t **mgr0) { isc_nm_t *mgr = NULL; - int references; REQUIRE(mgr0 != NULL); REQUIRE(VALID_NM(*mgr0)); @@ -378,9 +374,7 @@ isc_nm_detach(isc_nm_t **mgr0) { mgr = *mgr0; *mgr0 = NULL; - references = isc_refcount_decrement(&mgr->references); - INSIST(references > 0); - if (references == 1) { + if (isc_refcount_decrement(&mgr->references) == 1) { nm_destroy(&mgr); } } @@ -704,9 +698,9 @@ isc_nmsocket_attach(isc_nmsocket_t *sock, isc_nmsocket_t **target) { if (sock->parent != NULL) { INSIST(sock->parent->parent == NULL); /* sanity check */ - isc_refcount_increment(&sock->parent->references); + isc_refcount_increment0(&sock->parent->references); } else { - isc_refcount_increment(&sock->references); + isc_refcount_increment0(&sock->references); } *target = sock; @@ -888,7 +882,6 @@ isc_nmsocket_detach(isc_nmsocket_t **sockp) { REQUIRE(VALID_NMSOCK(*sockp)); isc_nmsocket_t *sock = *sockp, *rsock = NULL; - int references; *sockp = NULL; /* @@ -902,9 +895,7 @@ isc_nmsocket_detach(isc_nmsocket_t **sockp) { rsock = sock; } - references = isc_refcount_decrement(&rsock->references); - INSIST(references > 0); - if (references == 1) { + if (isc_refcount_decrement(&rsock->references) == 1) { isc__nmsocket_prep_destroy(rsock); } @@ -1045,7 +1036,7 @@ isc__nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer, handle = alloc_handle(sock); } else { INSIST(VALID_NMHANDLE(handle)); - isc_refcount_increment(&handle->references); + isc_refcount_increment0(&handle->references); } handle->sock = sock; @@ -1104,13 +1095,9 @@ isc__nmhandle_get(isc_nmsocket_t *sock, isc_sockaddr_t *peer, void isc_nmhandle_ref(isc_nmhandle_t *handle) { - int refs; - REQUIRE(VALID_NMHANDLE(handle)); - refs = isc_refcount_increment(&handle->references); - INSIST(refs > 0); - + isc_refcount_increment(&handle->references); } bool @@ -1169,13 +1156,10 @@ nmhandle_deactivate(isc_nmsocket_t *sock, isc_nmhandle_t *handle) { void isc_nmhandle_unref(isc_nmhandle_t *handle) { isc_nmsocket_t *sock = NULL; - int refs; REQUIRE(VALID_NMHANDLE(handle)); - refs = isc_refcount_decrement(&handle->references); - INSIST(refs > 0); - if (refs > 1) { + if (isc_refcount_decrement(&handle->references) > 1) { return; } diff --git a/lib/isc/ratelimiter.c b/lib/isc/ratelimiter.c index cf97ad7b39..8bee4e7e0f 100644 --- a/lib/isc/ratelimiter.c +++ b/lib/isc/ratelimiter.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -32,7 +33,7 @@ typedef enum { struct isc_ratelimiter { isc_mem_t * mctx; isc_mutex_t lock; - int refs; + isc_refcount_t references; isc_task_t * task; isc_timer_t * timer; isc_interval_t interval; @@ -60,14 +61,15 @@ isc_ratelimiter_create(isc_mem_t *mctx, isc_timermgr_t *timermgr, INSIST(ratelimiterp != NULL && *ratelimiterp == NULL); rl = isc_mem_get(mctx, sizeof(*rl)); - rl->mctx = mctx; - rl->refs = 1; - rl->task = task; + *rl = (isc_ratelimiter_t){ + .mctx = mctx, + .task = task, + .pertic = 1, + .state = isc_ratelimiter_idle, + }; + + isc_refcount_init(&rl->references, 1); 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_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 * (soon) have events outstanding. */ - rl->refs++; + isc_refcount_increment(&rl->references); ISC_EVENT_INIT(&rl->shutdownevent, sizeof(isc_event_t), @@ -213,14 +215,14 @@ ratelimiter_tick(isc_task_t *task, isc_event_t *event) { */ ISC_LIST_UNLINK(rl->pending, p, ev_ratelink); } else { - isc_result_t result; /* * No work left to do. Stop the timer so that we don't * waste resources by having it fire periodically. */ - result = isc_timer_reset(rl->timer, - isc_timertype_inactive, - NULL, NULL, false); + isc_result_t result = + isc_timer_reset(rl->timer, + isc_timertype_inactive, + NULL, NULL, false); RUNTIME_CHECK(result == ISC_R_SUCCESS); rl->state = isc_ratelimiter_idle; pertic = 0; /* Force the loop to exit. */ @@ -237,7 +239,6 @@ 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); @@ -246,9 +247,9 @@ 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; ISC_LIST_UNLINK(rl->pending, ev, ev_ratelink); ev->ev_attributes |= ISC_EVENTATTR_CANCELED; - task = ev->ev_sender; isc_task_send(task, &ev); } isc_timer_detach(&rl->timer); @@ -280,36 +281,25 @@ ratelimiter_free(isc_ratelimiter_t *rl) { void isc_ratelimiter_attach(isc_ratelimiter_t *source, isc_ratelimiter_t **target) { - REQUIRE(source != NULL); REQUIRE(target != NULL && *target == NULL); - LOCK(&source->lock); - REQUIRE(source->refs > 0); - source->refs++; - INSIST(source->refs > 0); - UNLOCK(&source->lock); + isc_refcount_increment(&source->references); + *target = source; } void isc_ratelimiter_detach(isc_ratelimiter_t **rlp) { isc_ratelimiter_t *rl; - bool free_now = false; REQUIRE(rlp != NULL && *rlp != NULL); rl = *rlp; - LOCK(&rl->lock); - REQUIRE(rl->refs > 0); - rl->refs--; - if (rl->refs == 0) - free_now = true; - UNLOCK(&rl->lock); - - if (free_now) + if (isc_refcount_decrement(&rl->references) == 1) { ratelimiter_free(rl); + } *rlp = NULL; } diff --git a/lib/isc/stats.c b/lib/isc/stats.c index 4f7f283b2f..7a4f38c9b8 100644 --- a/lib/isc/stats.c +++ b/lib/isc/stats.c @@ -82,6 +82,7 @@ isc_stats_detach(isc_stats_t **statsp) { *statsp = NULL; if (isc_refcount_decrement(&stats->references) == 1) { + isc_refcount_destroy(&stats->references); isc_mem_put(stats->mctx, stats->counters, sizeof(isc__atomic_statcounter_t) * stats->ncounters); diff --git a/lib/isc/task.c b/lib/isc/task.c index 7ec362024c..33114993d4 100644 --- a/lib/isc/task.c +++ b/lib/isc/task.c @@ -238,11 +238,12 @@ task_finished(isc__task_t *task) { REQUIRE(EMPTY(task->events)); REQUIRE(task->nevents == 0); REQUIRE(EMPTY(task->on_shutdown)); - REQUIRE(atomic_load(&task->references) == 0); REQUIRE(task->state == task_state_done); XTRACE("task_finished"); + isc_refcount_destroy(&task->references); + LOCK(&manager->lock); UNLINK(manager->tasks, task, link); atomic_fetch_sub(&manager->tasks_count, 1); diff --git a/lib/isc/unix/socket.c b/lib/isc/unix/socket.c index b0699f099c..eebce42f89 100644 --- a/lib/isc/unix/socket.c +++ b/lib/isc/unix/socket.c @@ -1933,7 +1933,7 @@ free_socket(isc__socket_t **socketp) { isc__socket_t *sock = *socketp; INSIST(VALID_SOCKET(sock)); - INSIST(isc_refcount_current(&sock->references) == 0); + isc_refcount_destroy(&sock->references); LOCK(&sock->lock); INSIST(!sock->connecting); INSIST(ISC_LIST_EMPTY(sock->recv_list)); @@ -2489,7 +2489,7 @@ socket_create(isc_socketmgr_t *manager0, int pf, isc_sockettype_t type, abort(); } sock->threadid = gen_threadid(sock); - isc_refcount_increment(&sock->references); + isc_refcount_increment0(&sock->references); thread = &manager->threads[sock->threadid]; *socketp = (isc_socket_t *)sock; @@ -3149,7 +3149,7 @@ process_fd(isc__socketthread_t *thread, int fd, bool readable, return; } - if (isc_refcount_increment(&sock->references) == 0) { + if (isc_refcount_increment0(&sock->references) == 0) { /* * Sock is being closed, it will be destroyed, bail. */ @@ -4678,7 +4678,7 @@ isc_socket_accept(isc_socket_t *sock0, UNLOCK(&sock->lock); return (ISC_R_SHUTTINGDOWN); } - isc_refcount_increment(&nsock->references); + isc_refcount_increment0(&nsock->references); nsock->statsindex = sock->statsindex; dev->ev_sender = ntask; diff --git a/lib/isc/win32/socket.c b/lib/isc/win32/socket.c index 2226374ab9..2d2c67a6bb 100644 --- a/lib/isc/win32/socket.c +++ b/lib/isc/win32/socket.c @@ -1736,7 +1736,7 @@ isc_socket_attach(isc_socket_t *sock, isc_socket_t **socketp) { CONSISTENT(sock); UNLOCK(&sock->lock); - isc_refcount_increment(&sock->references); + isc_refcount_increment0(&sock->references); *socketp = sock; } @@ -3114,7 +3114,7 @@ isc_socket_accept(isc_socket_t *sock, UNLOCK(&sock->lock); return (ISC_R_SHUTTINGDOWN); } - isc_refcount_increment(&nsock->references); + isc_refcount_increment0(&nsock->references); adev->ev_sender = ntask; adev->newsocket = nsock; diff --git a/lib/ns/client.c b/lib/ns/client.c index c178c043c6..a7878aa8a0 100644 --- a/lib/ns/client.c +++ b/lib/ns/client.c @@ -2347,7 +2347,7 @@ clientmgr_attach(ns_clientmgr_t *source, ns_clientmgr_t **targetp) { REQUIRE(VALID_MANAGER(source)); REQUIRE(targetp != NULL && *targetp == NULL); - oldrefs = isc_refcount_increment(&source->references); + oldrefs = isc_refcount_increment0(&source->references); isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), "clientmgr @%p attach: %d", source, oldrefs + 1); @@ -2358,9 +2358,7 @@ clientmgr_attach(ns_clientmgr_t *source, ns_clientmgr_t **targetp) { static void clientmgr_detach(ns_clientmgr_t **mp) { ns_clientmgr_t *mgr = *mp; - int32_t oldrefs; - oldrefs = isc_refcount_decrement(&mgr->references); - INSIST(oldrefs > 0); + int32_t oldrefs = isc_refcount_decrement(&mgr->references); isc_log_write(ns_lctx, NS_LOGCATEGORY_CLIENT, NS_LOGMODULE_CLIENT, ISC_LOG_DEBUG(3), @@ -2380,6 +2378,7 @@ clientmgr_destroy(ns_clientmgr_t *manager) { MTRACE("clientmgr_destroy"); + isc_refcount_destroy(&manager->references); manager->magic = 0; #if CLIENT_NMCTXS > 0 @@ -2479,7 +2478,6 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) { isc_result_t result; ns_clientmgr_t *manager; bool unlock = false; - int32_t oldrefs; REQUIRE(managerp != NULL); manager = *managerp; @@ -2503,8 +2501,7 @@ ns_clientmgr_destroy(ns_clientmgr_t **managerp) { isc_task_endexclusive(manager->excl); } - oldrefs = isc_refcount_decrement(&manager->references); - if (oldrefs == 1) { + if (isc_refcount_decrement(&manager->references) == 1) { clientmgr_destroy(manager); } diff --git a/lib/ns/interfacemgr.c b/lib/ns/interfacemgr.c index 60f916de48..df1fe63aab 100644 --- a/lib/ns/interfacemgr.c +++ b/lib/ns/interfacemgr.c @@ -300,6 +300,8 @@ static void ns_interfacemgr_destroy(ns_interfacemgr_t *mgr) { REQUIRE(NS_INTERFACEMGR_VALID(mgr)); + isc_refcount_destroy(&mgr->references); + #ifdef USE_ROUTE_SOCKET if (mgr->route != NULL) isc_socket_detach(&mgr->route); @@ -338,7 +340,7 @@ ns_interfacemgr_getaclenv(ns_interfacemgr_t *mgr) { void ns_interfacemgr_attach(ns_interfacemgr_t *source, ns_interfacemgr_t **target) { REQUIRE(NS_INTERFACEMGR_VALID(source)); - INSIST(isc_refcount_increment(&source->references) > 0); + isc_refcount_increment(&source->references); *target = source; } diff --git a/lib/ns/lib.c b/lib/ns/lib.c index c4c3fe6266..f2576632e9 100644 --- a/lib/ns/lib.c +++ b/lib/ns/lib.c @@ -68,7 +68,7 @@ ns_lib_init(void) { if (!initialize_done) return (ISC_R_FAILURE); - isc_refcount_increment(&references); + isc_refcount_increment0(&references); return (ISC_R_SUCCESS); } @@ -76,6 +76,7 @@ ns_lib_init(void) { void ns_lib_shutdown(void) { if (isc_refcount_decrement(&references) == 1) { + isc_refcount_destroy(&references); if (ns_g_mctx != NULL) { isc_mem_detach(&ns_g_mctx); }