#include <stdbool.h>
+#include <isc/refcount.h>
#include <isc/result.h>
#include <isc/util.h>
#include <isc/mutex.h>
dns_db_t common;
isc_mutex_t lock;
+ /* Protected by atomics */
+ isc_refcount_t references;
+
/* Locked */
- unsigned int references;
ISC_LIST(struct dns_ecdbnode) nodes;
} dns_ecdb_t;
/* Locked */
ISC_LIST(struct rdatasetheader) rdatasets;
- unsigned int references;
+
+ /* Protected by atomics */
+ isc_refcount_t references;
} dns_ecdbnode_t;
typedef struct rdatasetheader {
REQUIRE(VALID_ECDB(ecdb));
REQUIRE(targetp != NULL && *targetp == NULL);
- LOCK(&ecdb->lock);
- ecdb->references++;
- UNLOCK(&ecdb->lock);
+ isc_refcount_increment(&ecdb->references);
*targetp = source;
}
dns_name_free(&ecdb->common.origin, mctx);
isc_mutex_destroy(&ecdb->lock);
+ isc_refcount_destroy(&ecdb->references);
ecdb->common.impmagic = 0;
ecdb->common.magic = 0;
REQUIRE(VALID_ECDB(ecdb));
LOCK(&ecdb->lock);
- ecdb->references--;
- if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
+ if (isc_refcount_decrement(&ecdb->references) == 1 &&
+ ISC_LIST_EMPTY(ecdb->nodes)) {
need_destroy = true;
+ }
UNLOCK(&ecdb->lock);
if (need_destroy)
REQUIRE(VALID_ECDBNODE(node));
REQUIRE(targetp != NULL && *targetp == NULL);
- LOCK(&node->lock);
- INSIST(node->references > 0);
- node->references++;
- INSIST(node->references != 0); /* Catch overflow. */
- UNLOCK(&node->lock);
+ isc_refcount_increment(&node->references);
*targetp = node;
}
LOCK(&ecdb->lock);
ISC_LIST_UNLINK(ecdb->nodes, node, link);
- if (ecdb->references == 0 && ISC_LIST_EMPTY(ecdb->nodes))
+ if (isc_refcount_current(&ecdb->references) == 0 &&
+ ISC_LIST_EMPTY(ecdb->nodes)) {
need_destroydb = true;
+ }
UNLOCK(&ecdb->lock);
dns_name_free(&node->name, mctx);
}
isc_mutex_destroy(&node->lock);
+ isc_refcount_destroy(&node->references);
node->magic = 0;
isc_mem_put(mctx, node, sizeof(*node));
detachnode(dns_db_t *db, dns_dbnode_t **nodep) {
dns_ecdb_t *ecdb = (dns_ecdb_t *)db;
dns_ecdbnode_t *node;
- bool need_destroy = false;
REQUIRE(VALID_ECDB(ecdb));
REQUIRE(nodep != NULL);
node = (dns_ecdbnode_t *)*nodep;
REQUIRE(VALID_ECDBNODE(node));
+ *nodep = NULL;
- UNUSED(ecdb); /* in case REQUIRE() is empty */
-
- LOCK(&node->lock);
- INSIST(node->references > 0);
- node->references--;
- if (node->references == 0)
- need_destroy = true;
- UNLOCK(&node->lock);
-
- if (need_destroy)
+ if (isc_refcount_decrement(&node->references) == 1) {
destroynode(node);
-
- *nodep = NULL;
+ }
}
static isc_result_t
return (result);
}
node->ecdb= ecdb;
- node->references = 1;
+ isc_refcount_init(&node->references, 1);
ISC_LIST_INIT(node->rdatasets);
ISC_LINK_INIT(node, link);
rdataset->privateuint4 = 0;
rdataset->private5 = NULL;
- INSIST(node->references > 0);
- node->references++;
+ isc_refcount_increment(&node->references);
}
static isc_result_t
isc_mutex_init(&ecdb->lock);
- ecdb->references = 1;
+ isc_refcount_init(&ecdb->references, 1);
ISC_LIST_INIT(ecdb->nodes);
ecdb->common.mctx = NULL;