Use parking_lot::RwLock instead of DOMRefCell for PropertyDeclarationBlock

This commit is contained in:
Simon Sapin 2016-09-27 16:02:36 +02:00
parent d986fd2d2f
commit 89a29a7f12
24 changed files with 121 additions and 106 deletions

View file

@ -4,7 +4,7 @@
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser};
use cssparser::{DeclarationListParser, DeclarationParser};
use domrefcell::DOMRefCell;
use parking_lot::RwLock;
use parser::{ParserContext, log_css_error};
use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock};
use properties::PropertyDeclarationParseResult;
@ -69,7 +69,7 @@ impl KeyframeSelector {
}
/// A keyframe.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct Keyframe {
pub selector: KeyframeSelector,
@ -79,23 +79,26 @@ pub struct Keyframe {
/// But including them enables `compute_style_for_animation_step` to create a `ApplicableDeclarationBlock`
/// by cloning an `Arc<_>` (incrementing a reference count) rather than re-creating a `Vec<_>`.
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
pub block: Arc<DOMRefCell<PropertyDeclarationBlock>>,
pub block: Arc<RwLock<PropertyDeclarationBlock>>,
}
/// A keyframes step value. This can be a synthetised keyframes animation, that
/// is, one autogenerated from the current computed values, or a list of
/// declarations to apply.
// TODO: Find a better name for this?
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub enum KeyframesStepValue {
/// See `Keyframe::declarations`s docs about the presence of `Importance`.
Declarations(Arc<DOMRefCell<PropertyDeclarationBlock>>),
Declarations {
#[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")]
block: Arc<RwLock<PropertyDeclarationBlock>>
},
ComputedValues,
}
/// A single step from a keyframe animation.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct KeyframesStep {
/// The percentage of the animation duration when this step starts.
@ -116,9 +119,8 @@ impl KeyframesStep {
fn new(percentage: KeyframePercentage,
value: KeyframesStepValue) -> Self {
let declared_timing_function = match value {
KeyframesStepValue::Declarations(ref block) => {
// FIXME: Is this thread-safe?
unsafe { block.borrow_for_layout() }.declarations.iter().any(|&(ref prop_decl, _)| {
KeyframesStepValue::Declarations { ref block } => {
block.read().declarations.iter().any(|&(ref prop_decl, _)| {
match *prop_decl {
PropertyDeclaration::AnimationTimingFunction(..) => true,
_ => false,
@ -140,7 +142,7 @@ impl KeyframesStep {
/// of keyframes, in order.
///
/// It only takes into account animable properties.
#[derive(Debug, Clone, PartialEq)]
#[derive(Debug, Clone)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct KeyframesAnimation {
pub steps: Vec<KeyframesStep>,
@ -159,8 +161,7 @@ fn get_animated_properties(keyframe: &Keyframe) -> Vec<TransitionProperty> {
let mut ret = vec![];
// NB: declarations are already deduplicated, so we don't have to check for
// it here.
// FIXME: Is this thread-safe?
for &(ref declaration, _) in unsafe { keyframe.block.borrow_for_layout() }.declarations.iter() {
for &(ref declaration, _) in keyframe.block.read().declarations.iter() {
if let Some(property) = TransitionProperty::from_declaration(declaration) {
ret.push(property);
}
@ -184,8 +185,9 @@ impl KeyframesAnimation {
for keyframe in keyframes {
for percentage in keyframe.selector.0.iter() {
steps.push(KeyframesStep::new(*percentage,
KeyframesStepValue::Declarations(keyframe.block.clone())));
steps.push(KeyframesStep::new(*percentage, KeyframesStepValue::Declarations {
block: keyframe.block.clone(),
}));
}
}
@ -271,7 +273,7 @@ impl<'a> QualifiedRuleParser for KeyframeListParser<'a> {
}
Ok(Arc::new(Keyframe {
selector: prelude,
block: Arc::new(DOMRefCell::new(PropertyDeclarationBlock {
block: Arc::new(RwLock::new(PropertyDeclarationBlock {
declarations: declarations,
important_count: 0,
})),