Bug 1631232 - Always upgrade existing weak child references in the rule tree. r=emilio

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 cherry-picks https://github.com/servo/servo/pull/26220

MANUAL PUSH: So that I can preserve reviewer information.
This commit is contained in:
Anthony Ramine 2020-04-18 12:10:09 +02:00 committed by Emilio Cobos Álvarez
parent a1891f468b
commit cf2f0bb18e

View File

@ -405,18 +405,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)) }
}