dns_db_t common;
void *dbdata;
dns_sdlzimplementation_t *dlzimp;
- isc_mutex_t refcnt_lock;
+
+ /* Atomic */
+ isc_refcount_t references;
+
/* Locked */
- unsigned int references;
dns_dbversion_t *future_version;
int dummy_version;
};
ISC_LIST(isc_buffer_t) buffers;
dns_name_t *name;
ISC_LINK(dns_sdlzlookup_t) link;
- isc_mutex_t lock;
dns_rdatacallbacks_t callbacks;
- /* Locked */
- unsigned int references;
+
+ /* Atomic */
+ isc_refcount_t references;
};
typedef struct dns_sdlzlookup dns_sdlznode_t;
REQUIRE(VALID_SDLZDB(sdlz));
- LOCK(&sdlz->refcnt_lock);
- REQUIRE(sdlz->references > 0);
- sdlz->references++;
- UNLOCK(&sdlz->refcnt_lock);
+ isc_refcount_increment(&sdlz->references);
*targetp = source;
}
static void
destroy(dns_sdlz_db_t *sdlz) {
- isc_mem_t *mctx;
- mctx = sdlz->common.mctx;
-
sdlz->common.magic = 0;
sdlz->common.impmagic = 0;
- isc_mutex_destroy(&sdlz->refcnt_lock);
+ dns_name_free(&sdlz->common.origin, sdlz->common.mctx);
- dns_name_free(&sdlz->common.origin, mctx);
-
- isc_mem_put(mctx, sdlz, sizeof(dns_sdlz_db_t));
- isc_mem_detach(&mctx);
+ isc_refcount_destroy(&sdlz->references);
+ isc_mem_putanddetach(&sdlz->common.mctx, sdlz, sizeof(dns_sdlz_db_t));
}
static void
detach(dns_db_t **dbp) {
dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)(*dbp);
- bool need_destroy = false;
REQUIRE(VALID_SDLZDB(sdlz));
- LOCK(&sdlz->refcnt_lock);
- REQUIRE(sdlz->references > 0);
- sdlz->references--;
- if (sdlz->references == 0)
- need_destroy = true;
- UNLOCK(&sdlz->refcnt_lock);
-
- if (need_destroy)
- destroy(sdlz);
*dbp = NULL;
+
+ if (isc_refcount_decrement(&sdlz->references) == 1) {
+ destroy(sdlz);
+ }
}
static isc_result_t
ISC_LIST_INIT(node->buffers);
ISC_LINK_INIT(node, link);
node->name = NULL;
- isc_mutex_init(&node->lock);
dns_rdatacallbacks_init(&node->callbacks);
- node->references = 1;
+
+ isc_refcount_init(&node->references, 1);
node->magic = SDLZLOOKUP_MAGIC;
*nodep = node;
dns_name_free(node->name, mctx);
isc_mem_put(mctx, node->name, sizeof(dns_name_t));
}
- isc_mutex_destroy(&node->lock);
+ isc_refcount_destroy(&node->references);
+
node->magic = 0;
isc_mem_put(mctx, node, sizeof(dns_sdlznode_t));
db = &sdlz->common;
result = ISC_R_SUCCESS;
if (result != ISC_R_SUCCESS) {
+ isc_refcount_decrement(&node->references);
destroynode(node);
return (result);
}
if (result != ISC_R_SUCCESS &&
result != ISC_R_NOTIMPLEMENTED)
{
+ isc_refcount_decrement(&node->references);
destroynode(node);
return (result);
}
if (node->name == NULL) {
node->name = isc_mem_get(sdlz->common.mctx,
sizeof(dns_name_t));
- if (node->name == NULL) {
- destroynode(node);
- return (ISC_R_NOMEMORY);
- }
dns_name_init(node->name, NULL);
result = dns_name_dup(name, sdlz->common.mctx, node->name);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(sdlz->common.mctx, node->name,
- sizeof(dns_name_t));
- destroynode(node);
- return (result);
- }
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
}
*nodep = node;
UNUSED(sdlz);
- LOCK(&node->lock);
- INSIST(node->references > 0);
- node->references++;
- INSIST(node->references != 0); /* Catch overflow. */
- UNLOCK(&node->lock);
+ isc_refcount_increment(&node->references);
*targetp = source;
}
detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
dns_sdlznode_t *node;
- bool need_destroy = false;
REQUIRE(VALID_SDLZDB(sdlz));
REQUIRE(targetp != NULL && *targetp != NULL);
UNUSED(sdlz);
node = (dns_sdlznode_t *)(*targetp);
+ *targetp = NULL;
- 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);
-
- *targetp = NULL;
+ }
}
static isc_result_t
* and try again.
*/
if (i < nlabels) {
- destroynode(node);
+ detachnode(db, &node);
node = NULL;
continue;
}
xresult = dns_name_copy(xname, foundname, NULL);
if (xresult != ISC_R_SUCCESS) {
- if (node != NULL)
- destroynode(node);
- if (dns_rdataset_isassociated(rdataset))
+ if (node != NULL) {
+ detachnode(db, &node);
+ }
+ if (dns_rdataset_isassociated(rdataset)) {
dns_rdataset_disassociate(rdataset);
+ }
return (DNS_R_BADDB);
}
}
dns_sdlznode_t *node;
node = ISC_LIST_HEAD(sdlziter->nodelist);
ISC_LIST_UNLINK(sdlziter->nodelist, node, link);
+ isc_refcount_decrement(&node->references);
destroynode(node);
}
if (result != ISC_R_SUCCESS)
goto mem_cleanup;
- /* initialize the reference count mutex */
- isc_mutex_init(&sdlzdb->refcnt_lock);
-
/* set the rest of the database structure attributes */
sdlzdb->dlzimp = imp;
sdlzdb->common.methods = &sdlzdb_methods;
sdlzdb->common.rdclass = rdclass;
sdlzdb->common.mctx = NULL;
sdlzdb->dbdata = dbdata;
- sdlzdb->references = 1;
+ isc_refcount_init(&sdlzdb->references, 1);
/* attach to the memory context */
isc_mem_attach(mctx, &sdlzdb->common.mctx);
if (result != ISC_R_SUCCESS)
return (result);
sdlznode->name = isc_mem_get(mctx, sizeof(dns_name_t));
- if (sdlznode->name == NULL) {
- destroynode(sdlznode);
- return (ISC_R_NOMEMORY);
- }
dns_name_init(sdlznode->name, NULL);
result = dns_name_dup(newname, mctx, sdlznode->name);
- if (result != ISC_R_SUCCESS) {
- isc_mem_put(mctx, sdlznode->name, sizeof(dns_name_t));
- destroynode(sdlznode);
- return (result);
- }
+ RUNTIME_CHECK(result == ISC_R_SUCCESS);
ISC_LIST_PREPEND(allnodes->nodelist, sdlznode, link);
if (allnodes->origin == NULL &&
dns_name_equal(newname, &sdlz->common.origin))