mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-09-01 06:55:30 +00:00
Refactor node reference counting in rbtdb.c
Refactor the pattern in the newref() and decref() functions in rbtdb.c following the pattern, so it follows the similar pattern we already have for QPDB.
This commit is contained in:
111
lib/dns/rbtdb.c
111
lib/dns/rbtdb.c
@@ -1115,30 +1115,19 @@ delete_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
static void
|
||||||
* Caller must be holding the node lock.
|
rbtnode_newref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node DNS__DB_FLARG) {
|
||||||
*/
|
uint_fast32_t refs = isc_refcount_increment0(&node->references);
|
||||||
void
|
|
||||||
dns__rbtdb_newref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|
||||||
isc_rwlocktype_t nlocktype DNS__DB_FLARG) {
|
|
||||||
uint_fast32_t refs;
|
|
||||||
|
|
||||||
if (nlocktype == isc_rwlocktype_write &&
|
|
||||||
ISC_LINK_LINKED(node, deadlink))
|
|
||||||
{
|
|
||||||
ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], node,
|
|
||||||
deadlink);
|
|
||||||
}
|
|
||||||
|
|
||||||
refs = isc_refcount_increment0(&node->references);
|
|
||||||
#if DNS_DB_NODETRACE
|
#if DNS_DB_NODETRACE
|
||||||
fprintf(stderr, "incr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
|
fprintf(stderr, "incr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
|
||||||
func, file, line, node, refs + 1);
|
func, file, line, node, refs + 1);
|
||||||
#else
|
|
||||||
UNUSED(refs);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (refs == 0) {
|
if (refs > 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* this is the first reference to the node */
|
/* this is the first reference to the node */
|
||||||
refs = isc_refcount_increment0(
|
refs = isc_refcount_increment0(
|
||||||
&rbtdb->node_locks[node->locknum].references);
|
&rbtdb->node_locks[node->locknum].references);
|
||||||
@@ -1146,12 +1135,27 @@ dns__rbtdb_newref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"incr:nodelock:%s:%s:%u:%p:%p->references = "
|
"incr:nodelock:%s:%s:%u:%p:%p->references = "
|
||||||
"%" PRIuFAST32 "\n",
|
"%" PRIuFAST32 "\n",
|
||||||
func, file, line, node,
|
func, file, line, node, &rbtdb->node_locks[node->locknum],
|
||||||
&rbtdb->node_locks[node->locknum], refs + 1);
|
refs + 1);
|
||||||
#else
|
#else
|
||||||
UNUSED(refs);
|
UNUSED(refs);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Caller must be holding the node lock.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
dns__rbtdb_newref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
||||||
|
isc_rwlocktype_t nlocktype DNS__DB_FLARG) {
|
||||||
|
if (nlocktype == isc_rwlocktype_write &&
|
||||||
|
ISC_LINK_LINKED(node, deadlink))
|
||||||
|
{
|
||||||
|
ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum], node,
|
||||||
|
deadlink);
|
||||||
|
}
|
||||||
|
|
||||||
|
rbtnode_newref(rbtdb, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*%
|
/*%
|
||||||
@@ -1280,6 +1284,29 @@ reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
NODE_UNLOCK(nodelock, &nlocktype);
|
NODE_UNLOCK(nodelock, &nlocktype);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
rbtnode_decref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node DNS__DB_FLARG) {
|
||||||
|
db_nodelock_t *nodelock = &rbtdb->node_locks[node->locknum];
|
||||||
|
uint_fast32_t refs = isc_refcount_decrement(&node->references);
|
||||||
|
#if DNS_DB_NODETRACE
|
||||||
|
fprintf(stderr, "decr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
|
||||||
|
func, file, line, node, refs - 1);
|
||||||
|
#endif
|
||||||
|
if (refs > 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
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);
|
||||||
|
#else
|
||||||
|
UNUSED(refs);
|
||||||
|
#endif
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Caller must be holding the node lock; either the read or write lock.
|
* Caller must be holding the node lock; either the read or write lock.
|
||||||
* Note that the lock must be held even when node references are
|
* Note that the lock must be held even when node references are
|
||||||
@@ -1302,10 +1329,8 @@ dns__rbtdb_decref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
isc_result_t result;
|
isc_result_t result;
|
||||||
bool locked = *tlocktypep != isc_rwlocktype_none;
|
bool locked = *tlocktypep != isc_rwlocktype_none;
|
||||||
bool write_locked = false;
|
bool write_locked = false;
|
||||||
int bucket = node->locknum;
|
db_nodelock_t *nodelock = &rbtdb->node_locks[node->locknum];
|
||||||
db_nodelock_t *nodelock = &rbtdb->node_locks[bucket];
|
|
||||||
bool no_reference = true;
|
bool no_reference = true;
|
||||||
uint_fast32_t refs;
|
|
||||||
|
|
||||||
REQUIRE(*nlocktypep != isc_rwlocktype_none);
|
REQUIRE(*nlocktypep != isc_rwlocktype_none);
|
||||||
|
|
||||||
@@ -1313,24 +1338,10 @@ dns__rbtdb_decref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
((n)->data != NULL || ((l) && (n)->down != NULL) || \
|
((n)->data != NULL || ((l) && (n)->down != NULL) || \
|
||||||
(n) == (r)->origin_node || (n) == (r)->nsec3_origin_node)
|
(n) == (r)->origin_node || (n) == (r)->nsec3_origin_node)
|
||||||
|
|
||||||
/* Handle easy and/or typical case first. */
|
if (!rbtnode_decref(rbtdb, node DNS__DB_FLARG_PASS)) {
|
||||||
refs = isc_refcount_decrement(&node->references);
|
|
||||||
#if DNS_DB_NODETRACE
|
|
||||||
fprintf(stderr, "decr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
|
|
||||||
func, file, line, node, refs - 1);
|
|
||||||
#endif
|
|
||||||
if (refs > 1) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
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);
|
|
||||||
#else
|
|
||||||
UNUSED(refs);
|
|
||||||
#endif
|
|
||||||
if (!node->dirty && KEEP_NODE(node, rbtdb, locked)) {
|
if (!node->dirty && KEEP_NODE(node, rbtdb, locked)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -1340,21 +1351,14 @@ dns__rbtdb_decref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
* node. To clean it up, the node ref needs to decrement to 0 under the
|
* node. To clean it up, the node ref needs to decrement to 0 under the
|
||||||
* node write lock, so we regain the ref and try again.
|
* node write lock, so we regain the ref and try again.
|
||||||
*/
|
*/
|
||||||
dns__rbtdb_newref(rbtdb, node, *nlocktypep DNS__DB_FLARG_PASS);
|
rbtnode_newref(rbtdb, node DNS__DB_FLARG_PASS);
|
||||||
|
|
||||||
/* Upgrade the lock? */
|
/* Upgrade the lock? */
|
||||||
if (*nlocktypep == isc_rwlocktype_read) {
|
if (*nlocktypep == isc_rwlocktype_read) {
|
||||||
NODE_FORCEUPGRADE(&nodelock->lock, nlocktypep);
|
NODE_FORCEUPGRADE(&nodelock->lock, nlocktypep);
|
||||||
}
|
}
|
||||||
|
|
||||||
refs = isc_refcount_decrement(&node->references);
|
if (!rbtnode_decref(rbtdb, node DNS__DB_FLARG_PASS)) {
|
||||||
#if DNS_DB_NODETRACE
|
|
||||||
fprintf(stderr, "decr:node:%s:%s:%u:%p->references = %" PRIuFAST32 "\n",
|
|
||||||
func, file, line, node, refs - 1);
|
|
||||||
#else
|
|
||||||
UNUSED(refs);
|
|
||||||
#endif
|
|
||||||
if (refs > 1) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1407,15 +1411,6 @@ dns__rbtdb_decref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
write_locked = true;
|
write_locked = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
#else
|
|
||||||
UNUSED(refs);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (KEEP_NODE(node, rbtdb, locked || write_locked)) {
|
if (KEEP_NODE(node, rbtdb, locked || write_locked)) {
|
||||||
goto restore_locks;
|
goto restore_locks;
|
||||||
}
|
}
|
||||||
@@ -1455,7 +1450,7 @@ dns__rbtdb_decref(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
|
|||||||
} else {
|
} else {
|
||||||
INSIST(node->data == NULL);
|
INSIST(node->data == NULL);
|
||||||
if (!ISC_LINK_LINKED(node, deadlink)) {
|
if (!ISC_LINK_LINKED(node, deadlink)) {
|
||||||
ISC_LIST_APPEND(rbtdb->deadnodes[bucket], node,
|
ISC_LIST_APPEND(rbtdb->deadnodes[node->locknum], node,
|
||||||
deadlink);
|
deadlink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user