}
static void
-rpsdb_attachnode(dns_db_t *db, dns_dbnode_t *source, dns_dbnode_t **targetp) {
+rpsdb_attachnode(dns_db_t *db, dns_dbnode_t *source,
+ dns_dbnode_t **targetp DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = (dns_rpsdb_t *)db;
REQUIRE(VALID_RPSDB(rpsdb));
}
static void
-rpsdb_detachnode(dns_db_t *db, dns_dbnode_t **targetp) {
+rpsdb_detachnode(dns_db_t *db, dns_dbnode_t **targetp DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = (dns_rpsdb_t *)db;
REQUIRE(VALID_RPSDB(rpsdb));
static isc_result_t
rpsdb_findnode(dns_db_t *db, const dns_name_t *name, bool create,
- dns_dbnode_t **nodep) {
+ dns_dbnode_t **nodep DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = (dns_rpsdb_t *)db;
dns_db_t *dbp = NULL;
rpsdb_findrdataset(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
dns_rdatatype_t type, dns_rdatatype_t covers,
isc_stdtime_t now, dns_rdataset_t *rdataset,
- dns_rdataset_t *sigrdataset) {
+ dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = (dns_rpsdb_t *)db;
dns_rdatatype_t foundtype;
dns_rdataclass_t class;
rpsdb_finddb(dns_db_t *db, const dns_name_t *name, dns_dbversion_t *version,
dns_rdatatype_t type, unsigned int options, isc_stdtime_t now,
dns_dbnode_t **nodep, dns_name_t *foundname,
- dns_rdataset_t *rdataset, dns_rdataset_t *sigrdataset) {
+ dns_rdataset_t *rdataset,
+ dns_rdataset_t *sigrdataset DNS__DB_FLARG) {
dns_dbnode_t *node = NULL;
UNUSED(version);
node = NULL;
nodep = &node;
}
- rpsdb_findnode(db, name, false, nodep);
+ rpsdb_findnode(db, name, false, nodep DNS__DB_FLARG_PASS);
dns_name_copy(name, foundname);
return (rpsdb_findrdataset(db, *nodep, NULL, type, 0, 0, rdataset,
- sigrdataset));
+ sigrdataset DNS__DB_FLARG_PASS));
}
static isc_result_t
rpsdb_allrdatasets(dns_db_t *db, dns_dbnode_t *node, dns_dbversion_t *version,
unsigned int options, isc_stdtime_t now,
- dns_rdatasetiter_t **iteratorp) {
+ dns_rdatasetiter_t **iteratorp DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = (dns_rpsdb_t *)db;
rpsdb_rdatasetiter_t *rpsdb_iter = NULL;
},
};
- rpsdb_attachnode(db, node, &rpsdb_iter->common.node);
+ rpsdb_attachnode(db, node, &rpsdb_iter->common.node DNS__DB_FLARG_PASS);
*iteratorp = &rpsdb_iter->common;
}
static isc_result_t
-rpsdb_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep) {
+rpsdb_getoriginnode(dns_db_t *db, dns_dbnode_t **nodep DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = (dns_rpsdb_t *)db;
REQUIRE(VALID_RPSDB(rpsdb));
REQUIRE(nodep != NULL && *nodep == NULL);
- rpsdb_attachnode(db, &rpsdb->origin_node, nodep);
+ rpsdb_attachnode(db, &rpsdb->origin_node, nodep DNS__DB_FLARG_PASS);
return (ISC_R_SUCCESS);
}
static void
-rpsdb_rdataset_disassociate(dns_rdataset_t *rdataset) {
+rpsdb_rdataset_disassociate(dns_rdataset_t *rdataset DNS__DB_FLARG) {
dns_db_t *db = NULL;
/*
}
static void
-rpsdb_rdataset_clone(dns_rdataset_t *source, dns_rdataset_t *target) {
+rpsdb_rdataset_clone(dns_rdataset_t *source,
+ dns_rdataset_t *target DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = NULL;
dns_db_t *dbp = NULL;
}
static void
-rpsdb_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp) {
+rpsdb_rdatasetiter_destroy(dns_rdatasetiter_t **iteratorp DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = NULL;
dns_rdatasetiter_t *iterator = NULL;
isc_mem_t *mctx = NULL;
}
static isc_result_t
-rpsdb_rdatasetiter_next(dns_rdatasetiter_t *iter) {
+rpsdb_rdatasetiter_next(dns_rdatasetiter_t *iter DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = NULL;
rpsdb_rdatasetiter_t *rpsdb_iter = NULL;
dns_rdatatype_t next_type, type;
}
static isc_result_t
-rpsdb_rdatasetiter_first(dns_rdatasetiter_t *iterator) {
+rpsdb_rdatasetiter_first(dns_rdatasetiter_t *iterator DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = NULL;
rpsdb_rdatasetiter_t *rpsdb_iter = NULL;
rpsdb_iter->type = dns_rdatatype_none;
rpsdb_iter->class = dns_rdataclass_reserved0;
- return (rpsdb_rdatasetiter_next(iterator));
+ return (rpsdb_rdatasetiter_next(iterator DNS__DB_FLARG_PASS));
}
static void
rpsdb_rdatasetiter_current(dns_rdatasetiter_t *iterator,
- dns_rdataset_t *rdataset) {
+ dns_rdataset_t *rdataset DNS__DB_FLARG) {
dns_rpsdb_t *rpsdb = NULL;
rpsdb_rdatasetiter_t *rpsdb_iter = NULL;
dns_name_t *name;
isc_mem_t *mctx;
isc_refcount_t references;
+ isc_refcount_t erefs;
uint16_t locknum;
void *data;
unsigned int : 0;
newref(qpzonedb_t *qpdb, qpdata_t *node DNS__DB_FLARG) {
uint_fast32_t refs;
- refs = isc_refcount_increment0(&node->references);
+ qpdata_ref(node);
+ refs = isc_refcount_increment0(&node->erefs);
#if DNS_DB_NODETRACE
- fprintf(stderr, "incr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
+ fprintf(stderr, "incr:node:%s:%s:%u:%p->erefs = %" PRIuFAST32 "\n",
func, file, line, node, refs + 1);
#else
UNUSED(refs);
* threads are decreasing the reference to zero simultaneously and at least
* one of them is going to free the node.
*
- * This function returns true if and only if the node reference decreases
- * to zero.
+ * This decrements both the internal and external node reference counters.
+ * If the external reference count drops to zero, then the node lock
+ * reference count is also decremented.
*
- * NOTE: Decrementing the reference count of a node to zero does not mean it
- * will be immediately freed.
+ * (NOTE: Decrementing the reference count of a node to zero does
+ * not mean it will be immediately freed.)
*/
-static bool
+static void
decref(qpzonedb_t *qpdb, qpdata_t *node, uint32_t least_serial,
isc_rwlocktype_t *nlocktypep DNS__DB_FLARG) {
db_nodelock_t *nodelock = NULL;
nodelock = &qpdb->node_locks[bucket];
-#define KEEP_NODE(n, r) \
- ((n)->data != NULL || (n) == (r)->origin || (n) == (r)->nsec3_origin)
-
/* Handle easy and typical case first. */
- if (!node->dirty && KEEP_NODE(node, qpdb)) {
- refs = isc_refcount_decrement(&node->references);
+ if (!node->dirty && (node->data != NULL || node == qpdb->origin ||
+ node == qpdb->nsec3_origin))
+ {
+ refs = isc_refcount_decrement(&node->erefs);
#if DNS_DB_NODETRACE
fprintf(stderr,
- "decr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
+ "decr:node:%s:%s:%u:%p->erefs = %" PRIuFAST32 "\n",
func, file, line, node, refs - 1);
#else
UNUSED(refs);
#else
UNUSED(refs);
#endif
- return (true);
}
-
- return (false);
+ goto done;
}
/* Upgrade the lock? */
NODE_FORCEUPGRADE(&nodelock->lock, nlocktypep);
}
- refs = isc_refcount_decrement(&node->references);
+ refs = isc_refcount_decrement(&node->erefs);
#if DNS_DB_NODETRACE
- fprintf(stderr, "decr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
+ fprintf(stderr, "decr:node:%s:%s:%u:%p->erefs = %" PRIuFAST32 "\n",
func, file, line, node, refs - 1);
-#else
- UNUSED(refs);
#endif
- if (refs > 1) {
- return (false);
- }
-
- if (node->dirty) {
- if (least_serial == 0) {
- /*
- * Caller doesn't know the least serial.
- * Get it.
- */
- RWLOCK(&qpdb->lock, isc_rwlocktype_read);
- least_serial = qpdb->least_serial;
- RWUNLOCK(&qpdb->lock, isc_rwlocktype_read);
+ if (refs == 1) {
+ if (node->dirty) {
+ if (least_serial == 0) {
+ /*
+ * Caller doesn't know the least serial.
+ * Get it.
+ */
+ RWLOCK(&qpdb->lock, isc_rwlocktype_read);
+ least_serial = qpdb->least_serial;
+ RWUNLOCK(&qpdb->lock, isc_rwlocktype_read);
+ }
+ clean_zone_node(node, least_serial);
}
- clean_zone_node(node, least_serial);
- }
- refs = isc_refcount_decrement(&nodelock->references);
+ refs = isc_refcount_decrement(&nodelock->references);
#if DNS_DB_NODETRACE
- fprintf(stderr,
- "decr:nodelock:%s:%s:%u:%p:%p->references = %" PRIuFAST32 "\n",
- func, file, line, node, nodelock, refs - 1);
+ fprintf(stderr,
+ "decr:nodelock:%s:%s:%u:%p:%p->references = "
+ "%" PRIuFAST32 "\n",
+ func, file, line, node, nodelock, refs - 1);
#else
- UNUSED(refs);
+ UNUSED(refs);
#endif
-
- if (KEEP_NODE(node, qpdb)) {
- return (true);
}
-#undef KEEP_NODE
- return (true);
+done:
+ qpdata_unref(node);
}
static void
add_changed(dns_slabheader_t *header, qpdb_version_t *version DNS__DB_FLARG) {
qpdb_changed_t *changed = NULL;
qpzonedb_t *qpdb = (qpzonedb_t *)header->db;
+ qpdata_t *node = (qpdata_t *)header->node;
changed = isc_mem_get(qpdb->common.mctx, sizeof(*changed));
RWLOCK(&qpdb->lock, isc_rwlocktype_write);
REQUIRE(version->writer);
- qpdata_t *node = (qpdata_t *)header->node;
- uint_fast32_t refs = isc_refcount_increment(&node->references);
-#if DNS_DB_NODETRACE
- fprintf(stderr, "incr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
- func, file, line, node, refs + 1);
-#else
- UNUSED(refs);
-#endif
+
*changed = (qpdb_changed_t){ .node = node };
ISC_LIST_INITANDAPPEND(version->changed_list, changed, link);
+ newref(qpdb, node DNS__DB_FLARG_PASS);
RWUNLOCK(&qpdb->lock, isc_rwlocktype_write);
return (changed);
isc_result_t tresult;
dns_qpchain_node(&search.chain, i, NULL, (void **)&n, NULL);
- tresult = check_zonecut(n, &search);
+ tresult = check_zonecut(n, &search DNS__DB_FLARG_PASS);
if (tresult != DNS_R_CONTINUE) {
result = tresult;
search.chain.len = i - 1;
* have matched a wildcard.
*/
+ lock = &search.qpdb->node_locks[node->locknum].lock;
+ NODE_RDLOCK(lock, &nlocktype);
+
if (search.zonecut != NULL) {
/*
* If we're beneath a zone cut, we don't want to look for
* We now go looking for rdata...
*/
- lock = &search.qpdb->node_locks[node->locknum].lock;
- NODE_RDLOCK(lock, &nlocktype);
-
- found = NULL;
- foundsig = NULL;
sigtype = DNS_SIGTYPE(type);
- nsecheader = NULL;
- nsecsig = NULL;
- cnamesig = NULL;
empty_node = true;
for (header = node->data; header != NULL; header = header_next) {
header_next = header->next;
qpdata_t *node = (qpdata_t *)dbnode;
qpdb_version_t *version = dbversion;
qpdb_rdatasetiter_t *iterator = NULL;
- uint_fast32_t refs;
REQUIRE(VALID_QPZONE(qpdb));
iterator->common.options = options;
iterator->common.now = now;
- refs = isc_refcount_increment(&node->references);
-#if DNS_DB_NODETRACE
- fprintf(stderr, "incr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
- func, file, line, node, refs + 1);
-#else
- UNUSED(refs);
-#endif
+ newref(qpdb, node DNS__DB_FLARG_PASS);
iterator->current = NULL;
static void
attachnode(dns_db_t *db, dns_dbnode_t *source,
dns_dbnode_t **targetp DNS__DB_FLARG) {
- REQUIRE(VALID_QPZONE((qpzonedb_t *)db));
- REQUIRE(targetp != NULL && *targetp == NULL);
-
+ qpzonedb_t *qpdb = (qpzonedb_t *)db;
qpdata_t *node = (qpdata_t *)source;
- uint_fast32_t refs = isc_refcount_increment(&node->references);
-#if DNS_DB_NODETRACE
- fprintf(stderr, "incr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
- func, file, line, node, refs + 1);
-#else
- UNUSED(refs);
-#endif
+ REQUIRE(VALID_QPZONE(qpdb));
+ REQUIRE(targetp != NULL && *targetp == NULL);
+
+ newref(qpdb, node DNS__DB_FLARG_PASS);
*targetp = source;
}
nodelock = &qpdb->node_locks[node->locknum];
NODE_RDLOCK(&nodelock->lock, &nlocktype);
- if (decref(qpdb, node, 0, &nlocktype DNS__DB_FLARG_PASS)) {
- if (isc_refcount_current(&nodelock->references) == 0 &&
- nodelock->exiting)
- {
- inactive = true;
- }
+ decref(qpdb, node, 0, &nlocktype DNS__DB_FLARG_PASS);
+ if (isc_refcount_current(&nodelock->references) == 0 &&
+ nodelock->exiting)
+ {
+ inactive = true;
}
NODE_UNLOCK(&nodelock->lock, &nlocktype);