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(); return child.upgrade();
} }
let mut children = RwLockUpgradableReadGuard::upgrade(children); let mut children = RwLockUpgradableReadGuard::upgrade(children);
let weak = children.get_or_insert_with( let mut is_new = false;
key, let weak = {
|node| node.p.key(), let is_new = &mut is_new;
move || { children.get_or_insert_with(
let root = unsafe { root.downgrade() }; key,
let strong = |node| node.p.key(),
StrongRuleNode::new(Box::new(RuleNode::new(root, self.clone(), source, level))); move || {
let weak = unsafe { strong.downgrade() }; *is_new = true;
mem::forget(strong); let root = unsafe { root.downgrade() };
weak 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)) } unsafe { StrongRuleNode::from_unsafe_box(UnsafeBox::clone(&weak.p)) }
} }