lib/dns/rbtdb.c
/*
 * Prune the tree by recursively cleaning-up single leaves.  In the worst
 * case, the number of iteration is the number of tree levels, which is at
 * most the maximum number of domain name labels, i.e, 127.  In practice, this
 * should be much smaller (only a few times), and even the worst case would be
 * acceptable for a single event.
 */
Prune the tree by recursively cleaning-up single leaves.  In the worst
case, the number of iteration is the number of tree levels, which is at
most the maximum number of domain name labels, i.e, 127.  In practice, this
should be much smaller (only a few times), and even the worst case would be
acceptable for a single event.
Prune the tree by recursively cleaning - up single leaves . In the worst case the number of iteration is the number of tree levels which is at most the maximum number of domain name labels i . e 127 . In practice this should be much smaller ( only a few times ) and even the worst case would be acceptable for a single event .
static void
prune_tree(isc_task_t *task, isc_event_t *event) {
	dns_rbtdb_t *rbtdb = event->ev_sender;
	dns_rbtnode_t *node = event->ev_arg;
	dns_rbtnode_t *parent;
	unsigned int locknum;
	UNUSED(task);
	isc_event_free(&event);
	RWLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
	locknum = node->locknum;
	NODE_LOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
	do {
		parent = node->parent;
		decrement_reference(rbtdb, node, 0, isc_rwlocktype_write,
				    isc_rwlocktype_write, ISC_TRUE);
		if (parent != NULL && parent->down == NULL) {
			if (parent->locknum != locknum) {
				NODE_UNLOCK(&rbtdb->node_locks[locknum].lock,
					    isc_rwlocktype_write);
				locknum = parent->locknum;
				NODE_LOCK(&rbtdb->node_locks[locknum].lock,
					  isc_rwlocktype_write);
			}
			new_reference(rbtdb, parent);
			if (ISC_LINK_LINKED(parent, deadlink)) {
				ISC_LIST_UNLINK(rbtdb->deadnodes[locknum],
						parent, deadlink);
			}
		} else
			parent = NULL;
		node = parent;
	} while (node != NULL);
	NODE_UNLOCK(&rbtdb->node_locks[locknum].lock, isc_rwlocktype_write);
	RWUNLOCK(&rbtdb->tree_lock, isc_rwlocktype_write);
	detach((dns_db_t **)&rbtdb);
}
static void prune_tree ( isc_task_t * task , isc_event_t * event ) { dns_rbtdb_t * rbtdb = event -> ev_sender ; dns_rbtnode_t * node = event -> ev_arg ; dns_rbtnode_t * parent ; unsigned int locknum ; UNUSED ( task ) ; isc_event_free ( & event ) ; RWLOCK ( & rbtdb -> tree_lock , isc_rwlocktype_write ) ; locknum = node -> locknum ; NODE_LOCK ( & rbtdb -> node_locks [ locknum ] . lock , isc_rwlocktype_write ) ; do { parent = node -> parent ; decrement_reference ( rbtdb , node , 0 , isc_rwlocktype_write , isc_rwlocktype_write , ISC_TRUE ) ; if ( parent != NULL && parent -> down == NULL ) { if ( parent -> locknum != locknum ) { NODE_UNLOCK ( & rbtdb -> node_locks [ locknum ] . lock , isc_rwlocktype_write ) ; locknum = parent -> locknum ; NODE_LOCK ( & rbtdb -> node_locks [ locknum ] . lock , isc_rwlocktype_write ) ; } new_reference ( rbtdb , parent ) ; if ( ISC_LINK_LINKED ( parent , deadlink ) ) { ISC_LIST_UNLINK ( rbtdb -> deadnodes [ locknum ] , parent , deadlink ) ; } } else parent = NULL ; node = parent ; } while ( node != NULL ) ; NODE_UNLOCK ( & rbtdb -> node_locks [ locknum ] . lock , isc_rwlocktype_write ) ; RWUNLOCK ( & rbtdb -> tree_lock , isc_rwlocktype_write ) ; detach ( ( dns_db_t * * ) & rbtdb ) ; }
Prune the tree by recursively cleaning-up single leaves.
Prune the tree by recursively cleaning - up single leaves .
/*
			 * node was the only down child of the parent and has
			 * just been removed.  We'll then need to examine the
			 * parent.  Keep the lock if possible; otherwise,
			 * release the old lock and acquire one for the parent.
			 */ /*
			 * We need to gain a reference to the node before
			 * decrementing it in the next iteration.  In addition,
			 * if the node is in the dead-nodes list, extract it
			 * from the list beforehand as we do in
			 * reactivate_node().
			 */