struct sampledb {
dns_db_t common;
- isc_refcount_t refs;
sample_instance_t *inst;
/*
}
static void
-attach(dns_db_t *source, dns_db_t **targetp) {
- sampledb_t *sampledb = (sampledb_t *)source;
-
- REQUIRE(VALID_SAMPLEDB(sampledb));
-
- isc_refcount_increment(&sampledb->refs);
- *targetp = source;
-}
+destroy(dns_db_t *db) {
+ sampledb_t *sampledb = (sampledb_t *)db;
-static void
-free_sampledb(sampledb_t *sampledb) {
REQUIRE(VALID_SAMPLEDB(sampledb));
dns_db_detach(&sampledb->rbtdb);
sizeof(*sampledb));
}
-static void
-detach(dns_db_t **dbp) {
- REQUIRE(dbp != NULL && VALID_SAMPLEDB((sampledb_t *)(*dbp)));
- sampledb_t *sampledb = (sampledb_t *)(*dbp);
- *dbp = NULL;
-
- if (isc_refcount_decrement(&sampledb->refs) == 1) {
- free_sampledb(sampledb);
- }
-}
-
static void
currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
sampledb_t *sampledb = (sampledb_t *)db;
* determine which implementation of dns_db_*() function to call.
*/
static dns_dbmethods_t sampledb_methods = {
- .attach = attach,
- .detach = detach,
+ .destroy = destroy,
.currentversion = currentversion,
.newversion = newversion,
.attachversion = attachversion,
CHECK(dns_name_dupwithoffsets(origin, mctx, &sampledb->common.origin));
- isc_refcount_init(&sampledb->refs, 1);
+ isc_refcount_init(&sampledb->common.references, 1);
/* Translate instance name to instance pointer. */
sampledb->inst = driverarg;
dns_db_create(isc_mem_t *mctx, const char *db_type, const dns_name_t *origin,
dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc,
char *argv[], dns_db_t **dbp) {
- dns_dbimplementation_t *impinfo;
+ dns_dbimplementation_t *impinfo = NULL;
isc_once_do(&once, initialize);
result = ((impinfo->create)(mctx, origin, type, rdclass, argc,
argv, impinfo->driverarg, dbp));
RWUNLOCK(&implock, isc_rwlocktype_read);
+
+#if DNS_DB_TRACE
+ fprintf(stderr, "dns_db_create:%s:%s:%d:%p->references = 1\n",
+ __func__, __FILE__, __LINE__ + 1, *dbp);
+#endif
return (result);
}
return (ISC_R_NOTFOUND);
}
-void
-dns_db_attach(dns_db_t *source, dns_db_t **targetp) {
- /*
- * Attach *targetp to source.
- */
-
- REQUIRE(DNS_DB_VALID(source));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
- (source->methods->attach)(source, targetp);
-
- ENSURE(*targetp == source);
+static void
+dns__db_destroy(dns_db_t *db) {
+ (db->methods->destroy)(db);
}
-void
-dns_db_detach(dns_db_t **dbp) {
- /*
- * Detach *dbp from its database.
- */
-
- REQUIRE(dbp != NULL);
- REQUIRE(DNS_DB_VALID(*dbp));
-
- ((*dbp)->methods->detach)(dbp);
-
- ENSURE(*dbp == NULL);
-}
+#if DNS_DB_TRACE
+ISC_REFCOUNT_TRACE_IMPL(dns_db, dns__db_destroy);
+#else
+ISC_REFCOUNT_IMPL(dns_db, dns__db_destroy);
+#endif
bool
dns_db_iscache(dns_db_t *db) {
dns_dnsrps_rewrite_init(librpz_emsg_t *emsg, dns_rpz_st_t *st,
dns_rpz_zones_t *rpzs, const dns_name_t *qname,
isc_mem_t *mctx, bool have_rd) {
- rpsdb_t *rpsdb;
+ rpsdb_t *rpsdb = NULL;
rpsdb = isc_mem_get(mctx, sizeof(*rpsdb));
*rpsdb = (rpsdb_t){
.methods = &rpsdb_db_methods,
.rdclass = dns_rdataclass_in,
},
- .ref_cnt = 1,
.qname = qname,
};
+ isc_refcount_init(&rpsdb->common.refcount, 1);
if (!librpz->rsp_create(emsg, &rpsdb->rsp, NULL, rpzs->rps_client,
have_rd, false))
}
static void
-rpsdb_attach(dns_db_t *source, dns_db_t **targetp) {
- rpsdb_t *rpsdb = (rpsdb_t *)source;
-
- REQUIRE(VALID_RPSDB(rpsdb));
-
- /*
- * Use a simple count because only one thread uses any single rpsdb_t
- */
- ++rpsdb->ref_cnt;
- *targetp = source;
-}
-
-static void
-rpsdb_detach(dns_db_t **dbp) {
- rpsdb_t *rpsdb = (rpsdb_t *)*dbp;
+rpsdb_destroy(dns_db_t *db) {
+ rpsdb_t *rpsdb = (rpsdb_t *)db;
REQUIRE(VALID_RPSDB(rpsdb));
- REQUIRE(rpsdb->ref_cnt > 0);
*dbp = NULL;
- /*
- * Simple count because only one thread uses a rpsdb_t.
- */
- if (--rpsdb->ref_cnt != 0) {
- return;
- }
-
librpz->rsp_detach(&rpsdb->rsp);
+ isc_refcount_destroy(&rpsdb->common.refcount);
rpsdb->common.impmagic = 0;
isc_mem_putanddetach(&rpsdb->common.mctx, rpsdb, sizeof(*rpsdb));
}
REQUIRE(targetp != NULL && *targetp == NULL);
REQUIRE(source == &rpsdb->origin_node || source == &rpsdb->data_node);
- /*
- * Simple count because only one thread uses a rpsdb_t.
- */
- ++rpsdb->ref_cnt;
+ isc_refcount_increment(&rpsdb->common.refcount);
*targetp = source;
}
*targetp == &rpsdb->data_node);
*targetp = NULL;
- rpsdb_detach(&db);
+ dns_db_detach(&db);
}
static isc_result_t
rpsdb_findnode(dns_db_t *db, const dns_name_t *name, bool create,
dns_dbnode_t **nodep) {
rpsdb_t *rpsdb = (rpsdb_t *)db;
- dns_db_t *dbp;
+ dns_db_t *dbp = NULL;
REQUIRE(VALID_RPSDB(rpsdb));
REQUIRE(nodep != NULL && *nodep == NULL);
} else {
*nodep = &rpsdb->data_node;
}
- dbp = NULL;
- rpsdb_attach(db, &dbp);
+
+ dns_db_attach(db, &dbp);
return (ISC_R_SUCCESS);
}
}
static dns_dbmethods_t rpsdb_db_methods = {
- .attach = rpsdb_attach,
- .detach = rpsdb_detach,
+ .destroy = rpsdb_destroy,
.findnode = rpsdb_findnode,
.find = rpsdb_finddb,
.attachnode = rpsdb_attachnode,
***** Imports
*****/
+/* Define to 1 for detailed reference tracing */
+#undef DNS_DB_TRACE
+
#include <inttypes.h>
#include <stdbool.h>
*****/
typedef struct dns_dbmethods {
- void (*attach)(dns_db_t *source, dns_db_t **targetp);
- void (*detach)(dns_db_t **dbp);
+ void (*destroy)(dns_db_t *db);
isc_result_t (*beginload)(dns_db_t *db,
dns_rdatacallbacks_t *callbacks);
isc_result_t (*endload)(dns_db_t *db, dns_rdatacallbacks_t *callbacks);
dns_rdataclass_t rdclass;
dns_name_t origin;
isc_mem_t *mctx;
+ isc_refcount_t references;
ISC_LIST(dns_dbonupdatelistener_t) update_listeners;
};
*** Basic DB Methods
***/
+#if DNS_DB_TRACE
+#define dns_db_ref(ptr) dns_db__ref(ptr, __func__, __FILE__, __LINE__)
+#define dns_db_unref(ptr) dns_db__unref(ptr, __func__, __FILE__, __LINE__)
+#define dns_db_attach(ptr, ptrp) \
+ dns_db__attach(ptr, ptrp, __func__, __FILE__, __LINE__)
+#define dns_db_detach(ptrp) dns_db__detach(ptrp, __func__, __FILE__, __LINE__)
+ISC_REFCOUNT_TRACE_DECL(dns_db);
+#else
+ISC_REFCOUNT_DECL(dns_db);
+#endif
+
isc_result_t
dns_db_create(isc_mem_t *mctx, const char *db_type, const dns_name_t *origin,
dns_dbtype_t type, dns_rdataclass_t rdclass, unsigned int argc,
* specified.
*/
-void
-dns_db_attach(dns_db_t *source, dns_db_t **targetp);
-/*%<
- * Attach *targetp to source.
- *
- * Requires:
- *
- * \li 'source' is a valid database.
- *
- * \li 'targetp' points to a NULL dns_db_t *.
- *
- * Ensures:
- *
- * \li *targetp is attached to source.
- */
-
-void
-dns_db_detach(dns_db_t **dbp);
-/*%<
- * Detach *dbp from its database.
- *
- * Requires:
- *
- * \li 'dbp' points to a valid database.
- *
- * Ensures:
- *
- * \li *dbp is NULL.
- *
- * \li If '*dbp' is the last reference to the database,
- * all resources used by the database will be freed
- */
-
bool
dns_db_iscache(dns_db_t *db);
/*%<
isc_stats_t *gluecachestats; /* zone DB only */
/* Locked by lock. */
unsigned int active;
- isc_refcount_t references;
unsigned int attributes;
rbtdb_serial_t current_serial;
rbtdb_serial_t least_serial;
* DB Routines
*/
-static void
-attach(dns_db_t *source, dns_db_t **targetp) {
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)source;
-
- REQUIRE(VALID_RBTDB(rbtdb));
-
- isc_refcount_increment(&rbtdb->references);
-
- *targetp = source;
-}
-
static void
free_rbtdb_callback(void *arg) {
dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)arg;
isc_mem_put(rbtdb->common.mctx, rbtdb->node_locks,
rbtdb->node_lock_count * sizeof(rbtdb_nodelock_t));
TREE_DESTROYLOCK(&rbtdb->tree_lock);
- isc_refcount_destroy(&rbtdb->references);
+ isc_refcount_destroy(&rbtdb->common.references);
if (rbtdb->loop != NULL) {
isc_loop_detach(&rbtdb->loop);
}
}
static void
-detach(dns_db_t **dbp) {
- REQUIRE(dbp != NULL && VALID_RBTDB((dns_rbtdb_t *)(*dbp)));
- dns_rbtdb_t *rbtdb = (dns_rbtdb_t *)(*dbp);
- *dbp = NULL;
-
- if (isc_refcount_decrement(&rbtdb->references) == 1) {
- maybe_free_rbtdb(rbtdb);
- }
+destroy(dns_db_t *db) {
+ maybe_free_rbtdb((dns_rbtdb_t *)db);
}
static void
prune_t *prune = isc_mem_get(rbtdb->common.mctx, sizeof(*prune));
*prune = (prune_t){ .node = node };
- attach((dns_db_t *)rbtdb, &prune->db);
+ dns_db_attach((dns_db_t *)rbtdb, &prune->db);
new_reference(rbtdb, node, locktype);
isc_async_run(rbtdb->loop, prune_tree, prune);
NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, &nlocktype);
TREE_UNLOCK(&rbtdb->tree_lock, &tlocktype);
- detach((dns_db_t **)&rbtdb);
+ dns_db_detach((dns_db_t **)&rbtdb);
}
static void
if (again) {
isc_async_run(rbtdb->loop, cleanup_dead_nodes_callback, rbtdb);
} else {
- if (isc_refcount_decrement(&rbtdb->references) == 1) {
- (void)isc_refcount_current(&rbtdb->references);
+ if (isc_refcount_decrement(&rbtdb->common.references) == 1) {
maybe_free_rbtdb(rbtdb);
}
}
sizeof(*changed));
}
if (rbtdb->loop != NULL) {
- isc_refcount_increment(&rbtdb->references);
+ isc_refcount_increment(&rbtdb->common.references);
isc_async_run(rbtdb->loop, cleanup_dead_nodes_callback,
rbtdb);
} else {
}
static dns_dbmethods_t zone_methods = {
- .attach = attach,
- .detach = detach,
+ .destroy = destroy,
.beginload = beginload,
.endload = endload,
.dump = dump,
};
static dns_dbmethods_t cache_methods = {
- .attach = attach,
- .detach = detach,
+ .destroy = destroy,
.beginload = beginload,
.endload = endload,
.dump = dump,
/*
* Misc. Initialization.
*/
- isc_refcount_init(&rbtdb->references, 1);
+ isc_refcount_init(&rbtdb->common.references, 1);
rbtdb->attributes = 0;
rbtdb->loop = NULL;
rbtdb->serve_stale_ttl = 0;
char *zone;
dns_sdbimplementation_t *implementation;
void *dbdata;
-
- /* Atomic */
- isc_refcount_t references;
};
struct dns_sdblookup {
*/
static void
-attach(dns_db_t *source, dns_db_t **targetp) {
- dns_sdb_t *sdb = (dns_sdb_t *)source;
-
- REQUIRE(VALID_SDB(sdb));
-
- isc_refcount_increment(&sdb->references);
-
- *targetp = source;
-}
-
-static void
-destroy(dns_sdb_t *sdb) {
+destroy(dns_db_t *db) {
+ dns_sdb_t *sdb = (dns_sdb_t *)db;
dns_sdbimplementation_t *imp = sdb->implementation;
- isc_refcount_destroy(&sdb->references);
+ isc_refcount_destroy(&sdb->common.references);
if (imp != NULL && imp->methods->destroy != NULL) {
LOCK(&sdb->implementation->driverlock);
isc_mem_putanddetach(&sdb->common.mctx, sdb, sizeof(dns_sdb_t));
}
-static void
-detach(dns_db_t **dbp) {
- dns_sdb_t *sdb = (dns_sdb_t *)(*dbp);
-
- REQUIRE(VALID_SDB(sdb));
-
- *dbp = NULL;
-
- if (isc_refcount_decrement(&sdb->references) == 1) {
- destroy(sdb);
- }
-}
-
static void
currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
REQUIRE(versionp != NULL && *versionp == NULL);
node = isc_mem_get(sdb->common.mctx, sizeof(dns_sdbnode_t));
node->sdb = NULL;
- attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb);
+ dns_db_attach((dns_db_t *)sdb, (dns_db_t **)&node->sdb);
ISC_LIST_INIT(node->lists);
ISC_LIST_INIT(node->buffers);
ISC_LINK_INIT(node, link);
node->magic = 0;
isc_mem_put(mctx, node, sizeof(dns_sdbnode_t));
- detach((dns_db_t **)(void *)&sdb);
+ dns_db_detach((dns_db_t **)(void *)&sdb);
}
static isc_result_t
}
static dns_dbmethods_t sdb_methods = {
- .attach = attach,
- .detach = detach,
+ .destroy = destroy,
.currentversion = currentversion,
.attachversion = attachversion,
.closeversion = closeversion,
}
}
- isc_refcount_init(&sdb->references, 1);
+ isc_refcount_init(&sdb->common.references, 1);
sdb->common.magic = DNS_DB_MAGIC;
sdb->common.impmagic = SDB_MAGIC;
void *dbdata;
dns_sdlzimplementation_t *dlzimp;
- /* Atomic */
- isc_refcount_t references;
-
/* Locked */
dns_dbversion_t *future_version;
int dummy_version;
*/
static void
-attach(dns_db_t *source, dns_db_t **targetp) {
- dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)source;
-
- REQUIRE(VALID_SDLZDB(sdlz));
-
- isc_refcount_increment(&sdlz->references);
-
- *targetp = source;
-}
+destroy(dns_db_t *db) {
+ dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
-static void
-destroy(dns_sdlz_db_t *sdlz) {
sdlz->common.magic = 0;
sdlz->common.impmagic = 0;
dns_name_free(&sdlz->common.origin, sdlz->common.mctx);
- isc_refcount_destroy(&sdlz->references);
+ isc_refcount_destroy(&sdlz->common.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);
-
- REQUIRE(VALID_SDLZDB(sdlz));
-
- *dbp = NULL;
-
- if (isc_refcount_decrement(&sdlz->references) == 1) {
- destroy(sdlz);
- }
-}
-
static void
currentversion(dns_db_t *db, dns_dbversion_t **versionp) {
dns_sdlz_db_t *sdlz = (dns_sdlz_db_t *)db;
node = isc_mem_get(sdlz->common.mctx, sizeof(dns_sdlznode_t));
node->sdlz = NULL;
- attach((dns_db_t *)sdlz, (dns_db_t **)&node->sdlz);
+ dns_db_attach((dns_db_t *)sdlz, (dns_db_t **)&node->sdlz);
ISC_LIST_INIT(node->lists);
ISC_LIST_INIT(node->buffers);
ISC_LINK_INIT(node, link);
node->magic = 0;
isc_mem_put(mctx, node, sizeof(dns_sdlznode_t));
db = &sdlz->common;
- detach(&db);
+ dns_db_detach(&db);
}
static isc_result_t
}
static dns_dbmethods_t sdlzdb_methods = {
- .attach = attach,
- .detach = detach,
+ .destroy = destroy,
.currentversion = currentversion,
.newversion = newversion,
.attachversion = attachversion,
goto mem_cleanup;
}
- isc_refcount_init(&sdlzdb->references, 1);
+ isc_refcount_init(&sdlzdb->common.references, 1);
/* attach to the memory context */
isc_mem_attach(mctx, &sdlzdb->common.mctx);