fn with_locked_node_and_parent<F, Ret>(node: &Arc<TreeNode>, func: F) -> Ret
where F: FnOnce(MutexGuard<'_, Inner>, Option<MutexGuard<'_, Inner>>) -> Ret,
Expand description

Figures out the parent of the node and locks the node and its parent atomically.

The basic principle of preventing deadlocks in the tree is that we always lock the parent first, and then the child. For more info look at deadlock safety and invariant #2.

Sadly, it’s impossible to figure out the parent of a node without locking it. To then achieve locking order consistency, the node has to be unlocked before the parent gets locked. This leaves a small window where we already assume that we know the parent, but neither the parent nor the node is locked. Therefore, the parent could change.

To prevent that this problem leaks into the rest of the code, it is abstracted in this function.

The locked child and optionally its locked parent, if a parent exists, get passed to the func argument via (node, None) or (node, Some(parent)).