Auto merge of #26220 - servo:layout-2020-rule-tree-new-on-write, r=emilio

Always upgrade existing weak child references in the rule tree

Just because we didn't find a child when read-locking a node children list
doesn't mean it still won't exist while we wait to upgrade the read lock
into a write lock to create the child.
This commit is contained in:
bors-servo 2020-04-18 14:06:19 -04:00 committed by GitHub
commit 00ac447966
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -402,18 +402,31 @@ impl StrongRuleNode {
return child.upgrade();
}
let mut children = RwLockUpgradableReadGuard::upgrade(children);
let weak = children.get_or_insert_with(
key,
|node| node.p.key(),
move || {
let root = unsafe { root.downgrade() };
let strong =
StrongRuleNode::new(Box::new(RuleNode::new(root, self.clone(), source, level)));
let weak = unsafe { strong.downgrade() };
mem::forget(strong);
weak
},
);
let mut is_new = false;
let weak = {
let is_new = &mut is_new;
children.get_or_insert_with(
key,
|node| node.p.key(),
move || {
*is_new = true;
let root = unsafe { root.downgrade() };
let strong = StrongRuleNode::new(Box::new(RuleNode::new(
root,
self.clone(),
source,
level,
)));
let weak = unsafe { strong.downgrade() };
mem::forget(strong);
weak
},
)
};
if !is_new {
return weak.upgrade();
}
unsafe { StrongRuleNode::from_unsafe_box(UnsafeBox::clone(&weak.p)) }
}