lib/dns/rbtdb.c
/*
 * This function is assumed to be called when a node is newly referenced
 * and can be in the deadnode list.  In that case the node must be retrieved
 * from the list because it is going to be used.  In addition, if the caller
 * happens to hold a write lock on the tree, it's a good chance to purge dead
 * nodes.
 * Note: while a new reference is gained in multiple places, there are only very
 * few cases where the node can be in the deadnode list (only empty nodes can
 * have been added to the list).
 */
This function is assumed to be called when a node is newly referenced
and can be in the deadnode list.  In that case the node must be retrieved
from the list because it is going to be used.  In addition, if the caller
happens to hold a write lock on the tree, it's a good chance to purge dead
nodes.
Note: while a new reference is gained in multiple places, there are only very
few cases where the node can be in the deadnode list (only empty nodes can
have been added to the list).
This function is assumed to be called when a node is newly referenced and can be in the deadnode list . In that case the node must be retrieved from the list because it is going to be used . In addition if the caller happens to hold a write lock on the tree it ' s a good chance to purge dead nodes . Note : while a new reference is gained in multiple places there are only very few cases where the node can be in the deadnode list ( only empty nodes can have been added to the list ) .
static inline void
reactivate_node(dns_rbtdb_t *rbtdb, dns_rbtnode_t *node,
		isc_rwlocktype_t treelocktype)
{
	isc_boolean_t need_relock = ISC_FALSE;
	NODE_STRONGLOCK(&rbtdb->node_locks[node->locknum].lock);
	new_reference(rbtdb, node);
	NODE_WEAKLOCK(&rbtdb->node_locks[node->locknum].lock,
		      isc_rwlocktype_read);
	if (ISC_LINK_LINKED(node, deadlink))
		need_relock = ISC_TRUE;
	else if (!ISC_LIST_EMPTY(rbtdb->deadnodes[node->locknum]) &&
		 treelocktype == isc_rwlocktype_write)
		need_relock = ISC_TRUE;
	NODE_WEAKUNLOCK(&rbtdb->node_locks[node->locknum].lock,
			isc_rwlocktype_read);
	if (need_relock) {
		NODE_WEAKLOCK(&rbtdb->node_locks[node->locknum].lock,
			      isc_rwlocktype_write);
		if (ISC_LINK_LINKED(node, deadlink))
			ISC_LIST_UNLINK(rbtdb->deadnodes[node->locknum],
					node, deadlink);
		if (treelocktype == isc_rwlocktype_write)
			cleanup_dead_nodes(rbtdb, node->locknum);
		NODE_WEAKUNLOCK(&rbtdb->node_locks[node->locknum].lock,
				isc_rwlocktype_write);
	}
	NODE_STRONGUNLOCK(&rbtdb->node_locks[node->locknum].lock);
}
static inline void reactivate_node ( dns_rbtdb_t * rbtdb , dns_rbtnode_t * node , isc_rwlocktype_t treelocktype ) { isc_boolean_t need_relock = ISC_FALSE ; NODE_STRONGLOCK ( & rbtdb -> node_locks [ node -> locknum ] . lock ) ; new_reference ( rbtdb , node ) ; NODE_WEAKLOCK ( & rbtdb -> node_locks [ node -> locknum ] . lock , isc_rwlocktype_read ) ; if ( ISC_LINK_LINKED ( node , deadlink ) ) need_relock = ISC_TRUE ; else if ( ! ISC_LIST_EMPTY ( rbtdb -> deadnodes [ node -> locknum ] ) && treelocktype == isc_rwlocktype_write ) need_relock = ISC_TRUE ; NODE_WEAKUNLOCK ( & rbtdb -> node_locks [ node -> locknum ] . lock , isc_rwlocktype_read ) ; if ( need_relock ) { NODE_WEAKLOCK ( & rbtdb -> node_locks [ node -> locknum ] . lock , isc_rwlocktype_write ) ; if ( ISC_LINK_LINKED ( node , deadlink ) ) ISC_LIST_UNLINK ( rbtdb -> deadnodes [ node -> locknum ] , node , deadlink ) ; if ( treelocktype == isc_rwlocktype_write ) cleanup_dead_nodes ( rbtdb , node -> locknum ) ; NODE_WEAKUNLOCK ( & rbtdb -> node_locks [ node -> locknum ] . lock , isc_rwlocktype_write ) ; } NODE_STRONGUNLOCK ( & rbtdb -> node_locks [ node -> locknum ] . lock ) ; }
This function is assumed to be called when a node is newly referenced
 and can be in the deadnode list.
This function is assumed to be called when a node is newly referenced and can be in the deadnode list .