#include <isc/mem.h>
#include <isc/once.h>
#include <isc/print.h>
+#include <isc/refcount.h>
#include <isc/region.h>
#include <isc/util.h>
char *zone;
dns_sdbimplementation_t *implementation;
void *dbdata;
- isc_mutex_t lock;
- /* Locked */
- unsigned int references;
+
+ /* Atomic */
+ isc_refcount_t references;
};
struct dns_sdblookup {
ISC_LIST(isc_buffer_t) buffers;
dns_name_t *name;
ISC_LINK(dns_sdblookup_t) link;
- isc_mutex_t lock;
dns_rdatacallbacks_t callbacks;
- /* Locked */
- unsigned int references;
+
+ /* Atomic */
+ isc_refcount_t references;
};
typedef struct dns_sdblookup dns_sdbnode_t;
REQUIRE(VALID_SDB(sdb));
- LOCK(&sdb->lock);
- REQUIRE(sdb->references > 0);
- sdb->references++;
- UNLOCK(&sdb->lock);
+ isc_refcount_increment(&sdb->references);
*targetp = source;
}
}
isc_mem_free(mctx, sdb->zone);
- isc_mutex_destroy(&sdb->lock);
sdb->common.magic = 0;
sdb->common.impmagic = 0;
static void
detach(dns_db_t **dbp) {
dns_sdb_t *sdb = (dns_sdb_t *)(*dbp);
- bool need_destroy = false;
REQUIRE(VALID_SDB(sdb));
- LOCK(&sdb->lock);
- REQUIRE(sdb->references > 0);
- sdb->references--;
- if (sdb->references == 0)
- need_destroy = true;
- UNLOCK(&sdb->lock);
-
- if (need_destroy)
- destroy(sdb);
*dbp = NULL;
+
+ if (isc_refcount_decrement(&sdb->references) == 1) {
+ destroy(sdb);
+ }
}
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 = SDBLOOKUP_MAGIC;
*nodep = node;
dns_name_free(node->name, mctx);
isc_mem_put(mctx, node->name, sizeof(dns_name_t));
}
- isc_mutex_destroy(&node->lock);
+
node->magic = 0;
isc_mem_put(mctx, node, sizeof(dns_sdbnode_t));
detach((dns_db_t **) (void *)&sdb);
UNUSED(sdb);
- 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_sdb_t *sdb = (dns_sdb_t *)db;
dns_sdbnode_t *node;
- bool need_destroy = false;
REQUIRE(VALID_SDB(sdb));
REQUIRE(targetp != NULL && *targetp != NULL);
node = (dns_sdbnode_t *)(*targetp);
- LOCK(&node->lock);
- INSIST(node->references > 0);
- node->references--;
- if (node->references == 0)
- need_destroy = true;
- UNLOCK(&node->lock);
+ *targetp = NULL;
- if (need_destroy)
+ if (isc_refcount_decrement(&node->references) == 1) {
destroynode(node);
-
- *targetp = NULL;
+ }
}
static isc_result_t
isc_mem_attach(mctx, &sdb->common.mctx);
- isc_mutex_init(&sdb->lock);
-
result = dns_name_dupwithoffsets(origin, mctx, &sdb->common.origin);
if (result != ISC_R_SUCCESS)
goto cleanup_lock;
goto cleanup_zonestr;
}
- sdb->references = 1;
+ isc_refcount_init(&sdb->references, 1);
sdb->common.magic = DNS_DB_MAGIC;
sdb->common.impmagic = SDB_MAGIC;
cleanup_origin:
dns_name_free(&sdb->common.origin, mctx);
cleanup_lock:
- isc_mutex_destroy(&sdb->lock);
isc_mem_put(mctx, sdb, sizeof(dns_sdb_t));
isc_mem_detach(&mctx);