diff --git a/Cargo.lock b/Cargo.lock index 076924c397c..72065507be0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -928,9 +928,7 @@ dependencies = [ "lazy_static 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.21 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)", - "num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", - "rayon 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)", "selectors 0.18.0", "servo_url 0.0.1", "style 0.0.1", @@ -2756,6 +2754,7 @@ dependencies = [ "nsstring_vendor 0.1.0", "num-integer 0.1.33 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)", + "num_cpus 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)", "ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)", "pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index 7cad9f98523..ee90766b1e2 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -562,7 +562,7 @@ unsafe impl JSTraceable for StyleLocked { } } -unsafe impl JSTraceable for RwLock { +unsafe impl JSTraceable for StyleLocked { unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing. } diff --git a/components/script/dom/csskeyframerule.rs b/components/script/dom/csskeyframerule.rs index 617546d6a76..d36e8988e04 100644 --- a/components/script/dom/csskeyframerule.rs +++ b/components/script/dom/csskeyframerule.rs @@ -14,8 +14,7 @@ use dom::window::Window; use dom_struct::dom_struct; use std::sync::Arc; use style::keyframes::Keyframe; -use style::shared_lock::Locked; -use style_traits::ToCss; +use style::shared_lock::{Locked, ToCssWithGuard}; #[dom_struct] pub struct CSSKeyframeRule { @@ -70,6 +69,6 @@ impl SpecificCSSRule for CSSKeyframeRule { fn get_css(&self) -> DOMString { let guard = self.cssrule.shared_lock().read(); - self.keyframerule.read_with(&guard).to_css_string().into() + self.keyframerule.read_with(&guard).to_css_string(&guard).into() } } diff --git a/components/script/dom/cssstyledeclaration.rs b/components/script/dom/cssstyledeclaration.rs index 8af3b3975d2..d5d248f7880 100644 --- a/components/script/dom/cssstyledeclaration.rs +++ b/components/script/dom/cssstyledeclaration.rs @@ -11,10 +11,9 @@ use dom::bindings::reflector::{DomObject, Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; use dom::cssrule::CSSRule; use dom::element::Element; -use dom::node::{Node, window_from_node}; +use dom::node::{Node, window_from_node, document_from_node}; use dom::window::Window; use dom_struct::dom_struct; -use parking_lot::RwLock; use servo_url::ServoUrl; use std::ascii::AsciiExt; use std::sync::Arc; @@ -23,6 +22,7 @@ use style::parser::ParserContextExtraData; use style::properties::{Importance, PropertyDeclarationBlock, PropertyId, LonghandId, ShorthandId}; use style::properties::{parse_one_declaration, parse_style_attribute}; use style::selector_parser::PseudoElement; +use style::shared_lock::Locked; use style_traits::ToCss; // http://dev.w3.org/csswg/cssom/#the-cssstyledeclaration-interface @@ -40,7 +40,7 @@ pub enum CSSStyleOwner { Element(JS), CSSRule(JS, #[ignore_heap_size_of = "Arc"] - Arc>), + Arc>), } impl CSSStyleOwner { @@ -55,10 +55,13 @@ impl CSSStyleOwner { let mut changed = true; match *self { CSSStyleOwner::Element(ref el) => { + let document = document_from_node(&**el); + let shared_lock = document.style_shared_lock(); let mut attr = el.style_attribute().borrow_mut().take(); let result = if attr.is_some() { let lock = attr.as_ref().unwrap(); - let mut pdb = lock.write(); + let mut guard = shared_lock.write(); + let mut pdb = lock.write_with(&mut guard); let result = f(&mut pdb, &mut changed); result } else { @@ -69,7 +72,7 @@ impl CSSStyleOwner { // exact conditions under it changes. changed = !pdb.declarations().is_empty(); if changed { - attr = Some(Arc::new(RwLock::new(pdb))); + attr = Some(Arc::new(shared_lock.wrap(pdb))); } result @@ -83,7 +86,8 @@ impl CSSStyleOwner { // // [1]: https://github.com/whatwg/html/issues/2306 if let Some(pdb) = attr { - let serialization = pdb.read().to_css_string(); + let guard = shared_lock.read(); + let serialization = pdb.read_with(&guard).to_css_string(); el.set_attribute(&local_name!("style"), AttrValue::Declaration(serialization, pdb)); @@ -96,7 +100,10 @@ impl CSSStyleOwner { result } CSSStyleOwner::CSSRule(ref rule, ref pdb) => { - let result = f(&mut *pdb.write(), &mut changed); + let result = { + let mut guard = rule.shared_lock().write(); + f(&mut *pdb.write_with(&mut guard), &mut changed) + }; if changed { rule.global().as_window().Document().invalidate_stylesheets(); } @@ -111,15 +118,20 @@ impl CSSStyleOwner { match *self { CSSStyleOwner::Element(ref el) => { match *el.style_attribute().borrow() { - Some(ref pdb) => f(&pdb.read()), + Some(ref pdb) => { + let document = document_from_node(&**el); + let guard = document.style_shared_lock().read(); + f(pdb.read_with(&guard)) + } None => { let pdb = PropertyDeclarationBlock::new(); f(&pdb) } } } - CSSStyleOwner::CSSRule(_, ref pdb) => { - f(&pdb.read()) + CSSStyleOwner::CSSRule(ref rule, ref pdb) => { + let guard = rule.shared_lock().read(); + f(pdb.read_with(&guard)) } } } diff --git a/components/script/dom/element.rs b/components/script/dom/element.rs index 8e13716fa9d..3a73bbce97e 100644 --- a/components/script/dom/element.rs +++ b/components/script/dom/element.rs @@ -82,7 +82,6 @@ use html5ever::serialize::TraversalScope::{ChildrenOnly, IncludeNode}; use html5ever_atoms::{Prefix, LocalName, Namespace, QualName}; use js::jsapi::{HandleValue, JSAutoCompartment}; use net_traits::request::CorsSettings; -use parking_lot::RwLock; use ref_filter_map::ref_filter_map; use script_layout_interface::message::ReflowQueryType; use script_thread::Runnable; @@ -108,6 +107,7 @@ use style::properties::longhands::{self, background_image, border_spacing, font_ use style::restyle_hints::RESTYLE_SELF; use style::rule_tree::CascadeLevel; use style::selector_parser::{NonTSPseudoClass, RestyleDamage, SelectorImpl, SelectorParser}; +use style::shared_lock::{SharedRwLock, Locked}; use style::sink::Push; use style::stylist::ApplicableDeclarationBlock; use style::thread_state; @@ -129,7 +129,7 @@ pub struct Element { attrs: DOMRefCell>>, id_attribute: DOMRefCell>, #[ignore_heap_size_of = "Arc"] - style_attribute: DOMRefCell>>>, + style_attribute: DOMRefCell>>>, attr_list: MutNullableJS, class_list: MutNullableJS, state: Cell, @@ -352,7 +352,7 @@ pub trait LayoutElementHelpers { #[allow(unsafe_code)] unsafe fn html_element_in_html_document_for_layout(&self) -> bool; fn id_attribute(&self) -> *const Option; - fn style_attribute(&self) -> *const Option>>; + fn style_attribute(&self) -> *const Option>>; fn local_name(&self) -> &LocalName; fn namespace(&self) -> &Namespace; fn get_lang_for_layout(&self) -> String; @@ -384,14 +384,18 @@ impl LayoutElementHelpers for LayoutJS { where V: Push { #[inline] - fn from_declaration(declaration: PropertyDeclaration) -> ApplicableDeclarationBlock { + fn from_declaration(shared_lock: &SharedRwLock, declaration: PropertyDeclaration) + -> ApplicableDeclarationBlock { ApplicableDeclarationBlock::from_declarations( - Arc::new(RwLock::new(PropertyDeclarationBlock::with_one( + Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one( declaration, Importance::Normal ))), CascadeLevel::PresHints) } + let document = self.upcast::().owner_doc_for_layout(); + let shared_lock = document.style_shared_lock(); + let bgcolor = if let Some(this) = self.downcast::() { this.get_background_color() } else if let Some(this) = self.downcast::() { @@ -408,6 +412,7 @@ impl LayoutElementHelpers for LayoutJS { if let Some(color) = bgcolor { hints.push(from_declaration( + shared_lock, PropertyDeclaration::BackgroundColor( CSSColor { parsed: Color::RGBA(color), authored: None }))); } @@ -420,6 +425,7 @@ impl LayoutElementHelpers for LayoutJS { if let Some(url) = background { hints.push(from_declaration( + shared_lock, PropertyDeclaration::BackgroundImage( background_image::SpecifiedValue(vec![ background_image::single_value::SpecifiedValue(Some( @@ -442,6 +448,7 @@ impl LayoutElementHelpers for LayoutJS { if let Some(color) = color { hints.push(from_declaration( + shared_lock, PropertyDeclaration::Color( longhands::color::SpecifiedValue(CSSColor { parsed: Color::RGBA(color), @@ -459,6 +466,7 @@ impl LayoutElementHelpers for LayoutJS { if let Some(font_family) = font_family { hints.push(from_declaration( + shared_lock, PropertyDeclaration::FontFamily( font_family::computed_value::T(vec![ font_family::computed_value::FontFamily::from_atom( @@ -469,6 +477,7 @@ impl LayoutElementHelpers for LayoutJS { if let Some(font_size) = font_size { hints.push(from_declaration( + shared_lock, PropertyDeclaration::FontSize(font_size::SpecifiedValue(font_size.into())))) } @@ -481,6 +490,7 @@ impl LayoutElementHelpers for LayoutJS { if let Some(cellspacing) = cellspacing { let width_value = specified::Length::from_px(cellspacing as f32); hints.push(from_declaration( + shared_lock, PropertyDeclaration::BorderSpacing( Box::new(border_spacing::SpecifiedValue { horizontal: width_value.clone(), @@ -514,6 +524,7 @@ impl LayoutElementHelpers for LayoutJS { if let Some(size) = size { let value = specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(size)); hints.push(from_declaration( + shared_lock, PropertyDeclaration::Width( specified::LengthOrPercentageOrAuto::Length(value)))); } @@ -539,12 +550,14 @@ impl LayoutElementHelpers for LayoutJS { let width_value = specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage)); hints.push(from_declaration( + shared_lock, PropertyDeclaration::Width(width_value))); } LengthOrPercentageOrAuto::Length(length) => { let width_value = specified::LengthOrPercentageOrAuto::Length( specified::NoCalcLength::Absolute(length)); hints.push(from_declaration( + shared_lock, PropertyDeclaration::Width(width_value))); } } @@ -564,12 +577,14 @@ impl LayoutElementHelpers for LayoutJS { let height_value = specified::LengthOrPercentageOrAuto::Percentage(specified::Percentage(percentage)); hints.push(from_declaration( + shared_lock, PropertyDeclaration::Height(height_value))); } LengthOrPercentageOrAuto::Length(length) => { let height_value = specified::LengthOrPercentageOrAuto::Length( specified::NoCalcLength::Absolute(length)); hints.push(from_declaration( + shared_lock, PropertyDeclaration::Height(height_value))); } } @@ -592,6 +607,7 @@ impl LayoutElementHelpers for LayoutJS { // https://html.spec.whatwg.org/multipage/#textarea-effective-width let value = specified::NoCalcLength::ServoCharacterWidth(specified::CharacterWidth(cols)); hints.push(from_declaration( + shared_lock, PropertyDeclaration::Width(specified::LengthOrPercentageOrAuto::Length(value)))); } @@ -610,6 +626,7 @@ impl LayoutElementHelpers for LayoutJS { // https://html.spec.whatwg.org/multipage/#textarea-effective-height let value = specified::NoCalcLength::FontRelative(specified::FontRelativeLength::Em(rows as CSSFloat)); hints.push(from_declaration( + shared_lock, PropertyDeclaration::Height(specified::LengthOrPercentageOrAuto::Length(value)))); } @@ -623,12 +640,16 @@ impl LayoutElementHelpers for LayoutJS { if let Some(border) = border { let width_value = specified::BorderWidth::from_length(specified::Length::from_px(border as f32)); hints.push(from_declaration( + shared_lock, PropertyDeclaration::BorderTopWidth(Box::new(width_value.clone())))); hints.push(from_declaration( + shared_lock, PropertyDeclaration::BorderLeftWidth(Box::new(width_value.clone())))); hints.push(from_declaration( + shared_lock, PropertyDeclaration::BorderBottomWidth(Box::new(width_value.clone())))); hints.push(from_declaration( + shared_lock, PropertyDeclaration::BorderRightWidth(Box::new(width_value)))); } } @@ -672,7 +693,7 @@ impl LayoutElementHelpers for LayoutJS { } #[allow(unsafe_code)] - fn style_attribute(&self) -> *const Option>> { + fn style_attribute(&self) -> *const Option>> { unsafe { (*self.unsafe_get()).style_attribute.borrow_for_layout() } @@ -835,7 +856,7 @@ impl Element { ns!() } - pub fn style_attribute(&self) -> &DOMRefCell>>> { + pub fn style_attribute(&self) -> &DOMRefCell>>> { &self.style_attribute } @@ -2170,7 +2191,7 @@ impl VirtualMethods for Element { block } else { let win = window_from_node(self); - Arc::new(RwLock::new(parse_style_attribute( + Arc::new(doc.style_shared_lock().wrap(parse_style_attribute( &attr.value(), &doc.base_url(), win.css_error_reporter(), diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs index 5a9a834667b..36aa7601d0b 100644 --- a/components/script/layout_wrapper.rs +++ b/components/script/layout_wrapper.rs @@ -44,7 +44,6 @@ use dom::text::Text; use gfx_traits::ByteIndex; use html5ever_atoms::{LocalName, Namespace}; use msg::constellation_msg::PipelineId; -use parking_lot::RwLock; use range::Range; use script_layout_interface::{HTMLCanvasData, LayoutNodeType, SVGSVGData, TrustedNodeAddress}; use script_layout_interface::{OpaqueStyleAndLayoutData, PartialPersistentLayoutData}; @@ -69,7 +68,7 @@ use style::dom::UnsafeNode; use style::element_state::*; use style::properties::{ComputedValues, PropertyDeclarationBlock}; use style::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl}; -use style::shared_lock::SharedRwLock as StyleSharedRwLock; +use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked}; use style::sink::Push; use style::str::is_whitespace; use style::stylist::ApplicableDeclarationBlock; @@ -377,7 +376,7 @@ impl<'le> TElement for ServoLayoutElement<'le> { ServoLayoutNode::from_layout_js(self.element.upcast()) } - fn style_attribute(&self) -> Option<&Arc>> { + fn style_attribute(&self) -> Option<&Arc>> { unsafe { (*self.element.style_attribute()).as_ref() } diff --git a/components/style/Cargo.toml b/components/style/Cargo.toml index c1c234c994a..6532efc4e9d 100644 --- a/components/style/Cargo.toml +++ b/components/style/Cargo.toml @@ -13,7 +13,7 @@ path = "lib.rs" doctest = false [features] -gecko = ["nsstring_vendor", "rayon/unstable"] +gecko = ["nsstring_vendor", "rayon/unstable", "num_cpus"] use_bindgen = ["bindgen", "regex"] servo = ["serde/unstable", "serde", "serde_derive", "heapsize_derive", "style_traits/servo", "servo_atoms", "html5ever-atoms", @@ -37,6 +37,7 @@ lazy_static = "0.2" log = "0.3" matches = "0.1" nsstring_vendor = {path = "gecko_bindings/nsstring_vendor", optional = true} +num_cpus = {version = "1.1.0", optional = true} num-integer = "0.1.32" num-traits = "0.1.32" ordered-float = "0.4" diff --git a/components/style/animation.rs b/components/style/animation.rs index ddf1498d983..9734b67c1fd 100644 --- a/components/style/animation.rs +++ b/components/style/animation.rs @@ -415,7 +415,7 @@ fn compute_style_for_animation_step(context: &SharedStyleContext, match step.value { KeyframesStepValue::ComputedValues => style_from_cascade.clone(), KeyframesStepValue::Declarations { block: ref declarations } => { - let guard = declarations.read(); + let guard = declarations.read_with(context.guards.author); // No !important in keyframes. debug_assert!(guard.declarations().iter() diff --git a/components/style/attr.rs b/components/style/attr.rs index 0d07a35e828..b4cd434635e 100644 --- a/components/style/attr.rs +++ b/components/style/attr.rs @@ -11,9 +11,9 @@ use app_units::Au; use cssparser::{self, Color, RGBA}; use euclid::num::Zero; use num_traits::ToPrimitive; -use parking_lot::RwLock; use properties::PropertyDeclarationBlock; use servo_url::ServoUrl; +use shared_lock::Locked; use std::ascii::AsciiExt; use std::str::FromStr; use std::sync::Arc; @@ -61,7 +61,7 @@ pub enum AttrValue { /// declarationblock for longer than needed. Declaration(String, #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")] - Arc>) + Arc>) } /// Shared implementation to parse an integer according to diff --git a/components/style/dom.rs b/components/style/dom.rs index 612105c20e9..ac8ad3bd109 100644 --- a/components/style/dom.rs +++ b/components/style/dom.rs @@ -11,10 +11,10 @@ use {Atom, Namespace, LocalName}; use atomic_refcell::{AtomicRef, AtomicRefCell, AtomicRefMut}; use data::ElementData; use element_state::ElementState; -use parking_lot::RwLock; use properties::{ComputedValues, PropertyDeclarationBlock}; use selector_parser::{ElementExt, PreExistingComputedValues, PseudoElement}; use selectors::matching::ElementSelectorFlags; +use shared_lock::Locked; use sink::Push; use std::fmt; use std::fmt::Debug; @@ -230,8 +230,8 @@ pub trait PresentationalHintsSynthetizer { /// The animation rules. The first one is for Animation cascade level, and the second one is for /// Transition cascade level. -pub struct AnimationRules(pub Option>>, - pub Option>>); +pub struct AnimationRules(pub Option>>, + pub Option>>); /// The element trait, the main abstraction the style crate acts over. pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + PresentationalHintsSynthetizer { @@ -252,7 +252,7 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre } /// Get this element's style attribute. - fn style_attribute(&self) -> Option<&Arc>>; + fn style_attribute(&self) -> Option<&Arc>>; /// Get this element's animation rules. fn get_animation_rules(&self, _pseudo: Option<&PseudoElement>) -> AnimationRules { @@ -261,13 +261,13 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre /// Get this element's animation rule. fn get_animation_rule(&self, _pseudo: Option<&PseudoElement>) - -> Option>> { + -> Option>> { None } /// Get this element's transition rule. fn get_transition_rule(&self, _pseudo: Option<&PseudoElement>) - -> Option>> { + -> Option>> { None } diff --git a/components/style/gecko/arc_types.rs b/components/style/gecko/arc_types.rs index d400c01c568..349fca1bbcb 100644 --- a/components/style/gecko/arc_types.rs +++ b/components/style/gecko/arc_types.rs @@ -48,7 +48,7 @@ impl_arc_ffi!(Stylesheet => RawServoStyleSheet impl_arc_ffi!(ComputedValues => ServoComputedValues [Servo_ComputedValues_AddRef, Servo_ComputedValues_Release]); -impl_arc_ffi!(RwLock => RawServoDeclarationBlock +impl_arc_ffi!(Locked => RawServoDeclarationBlock [Servo_DeclarationBlock_AddRef, Servo_DeclarationBlock_Release]); impl_arc_ffi!(Locked => RawServoStyleRule diff --git a/components/style/gecko/global_style_data.rs b/components/style/gecko/global_style_data.rs new file mode 100644 index 00000000000..2653ad16b1f --- /dev/null +++ b/components/style/gecko/global_style_data.rs @@ -0,0 +1,50 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +//! Global style data + +use num_cpus; +use rayon; +use shared_lock::SharedRwLock; +use std::cmp; +use std::env; + +/// Global style data +pub struct GlobalStyleData { + /// How many threads parallel styling can use. + pub num_threads: usize, + + /// The parallel styling thread pool. + pub style_thread_pool: Option, + + /// Shared RWLock for CSSOM objects + pub shared_lock: SharedRwLock, +} + +lazy_static! { + /// Global style data + pub static ref GLOBAL_STYLE_DATA: GlobalStyleData = { + let stylo_threads = env::var("STYLO_THREADS") + .map(|s| s.parse::().expect("invalid STYLO_THREADS value")); + let num_threads = match stylo_threads { + Ok(num) => num, + _ => cmp::max(num_cpus::get() * 3 / 4, 1), + }; + + let pool = if num_threads <= 1 { + None + } else { + let configuration = + rayon::Configuration::new().set_num_threads(num_threads); + let pool = rayon::ThreadPool::new(configuration).ok(); + pool + }; + + GlobalStyleData { + num_threads: num_threads, + style_thread_pool: pool, + shared_lock: SharedRwLock::new(), + } + }; +} diff --git a/components/style/gecko/mod.rs b/components/style/gecko/mod.rs index 2ee19fc60fc..48d50c5fa80 100644 --- a/components/style/gecko/mod.rs +++ b/components/style/gecko/mod.rs @@ -10,6 +10,7 @@ mod non_ts_pseudo_class_list; pub mod arc_types; pub mod conversions; pub mod data; +pub mod global_style_data; pub mod media_queries; pub mod restyle_damage; pub mod selector_parser; diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index fa057a4ae26..b9cab601f2c 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -20,6 +20,7 @@ use dom::{AnimationRules, LayoutIterator, NodeInfo, TElement, TNode, UnsafeNode} use dom::{OpaqueNode, PresentationalHintsSynthetizer}; use element_state::ElementState; use error_reporting::StdoutErrorReporter; +use gecko::global_style_data::GLOBAL_STYLE_DATA; use gecko::selector_parser::{SelectorImpl, NonTSPseudoClass, PseudoElement}; use gecko::snapshot_helpers; use gecko_bindings::bindings; @@ -53,6 +54,7 @@ use selectors::Element; use selectors::matching::{ElementSelectorFlags, StyleRelations, matches_complex_selector}; use selectors::parser::{AttrSelector, NamespaceConstraint}; use servo_url::ServoUrl; +use shared_lock::Locked; use sink::Push; use std::fmt; use std::ptr; @@ -407,12 +409,14 @@ fn selector_flags_to_node_flags(flags: ElementSelectorFlags) -> u32 { fn get_animation_rule(element: &GeckoElement, pseudo: Option<&PseudoElement>, cascade_level: CascadeLevel) - -> Option>> { + -> Option>> { let atom_ptr = PseudoElement::ns_atom_or_null_from_opt(pseudo); let animation_values = Arc::new(RwLock::new(AnimationValueMap::new())); if unsafe { Gecko_GetAnimationRule(element.0, atom_ptr, cascade_level, HasArcFFI::arc_as_borrowed(&animation_values)) } { - Some(Arc::new(RwLock::new(PropertyDeclarationBlock::from_animation_value_map(&animation_values.read())))) + let shared_lock = &GLOBAL_STYLE_DATA.shared_lock; + Some(Arc::new(shared_lock.wrap( + PropertyDeclarationBlock::from_animation_value_map(&animation_values.read())))) } else { None } @@ -425,7 +429,7 @@ impl<'le> TElement for GeckoElement<'le> { unsafe { GeckoNode(&*(self.0 as *const _ as *const RawGeckoNode)) } } - fn style_attribute(&self) -> Option<&Arc>> { + fn style_attribute(&self) -> Option<&Arc>> { let declarations = unsafe { Gecko_GetStyleAttrDeclarationBlock(self.0) }; declarations.map(|s| s.as_arc_opt()).unwrap_or(None) } @@ -436,12 +440,12 @@ impl<'le> TElement for GeckoElement<'le> { } fn get_animation_rule(&self, pseudo: Option<&PseudoElement>) - -> Option>> { + -> Option>> { get_animation_rule(self, pseudo, CascadeLevel::Animations) } fn get_transition_rule(&self, pseudo: Option<&PseudoElement>) - -> Option>> { + -> Option>> { get_animation_rule(self, pseudo, CascadeLevel::Transitions) } diff --git a/components/style/keyframes.rs b/components/style/keyframes.rs index 44ca0921706..67f0c848f8d 100644 --- a/components/style/keyframes.rs +++ b/components/style/keyframes.rs @@ -8,14 +8,13 @@ use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, RuleListParser}; use cssparser::{DeclarationListParser, DeclarationParser, parse_one_rule}; -use parking_lot::RwLock; use parser::{ParserContext, ParserContextExtraData, log_css_error}; use properties::{Importance, PropertyDeclaration, PropertyDeclarationBlock, PropertyId}; use properties::{PropertyDeclarationId, LonghandId, ParsedDeclaration}; use properties::LonghandIdSet; use properties::animated_properties::TransitionProperty; use properties::longhands::transition_timing_function::single_value::SpecifiedValue as SpecifiedTimingFunction; -use shared_lock::{SharedRwLock, SharedRwLockReadGuard, Locked}; +use shared_lock::{SharedRwLock, SharedRwLockReadGuard, Locked, ToCssWithGuard}; use std::fmt; use std::sync::Arc; use style_traits::ToCss; @@ -102,11 +101,12 @@ pub struct Keyframe { /// /// Note that `!important` rules in keyframes don't apply, but we keep this /// `Arc` just for convenience. - pub block: Arc>, + pub block: Arc>, } -impl ToCss for Keyframe { - fn to_css(&self, dest: &mut W) -> fmt::Result where W: fmt::Write { +impl ToCssWithGuard for Keyframe { + fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result + where W: fmt::Write { let mut iter = self.selector.percentages().iter(); try!(iter.next().unwrap().to_css(dest)); for percentage in iter { @@ -114,7 +114,7 @@ impl ToCss for Keyframe { try!(percentage.to_css(dest)); } try!(dest.write_str(" { ")); - try!(self.block.read().to_css(dest)); + try!(self.block.read_with(guard).to_css(dest)); try!(dest.write_str(" }")); Ok(()) } @@ -154,7 +154,7 @@ pub enum KeyframesStepValue { Declarations { /// The declaration block per se. #[cfg_attr(feature = "servo", ignore_heap_size_of = "Arc")] - block: Arc> + block: Arc> }, /// A synthetic step computed from the current computed values at the time /// of the animation. @@ -180,10 +180,11 @@ pub struct KeyframesStep { impl KeyframesStep { #[inline] fn new(percentage: KeyframePercentage, - value: KeyframesStepValue) -> Self { + value: KeyframesStepValue, + guard: &SharedRwLockReadGuard) -> Self { let declared_timing_function = match value { KeyframesStepValue::Declarations { ref block } => { - block.read().declarations().iter().any(|&(ref prop_decl, _)| { + block.read_with(guard).declarations().iter().any(|&(ref prop_decl, _)| { match *prop_decl { PropertyDeclaration::AnimationTimingFunction(..) => true, _ => false, @@ -201,13 +202,14 @@ impl KeyframesStep { } /// Return specified TransitionTimingFunction if this KeyframesSteps has 'animation-timing-function'. - pub fn get_animation_timing_function(&self) -> Option { + pub fn get_animation_timing_function(&self, guard: &SharedRwLockReadGuard) + -> Option { if !self.declared_timing_function { return None; } match self.value { KeyframesStepValue::Declarations { ref block } => { - let guard = block.read(); + let guard = block.read_with(guard); let &(ref declaration, _) = guard.get(PropertyDeclarationId::Longhand(LonghandId::AnimationTimingFunction)).unwrap(); match *declaration { @@ -249,7 +251,8 @@ fn get_animated_properties(keyframes: &[Arc>], guard: &SharedRw // it here. for keyframe in keyframes { let keyframe = keyframe.read_with(&guard); - for &(ref declaration, importance) in keyframe.block.read().declarations().iter() { + let block = keyframe.block.read_with(guard); + for &(ref declaration, importance) in block.declarations().iter() { assert!(!importance.important()); if let Some(property) = TransitionProperty::from_declaration(declaration) { @@ -294,7 +297,7 @@ impl KeyframesAnimation { for percentage in keyframe.selector.0.iter() { result.steps.push(KeyframesStep::new(*percentage, KeyframesStepValue::Declarations { block: keyframe.block.clone(), - })); + }, guard)); } } @@ -304,12 +307,14 @@ impl KeyframesAnimation { // Prepend autogenerated keyframes if appropriate. if result.steps[0].start_percentage.0 != 0. { result.steps.insert(0, KeyframesStep::new(KeyframePercentage::new(0.), - KeyframesStepValue::ComputedValues)); + KeyframesStepValue::ComputedValues, + guard)); } if result.steps.last().unwrap().start_percentage.0 != 1. { result.steps.push(KeyframesStep::new(KeyframePercentage::new(1.), - KeyframesStepValue::ComputedValues)); + KeyframesStepValue::ComputedValues, + guard)); } result @@ -381,7 +386,7 @@ impl<'a> QualifiedRuleParser for KeyframeListParser<'a> { } Ok(Arc::new(self.shared_lock.wrap(Keyframe { selector: prelude, - block: Arc::new(RwLock::new(block)), + block: Arc::new(self.shared_lock.wrap(block)), }))) } } diff --git a/components/style/lib.rs b/components/style/lib.rs index eabb8d20c51..ab564c59bd8 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -57,6 +57,7 @@ extern crate log; #[macro_use] extern crate matches; #[cfg(feature = "gecko")] extern crate nsstring_vendor as nsstring; +#[cfg(feature = "gecko")] extern crate num_cpus; extern crate num_integer; extern crate num_traits; extern crate ordered_float; diff --git a/components/style/matching.rs b/components/style/matching.rs index f58d429beb0..38552ff46da 100644 --- a/components/style/matching.rs +++ b/components/style/matching.rs @@ -886,7 +886,8 @@ pub trait MatchMethods : TElement { let new_node = context.shared.stylist.rule_tree .update_rule_at_level(CascadeLevel::StyleAttributeNormal, style_attribute, - primary_rules); + primary_rules, + &context.shared.guards); if let Some(n) = new_node { *primary_rules = n; rule_node_changed = true; @@ -895,7 +896,8 @@ pub trait MatchMethods : TElement { let new_node = context.shared.stylist.rule_tree .update_rule_at_level(CascadeLevel::StyleAttributeImportant, style_attribute, - primary_rules); + primary_rules, + &context.shared.guards); if let Some(n) = new_node { *primary_rules = n; rule_node_changed = true; diff --git a/components/style/rule_tree/mod.rs b/components/style/rule_tree/mod.rs index c1d4b27edf5..80aa88596d6 100644 --- a/components/style/rule_tree/mod.rs +++ b/components/style/rule_tree/mod.rs @@ -10,7 +10,6 @@ use arc_ptr_eq; #[cfg(feature = "servo")] use heapsize::HeapSizeOf; -use parking_lot::{RwLock, RwLockReadGuard}; use properties::{Importance, PropertyDeclarationBlock}; use shared_lock::{Locked, ReadGuards, SharedRwLockReadGuard}; use std::io::{self, Write}; @@ -54,7 +53,7 @@ pub enum StyleSource { /// A style rule stable pointer. Style(Arc>), /// A declaration block stable pointer. - Declarations(Arc>), + Declarations(Arc>), } impl StyleSource { @@ -82,13 +81,12 @@ impl StyleSource { /// Read the style source guard, and obtain thus read access to the /// underlying property declaration block. #[inline] - pub fn read<'a>(&'a self, guard: &'a SharedRwLockReadGuard) - -> RwLockReadGuard<'a, PropertyDeclarationBlock> { + pub fn read<'a>(&'a self, guard: &'a SharedRwLockReadGuard) -> &'a PropertyDeclarationBlock { let block = match *self { StyleSource::Style(ref rule) => &rule.read_with(guard).block, StyleSource::Declarations(ref block) => block, }; - block.read() + block.read_with(guard) } } @@ -162,8 +160,9 @@ impl RuleTree { /// the old path is still valid. pub fn update_rule_at_level(&self, level: CascadeLevel, - pdb: Option<&Arc>>, - path: &StrongRuleNode) + pdb: Option<&Arc>>, + path: &StrongRuleNode, + guards: &ReadGuards) -> Option { debug_assert!(level.is_unique_per_element()); // TODO(emilio): Being smarter with lifetimes we could avoid a bit of @@ -222,13 +221,13 @@ impl RuleTree { // pretty bad styling cases already. if let Some(pdb) = pdb { if level.is_important() { - if pdb.read().any_important() { + if pdb.read_with(level.guard(guards)).any_important() { current = current.ensure_child(self.root.downgrade(), StyleSource::Declarations(pdb.clone()), level); } } else { - if pdb.read().any_normal() { + if pdb.read_with(level.guard(guards)).any_normal() { current = current.ensure_child(self.root.downgrade(), StyleSource::Declarations(pdb.clone()), level); diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index 96c553c4a49..95104a4df60 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -469,7 +469,7 @@ impl ToCssWithGuard for KeyframesRule { } first = false; let keyframe = lock.read_with(&guard); - try!(keyframe.to_css(dest)); + try!(keyframe.to_css(guard, dest)); } dest.write_str(" }") } @@ -528,19 +528,19 @@ impl ToCssWithGuard for SupportsRule { #[derive(Debug)] pub struct StyleRule { pub selectors: SelectorList, - pub block: Arc>, + pub block: Arc>, } impl ToCssWithGuard for StyleRule { // https://drafts.csswg.org/cssom/#serialize-a-css-rule CSSStyleRule - fn to_css(&self, _guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result + fn to_css(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result where W: fmt::Write { // Step 1 try!(self.selectors.to_css(dest)); // Step 2 try!(dest.write_str(" { ")); // Step 3 - let declaration_block = self.block.read(); + let declaration_block = self.block.read_with(guard); try!(declaration_block.to_css(dest)); // Step 4 if declaration_block.declarations().len() > 0 { @@ -1018,9 +1018,10 @@ impl<'a, 'b> QualifiedRuleParser for NestedRuleParser<'a, 'b> { fn parse_block(&mut self, prelude: SelectorList, input: &mut Parser) -> Result { + let declarations = parse_property_declaration_list(self.context, input); Ok(CssRule::Style(Arc::new(self.shared_lock.wrap(StyleRule { selectors: prelude, - block: Arc::new(RwLock::new(parse_property_declaration_list(self.context, input))) + block: Arc::new(self.shared_lock.wrap(declarations)) })))) } } diff --git a/components/style/stylist.rs b/components/style/stylist.rs index 2166e81946a..d58e0dd0e85 100644 --- a/components/style/stylist.rs +++ b/components/style/stylist.rs @@ -12,7 +12,6 @@ use dom::{AnimationRules, PresentationalHintsSynthetizer, TElement}; use error_reporting::StdoutErrorReporter; use keyframes::KeyframesAnimation; use media_queries::Device; -use parking_lot::RwLock; use pdqsort::sort_by; use properties::{self, CascadeFlags, ComputedValues}; #[cfg(feature = "servo")] @@ -542,7 +541,7 @@ impl Stylist { &self, element: &E, parent_bf: Option<&BloomFilter>, - style_attribute: Option<&Arc>>, + style_attribute: Option<&Arc>>, animation_rules: AnimationRules, pseudo_element: Option<&PseudoElement>, guards: &ReadGuards, @@ -613,7 +612,7 @@ impl Stylist { // Step 4: Normal style attributes. if let Some(sa) = style_attribute { - if sa.read().any_normal() { + if sa.read_with(guards.author).any_normal() { relations |= AFFECTED_BY_STYLE_ATTRIBUTE; Push::push( applicable_declarations, @@ -649,7 +648,7 @@ impl Stylist { // Step 7: `!important` style attributes. if let Some(sa) = style_attribute { - if sa.read().any_important() { + if sa.read_with(guards.author).any_important() { relations |= AFFECTED_BY_STYLE_ATTRIBUTE; Push::push( applicable_declarations, @@ -1005,7 +1004,7 @@ impl SelectorMap { if rule.selector.compound_selector.is_empty() && rule.selector.next.is_none() { let style_rule = rule.style_rule.read_with(guard); - let block = style_rule.block.read(); + let block = style_rule.block.read_with(guard); if block.any_normal() { matching_rules_list.push( rule.to_applicable_declaration_block(cascade_level)); @@ -1069,7 +1068,7 @@ impl SelectorMap { { for rule in rules.iter() { let style_rule = rule.style_rule.read_with(guard); - let block = style_rule.block.read(); + let block = style_rule.block.read_with(guard); let any_declaration_for_importance = if cascade_level.is_important() { block.any_important() } else { @@ -1208,7 +1207,7 @@ impl ApplicableDeclarationBlock { /// Constructs an applicable declaration block from a given property /// declaration block and importance. #[inline] - pub fn from_declarations(declarations: Arc>, + pub fn from_declarations(declarations: Arc>, level: CascadeLevel) -> Self { ApplicableDeclarationBlock { diff --git a/ports/geckolib/Cargo.toml b/ports/geckolib/Cargo.toml index 9ed52128eaf..40e9b7e65ad 100644 --- a/ports/geckolib/Cargo.toml +++ b/ports/geckolib/Cargo.toml @@ -20,9 +20,7 @@ env_logger = {version = "0.4", default-features = false} # disable `regex` to re lazy_static = "0.2" libc = "0.2" log = {version = "0.3.5", features = ["release_max_level_info"]} -num_cpus = "1.1.0" parking_lot = "0.3" -rayon = "0.6" selectors = {path = "../../components/selectors"} servo_url = {path = "../../components/url"} style = {path = "../../components/style", features = ["gecko"]} diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index bbe8bc6907d..f39e4a903cc 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -6,13 +6,10 @@ use atomic_refcell::AtomicRefMut; use cssparser::Parser; use cssparser::ToCss as ParserToCss; use env_logger::LogBuilder; -use num_cpus; use parking_lot::RwLock; -use rayon; use selectors::Element; use servo_url::ServoUrl; use std::borrow::Cow; -use std::cmp; use std::env; use std::fmt::Write; use std::ptr; @@ -24,6 +21,7 @@ use style::data::{ElementData, ElementStyles, RestyleData}; use style::dom::{ShowSubtreeData, TElement, TNode}; use style::error_reporting::StdoutErrorReporter; use style::gecko::data::{PerDocumentStyleData, PerDocumentStyleDataImpl}; +use style::gecko::global_style_data::GLOBAL_STYLE_DATA; use style::gecko::restyle_damage::GeckoRestyleDamage; use style::gecko::selector_parser::{SelectorImpl, PseudoElement}; use style::gecko::traversal::RecalcStyleOnly; @@ -96,48 +94,7 @@ use super::stylesheet_loader::StylesheetLoader; * depend on but good enough for our purposes. */ -pub struct GlobalStyleData { - // How many threads parallel styling can use. - pub num_threads: usize, - // The parallel styling thread pool. - pub style_thread_pool: Option, - - // Shared RWLock for CSSOM objects - pub shared_lock: SharedRwLock, -} - -impl GlobalStyleData { - pub fn new() -> Self { - let stylo_threads = env::var("STYLO_THREADS") - .map(|s| s.parse::().expect("invalid STYLO_THREADS value")); - let num_threads = match stylo_threads { - Ok(num) => num, - _ => cmp::max(num_cpus::get() * 3 / 4, 1), - }; - - let pool = if num_threads <= 1 { - None - } else { - let configuration = - rayon::Configuration::new().set_num_threads(num_threads); - let pool = rayon::ThreadPool::new(configuration).ok(); - pool - }; - - GlobalStyleData { - num_threads: num_threads, - style_thread_pool: pool, - shared_lock: SharedRwLock::new(), - } - } -} - -lazy_static! { - pub static ref GLOBAL_STYLE_DATA: GlobalStyleData = { - GlobalStyleData::new() - }; -} #[no_mangle] pub extern "C" fn Servo_Initialize() { @@ -638,7 +595,7 @@ pub extern "C" fn Servo_StyleRule_SetStyle(rule: RawServoStyleRuleBorrowed, let global_style_data = &*GLOBAL_STYLE_DATA; let mut guard = global_style_data.shared_lock.write(); let rule = Locked::::as_arc(&rule); - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); rule.write_with(&mut guard).block = declarations.clone(); } @@ -829,9 +786,10 @@ pub extern "C" fn Servo_ParseProperty(property: *const nsACString, value: *const match ParsedDeclaration::parse(id, &context, &mut Parser::new(value), false) { Ok(parsed) => { + let global_style_data = &*GLOBAL_STYLE_DATA; let mut block = PropertyDeclarationBlock::new(); parsed.expand(|d| block.push(d, Importance::Normal)); - Arc::new(RwLock::new(block)).into_strong() + Arc::new(global_style_data.shared_lock.wrap(block)).into_strong() } Err(_) => RawServoDeclarationBlockStrong::null() } @@ -842,36 +800,47 @@ pub extern "C" fn Servo_ParseStyleAttribute(data: *const nsACString, base: *const nsACString, raw_extra_data: *const structs::GeckoParserExtraData) -> RawServoDeclarationBlockStrong { + let global_style_data = &*GLOBAL_STYLE_DATA; let value = unsafe { data.as_ref().unwrap().as_str_unchecked() }; make_context!((base, raw_extra_data) => (base_url, extra_data)); - Arc::new(RwLock::new(GeckoElement::parse_style_attribute(value, &base_url, extra_data))).into_strong() + Arc::new(global_style_data.shared_lock.wrap( + GeckoElement::parse_style_attribute(value, &base_url, extra_data))).into_strong() } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_CreateEmpty() -> RawServoDeclarationBlockStrong { - Arc::new(RwLock::new(PropertyDeclarationBlock::new())).into_strong() + let global_style_data = &*GLOBAL_STYLE_DATA; + Arc::new(global_style_data.shared_lock.wrap(PropertyDeclarationBlock::new())).into_strong() } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_Clone(declarations: RawServoDeclarationBlockBorrowed) -> RawServoDeclarationBlockStrong { - let declarations = RwLock::::as_arc(&declarations); - Arc::new(RwLock::new(declarations.read().clone())).into_strong() + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let declarations = Locked::::as_arc(&declarations); + Arc::new(global_style_data.shared_lock.wrap( + declarations.read_with(&guard).clone() + )).into_strong() } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_Equals(a: RawServoDeclarationBlockBorrowed, b: RawServoDeclarationBlockBorrowed) -> bool { - *RwLock::::as_arc(&a).read().declarations() == - *RwLock::::as_arc(&b).read().declarations() + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + *Locked::::as_arc(&a).read_with(&guard).declarations() == + *Locked::::as_arc(&b).read_with(&guard).declarations() } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_GetCssText(declarations: RawServoDeclarationBlockBorrowed, result: *mut nsAString) { - let declarations = RwLock::::as_arc(&declarations); - declarations.read().to_css(unsafe { result.as_mut().unwrap() }).unwrap(); + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let declarations = Locked::::as_arc(&declarations); + declarations.read_with(&guard).to_css(unsafe { result.as_mut().unwrap() }).unwrap(); } #[no_mangle] @@ -880,9 +849,11 @@ pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue( property_id: nsCSSPropertyID, buffer: *mut nsAString) { let property_id = get_property_id_from_nscsspropertyid!(property_id, ()); - let declarations = RwLock::::as_arc(&declarations); + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let declarations = Locked::::as_arc(&declarations); let mut string = String::new(); - let rv = declarations.read().single_value_to_css(&property_id, &mut string); + let rv = declarations.read_with(&guard).single_value_to_css(&property_id, &mut string); debug_assert!(rv.is_ok()); write!(unsafe { &mut *buffer }, "{}", string).expect("Failed to copy string"); @@ -890,15 +861,19 @@ pub extern "C" fn Servo_DeclarationBlock_SerializeOneValue( #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_Count(declarations: RawServoDeclarationBlockBorrowed) -> u32 { - let declarations = RwLock::::as_arc(&declarations); - declarations.read().declarations().len() as u32 + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let declarations = Locked::::as_arc(&declarations); + declarations.read_with(&guard).declarations().len() as u32 } #[no_mangle] pub extern "C" fn Servo_DeclarationBlock_GetNthProperty(declarations: RawServoDeclarationBlockBorrowed, index: u32, result: *mut nsAString) -> bool { - let declarations = RwLock::::as_arc(&declarations); - if let Some(&(ref decl, _)) = declarations.read().declarations().get(index as usize) { + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let declarations = Locked::::as_arc(&declarations); + if let Some(&(ref decl, _)) = declarations.read_with(&guard).declarations().get(index as usize) { let result = unsafe { result.as_mut().unwrap() }; decl.id().to_css(result).unwrap(); true @@ -919,8 +894,12 @@ macro_rules! get_property_id_from_property { fn get_property_value(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId, value: *mut nsAString) { - let declarations = RwLock::::as_arc(&declarations); - declarations.read().property_value_to_css(&property_id, unsafe { value.as_mut().unwrap() }).unwrap(); + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let declarations = Locked::::as_arc(&declarations); + declarations.read_with(&guard) + .property_value_to_css(&property_id, unsafe { value.as_mut().unwrap() }) + .unwrap(); } #[no_mangle] @@ -939,8 +918,10 @@ pub extern "C" fn Servo_DeclarationBlock_GetPropertyValueById(declarations: RawS pub extern "C" fn Servo_DeclarationBlock_GetPropertyIsImportant(declarations: RawServoDeclarationBlockBorrowed, property: *const nsACString) -> bool { let property_id = get_property_id_from_property!(property, false); - let declarations = RwLock::::as_arc(&declarations); - declarations.read().property_priority(&property_id).important() + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let declarations = Locked::::as_arc(&declarations); + declarations.read_with(&guard).property_priority(&property_id).important() } fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId, @@ -951,7 +932,10 @@ fn set_property(declarations: RawServoDeclarationBlockBorrowed, property_id: Pro make_context!((base, data) => (base_url, extra_data)); if let Ok(parsed) = parse_one_declaration(property_id, value, &base_url, &StdoutErrorReporter, extra_data) { - let mut declarations = RwLock::::as_arc(&declarations).write(); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + let declarations = Locked::::as_arc(&declarations) + .write_with(&mut guard); let importance = if is_important { Importance::Important } else { Importance::Normal }; let mut changed = false; parsed.expand(|decl| { @@ -984,8 +968,10 @@ pub extern "C" fn Servo_DeclarationBlock_SetPropertyById(declarations: RawServoD } fn remove_property(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId) { - let declarations = RwLock::::as_arc(&declarations); - declarations.write().remove_property(&property_id); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + let declarations = Locked::::as_arc(&declarations); + declarations.write_with(&mut guard).remove_property(&property_id); } #[no_mangle] @@ -1095,9 +1081,11 @@ pub extern "C" fn Servo_DeclarationBlock_PropertyIsSet(declarations: property: nsCSSPropertyID) -> bool { use style::properties::PropertyDeclarationId; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property, false); - declarations.read().get(PropertyDeclarationId::Longhand(long)).is_some() + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + declarations.read_with(&guard).get(PropertyDeclarationId::Longhand(long)).is_some() } #[no_mangle] @@ -1110,12 +1098,14 @@ pub extern "C" fn Servo_DeclarationBlock_SetIdentStringValue(declarations: use style::properties::{PropertyDeclaration, LonghandId}; use style::properties::longhands::_x_lang::computed_value::T as Lang; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); let prop = match_wrap_declared! { long, XLang => Lang(Atom::from(value)), }; - declarations.write().push(prop, Importance::Normal); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + declarations.write_with(&mut guard).push(prop, Importance::Normal); } #[no_mangle] @@ -1128,7 +1118,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations: use style::properties::longhands; use style::values::specified::{BorderStyle, NoCalcLength}; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); let value = value as u32; @@ -1152,7 +1142,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetKeywordValue(declarations: BorderBottomStyle => BorderStyle::from_gecko_keyword(value), BorderLeftStyle => BorderStyle::from_gecko_keyword(value), }; - declarations.write().push(prop, Importance::Normal); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + declarations.write_with(&mut guard).push(prop, Importance::Normal); } #[no_mangle] @@ -1162,12 +1154,14 @@ pub extern "C" fn Servo_DeclarationBlock_SetIntValue(declarations: RawServoDecla use style::properties::{PropertyDeclaration, LonghandId}; use style::properties::longhands::_x_span::computed_value::T as Span; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); let prop = match_wrap_declared! { long, XSpan => Span(value), }; - declarations.write().push(prop, Importance::Normal); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + declarations.write_with(&mut guard).push(prop, Importance::Normal); } #[no_mangle] @@ -1180,7 +1174,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetPixelValue(declarations: use style::values::specified::BorderWidth; use style::values::specified::length::NoCalcLength; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); let nocalc = NoCalcLength::from_px(value); @@ -1206,7 +1200,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetPixelValue(declarations: } ), }; - declarations.write().push(prop, Importance::Normal); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + declarations.write_with(&mut guard).push(prop, Importance::Normal); } #[no_mangle] @@ -1217,7 +1213,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetPercentValue(declarations: use style::properties::{PropertyDeclaration, LonghandId}; use style::values::specified::length::Percentage; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); let pc = Percentage(value); @@ -1229,7 +1225,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetPercentValue(declarations: MarginBottom => pc.into(), MarginLeft => pc.into(), }; - declarations.write().push(prop, Importance::Normal); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + declarations.write_with(&mut guard).push(prop, Importance::Normal); } #[no_mangle] @@ -1239,7 +1237,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetAutoValue(declarations: use style::properties::{PropertyDeclaration, LonghandId}; use style::values::specified::LengthOrPercentageOrAuto; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); let auto = LengthOrPercentageOrAuto::Auto; @@ -1251,7 +1249,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetAutoValue(declarations: MarginBottom => auto, MarginLeft => auto, }; - declarations.write().push(prop, Importance::Normal); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + declarations.write_with(&mut guard).push(prop, Importance::Normal); } #[no_mangle] @@ -1261,7 +1261,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetCurrentColor(declarations: use style::properties::{PropertyDeclaration, LonghandId}; use style::values::specified::{Color, CSSColor}; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); let cc = CSSColor { parsed: Color::CurrentColor, authored: None }; @@ -1271,7 +1271,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetCurrentColor(declarations: BorderBottomColor => cc, BorderLeftColor => cc, }; - declarations.write().push(prop, Importance::Normal); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + declarations.write_with(&mut guard).push(prop, Importance::Normal); } #[no_mangle] @@ -1284,7 +1286,7 @@ pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations: use style::properties::longhands; use style::values::specified::{Color, CSSColor}; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let long = get_longhand_from_id!(property); let rgba = convert_nscolor_to_rgba(value); let color = CSSColor { parsed: Color::RGBA(rgba), authored: None }; @@ -1297,7 +1299,9 @@ pub extern "C" fn Servo_DeclarationBlock_SetColorValue(declarations: Color => longhands::color::SpecifiedValue(color), BackgroundColor => color, }; - declarations.write().push(prop, Importance::Normal); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + declarations.write_with(&mut guard).push(prop, Importance::Normal); } #[no_mangle] @@ -1308,13 +1312,15 @@ pub extern "C" fn Servo_DeclarationBlock_SetFontFamily(declarations: use style::properties::PropertyDeclaration; use style::properties::longhands::font_family::SpecifiedValue as FontFamily; - let declarations = RwLock::::as_arc(&declarations); + let declarations = Locked::::as_arc(&declarations); let string = unsafe { (*value).to_string() }; let mut parser = Parser::new(&string); if let Ok(family) = FontFamily::parse(&mut parser) { if parser.is_exhausted() { + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); let decl = PropertyDeclaration::FontFamily(family); - declarations.write().push(decl, Importance::Normal); + declarations.write_with(&mut guard).push(decl, Importance::Normal); } } } @@ -1325,11 +1331,14 @@ pub extern "C" fn Servo_DeclarationBlock_SetTextDecorationColorOverride(declarat use style::properties::PropertyDeclaration; use style::properties::longhands::text_decoration_line; - let declarations = RwLock::::as_arc(&declarations); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + + let declarations = Locked::::as_arc(&declarations); let mut decoration = text_decoration_line::computed_value::none; decoration |= text_decoration_line::COLOR_OVERRIDE; let decl = PropertyDeclaration::TextDecorationLine(decoration); - declarations.write().push(decl, Importance::Normal); + declarations.write_with(&mut guard).push(decl, Importance::Normal); } #[no_mangle] @@ -1523,6 +1532,11 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis use style::properties::LonghandIdSet; use style::properties::declaration_block::Importance; use style::values::computed::Context; + + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + + let data = PerDocumentStyleData::from_ffi(raw_data).borrow(); let style = ComputedValues::as_arc(&style); @@ -1549,8 +1563,8 @@ pub extern "C" fn Servo_GetComputedKeyframeValues(keyframes: RawGeckoKeyframeLis .filter(|&property| !property.mServoDeclarationBlock.mRawPtr.is_null()); for property in iter { let declarations = unsafe { &*property.mServoDeclarationBlock.mRawPtr.clone() }; - let declarations = RwLock::::as_arc(&declarations); - let guard = declarations.read(); + let declarations = Locked::::as_arc(&declarations); + let guard = declarations.read_with(&guard); let anim_iter = guard.declarations() .iter() @@ -1614,15 +1628,18 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet use style::gecko_bindings::structs::Keyframe; use style::properties::LonghandIdSet; + let data = PerDocumentStyleData::from_ffi(raw_data).borrow(); let name = unsafe { Atom::from(name.as_ref().unwrap().as_str_unchecked()) }; let style_timing_function = unsafe { timing_function.as_ref().unwrap() }; let style = ComputedValues::as_arc(&style); if let Some(ref animation) = data.stylist.animations().get(&name) { + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); for step in &animation.steps { // Override timing_function if the keyframe has animation-timing-function. - let timing_function = if let Some(val) = step.get_animation_timing_function() { + let timing_function = if let Some(val) = step.get_animation_timing_function(&guard) { val.into() } else { *style_timing_function @@ -1637,7 +1654,8 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet fn add_computed_property_value(keyframe: *mut Keyframe, index: usize, style: &ComputedValues, - property: &TransitionProperty) { + property: &TransitionProperty, + shared_lock: &SharedRwLock) { let block = style.to_declaration_block(property.clone().into()); unsafe { (*keyframe).mPropertyValues.set_len((index + 1) as u32); @@ -1645,18 +1663,19 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet // FIXME. Do not set computed values once we handles missing keyframes // with additive composition. (*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky( - Arc::new(RwLock::new(block))); + Arc::new(shared_lock.wrap(block))); } } match step.value { KeyframesStepValue::ComputedValues => { for (index, property) in animation.properties_changed.iter().enumerate() { - add_computed_property_value(keyframe, index, style, property); + add_computed_property_value( + keyframe, index, style, property, &global_style_data.shared_lock); } }, KeyframesStepValue::Declarations { ref block } => { - let guard = block.read(); + let guard = block.read_with(&guard); // Filter out non-animatable properties. let animatable = guard.declarations() @@ -1673,8 +1692,9 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet (*keyframe).mPropertyValues.set_len((index + 1) as u32); (*keyframe).mPropertyValues[index].mProperty = property.into(); (*keyframe).mPropertyValues[index].mServoDeclarationBlock.set_arc_leaky( - Arc::new(RwLock::new(PropertyDeclarationBlock::with_one( - declaration.clone(), Importance::Normal + Arc::new(global_style_data.shared_lock.wrap( + PropertyDeclarationBlock::with_one( + declaration.clone(), Importance::Normal )))); if step.start_percentage.0 == 0. || step.start_percentage.0 == 1. { @@ -1689,7 +1709,8 @@ pub extern "C" fn Servo_StyleSet_FillKeyframesForName(raw_data: RawServoStyleSet let mut index = unsafe { (*keyframe).mPropertyValues.len() }; for property in animation.properties_changed.iter() { if !seen.has_transition_property_bit(&property) { - add_computed_property_value(keyframe, index, style, property); + add_computed_property_value( + keyframe, index, style, property, &global_style_data.shared_lock); index += 1; } } diff --git a/ports/geckolib/lib.rs b/ports/geckolib/lib.rs index 0bdbaa12f24..a7dd0561299 100644 --- a/ports/geckolib/lib.rs +++ b/ports/geckolib/lib.rs @@ -10,9 +10,7 @@ extern crate env_logger; #[macro_use] extern crate lazy_static; extern crate libc; #[macro_use] extern crate log; -extern crate num_cpus; extern crate parking_lot; -extern crate rayon; extern crate selectors; extern crate servo_url; #[macro_use] extern crate style; diff --git a/ports/geckolib/stylesheet_loader.rs b/ports/geckolib/stylesheet_loader.rs index 2e81de1a57e..5e226ee54c9 100644 --- a/ports/geckolib/stylesheet_loader.rs +++ b/ports/geckolib/stylesheet_loader.rs @@ -3,13 +3,13 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use std::sync::Arc; +use style::gecko::global_style_data::GLOBAL_STYLE_DATA; use style::gecko_bindings::bindings::Gecko_LoadStyleSheet; use style::gecko_bindings::structs::{Loader, ServoStyleSheet}; use style::gecko_bindings::sugar::ownership::HasArcFFI; use style::shared_lock::Locked; use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader}; use style_traits::ToCss; -use super::glue::GLOBAL_STYLE_DATA; pub struct StylesheetLoader(*mut Loader, *mut ServoStyleSheet); diff --git a/tests/unit/style/keyframes.rs b/tests/unit/style/keyframes.rs index a916f18da01..9fe2f0d3f39 100644 --- a/tests/unit/style/keyframes.rs +++ b/tests/unit/style/keyframes.rs @@ -2,7 +2,6 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -use parking_lot::RwLock; use std::sync::Arc; use style::keyframes::{Keyframe, KeyframesAnimation, KeyframePercentage, KeyframeSelector}; use style::keyframes::{KeyframesStep, KeyframesStepValue}; @@ -30,7 +29,7 @@ fn test_no_property_in_keyframe() { let keyframes = vec![ Arc::new(shared_lock.wrap(Keyframe { selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(1.)]), - block: Arc::new(RwLock::new(PropertyDeclarationBlock::new())) + block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::new())) })), ]; let animation = KeyframesAnimation::from_keyframes(&keyframes, &shared_lock.read()); @@ -46,14 +45,14 @@ fn test_no_property_in_keyframe() { fn test_missing_property_in_initial_keyframe() { let shared_lock = SharedRwLock::new(); let declarations_on_initial_keyframe = - Arc::new(RwLock::new(PropertyDeclarationBlock::with_one( + Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one( PropertyDeclaration::Width( LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), Importance::Normal ))); let declarations_on_final_keyframe = - Arc::new(RwLock::new({ + Arc::new(shared_lock.wrap({ let mut block = PropertyDeclarationBlock::new(); block.push( PropertyDeclaration::Width( @@ -103,7 +102,7 @@ fn test_missing_property_in_initial_keyframe() { fn test_missing_property_in_final_keyframe() { let shared_lock = SharedRwLock::new(); let declarations_on_initial_keyframe = - Arc::new(RwLock::new({ + Arc::new(shared_lock.wrap({ let mut block = PropertyDeclarationBlock::new(); block.push( PropertyDeclaration::Width( @@ -119,7 +118,7 @@ fn test_missing_property_in_final_keyframe() { })); let declarations_on_final_keyframe = - Arc::new(RwLock::new(PropertyDeclarationBlock::with_one( + Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one( PropertyDeclaration::Height( LengthOrPercentageOrAuto::Length(NoCalcLength::from_px(20f32))), Importance::Normal, @@ -160,7 +159,7 @@ fn test_missing_property_in_final_keyframe() { fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() { let shared_lock = SharedRwLock::new(); let declarations = - Arc::new(RwLock::new({ + Arc::new(shared_lock.wrap({ let mut block = PropertyDeclarationBlock::new(); block.push( PropertyDeclaration::Width( @@ -178,7 +177,7 @@ fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() { let keyframes = vec![ Arc::new(shared_lock.wrap(Keyframe { selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.)]), - block: Arc::new(RwLock::new(PropertyDeclarationBlock::new())) + block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::new())) })), Arc::new(shared_lock.wrap(Keyframe { selector: KeyframeSelector::new_for_unit_testing(vec![KeyframePercentage::new(0.5)]), @@ -191,7 +190,7 @@ fn test_missing_keyframe_in_both_of_initial_and_final_keyframe() { KeyframesStep { start_percentage: KeyframePercentage(0.), value: KeyframesStepValue::Declarations { - block: Arc::new(RwLock::new( + block: Arc::new(shared_lock.wrap( // XXX: Should we use ComputedValues in this case? PropertyDeclarationBlock::new() )) diff --git a/tests/unit/style/rule_tree/bench.rs b/tests/unit/style/rule_tree/bench.rs index aeac93912aa..4d4012f16c1 100644 --- a/tests/unit/style/rule_tree/bench.rs +++ b/tests/unit/style/rule_tree/bench.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use cssparser::{Parser, SourcePosition}; -use parking_lot::RwLock; use rayon; use servo_url::ServoUrl; use std::sync::Arc; @@ -65,9 +64,11 @@ fn test_insertion(rule_tree: &RuleTree, rules: Vec<(StyleSource, CascadeLevel)>) rule_tree.insert_ordered_rules(rules.into_iter()) } -fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, CascadeLevel)]) -> StrongRuleNode { +fn test_insertion_style_attribute(rule_tree: &RuleTree, rules: &[(StyleSource, CascadeLevel)], + shared_lock: &SharedRwLock) + -> StrongRuleNode { let mut rules = rules.to_vec(); - rules.push((StyleSource::Declarations(Arc::new(RwLock::new(PropertyDeclarationBlock::with_one( + rules.push((StyleSource::Declarations(Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one( PropertyDeclaration::Display( longhands::display::SpecifiedValue::block), Importance::Normal @@ -121,11 +122,12 @@ fn bench_expensive_insertion(b: &mut Bencher) { .bar { height: 500px; } \ .baz { display: block; }"); + let shared_lock = SharedRwLock::new(); b.iter(|| { let _gc = AutoGCRuleTree::new(&r); for _ in 0..(4000 + 400) { - test::black_box(test_insertion_style_attribute(&r, &rules_matched)); + test::black_box(test_insertion_style_attribute(&r, &rules_matched, &shared_lock)); } }); } @@ -170,6 +172,7 @@ fn bench_expensive_insersion_parallel(b: &mut Bencher) { .bar { height: 500px; } \ .baz { display: block; }"); + let shared_lock = SharedRwLock::new(); b.iter(|| { let _gc = AutoGCRuleTree::new(&r); @@ -178,12 +181,14 @@ fn bench_expensive_insersion_parallel(b: &mut Bencher) { s.spawn(|s| { for _ in 0..1000 { test::black_box(test_insertion_style_attribute(&r, - &rules_matched)); + &rules_matched, + &shared_lock)); } s.spawn(|_| { for _ in 0..100 { test::black_box(test_insertion_style_attribute(&r, - &rules_matched)); + &rules_matched, + &shared_lock)); } }) }) diff --git a/tests/unit/style/stylesheets.rs b/tests/unit/style/stylesheets.rs index 2bcb9b58a77..fa6a26963f8 100644 --- a/tests/unit/style/stylesheets.rs +++ b/tests/unit/style/stylesheets.rs @@ -109,7 +109,7 @@ fn test_parse_stylesheet() { specificity: (0 << 20) + (1 << 10) + (1 << 0), }, ]), - block: Arc::new(RwLock::new(block_from(vec![ + block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ (PropertyDeclaration::Display(longhands::display::SpecifiedValue::none), Importance::Important), (PropertyDeclaration::Custom(Atom::from("a"), @@ -154,7 +154,7 @@ fn test_parse_stylesheet() { specificity: (0 << 20) + (0 << 10) + (1 << 0), }, ]), - block: Arc::new(RwLock::new(block_from(vec![ + block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ (PropertyDeclaration::Display(longhands::display::SpecifiedValue::block), Importance::Normal), ]))), @@ -185,7 +185,7 @@ fn test_parse_stylesheet() { specificity: (1 << 20) + (1 << 10) + (0 << 0), }, ]), - block: Arc::new(RwLock::new(block_from(vec![ + block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ (PropertyDeclaration::BackgroundColor( longhands::background_color::SpecifiedValue { authored: Some("blue".to_owned().into_boxed_str()), @@ -241,7 +241,7 @@ fn test_parse_stylesheet() { Arc::new(stylesheet.shared_lock.wrap(Keyframe { selector: KeyframeSelector::new_for_unit_testing( vec![KeyframePercentage::new(0.)]), - block: Arc::new(RwLock::new(block_from(vec![ + block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ (PropertyDeclaration::Width( LengthOrPercentageOrAuto::Percentage(Percentage(0.))), Importance::Normal), @@ -250,7 +250,7 @@ fn test_parse_stylesheet() { Arc::new(stylesheet.shared_lock.wrap(Keyframe { selector: KeyframeSelector::new_for_unit_testing( vec![KeyframePercentage::new(1.)]), - block: Arc::new(RwLock::new(block_from(vec![ + block: Arc::new(stylesheet.shared_lock.wrap(block_from(vec![ (PropertyDeclaration::Width( LengthOrPercentageOrAuto::Percentage(Percentage(1.))), Importance::Normal), diff --git a/tests/unit/style/stylist.rs b/tests/unit/style/stylist.rs index 34a7feff965..8f559703cbe 100644 --- a/tests/unit/style/stylist.rs +++ b/tests/unit/style/stylist.rs @@ -3,7 +3,6 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ use html5ever_atoms::LocalName; -use parking_lot::RwLock; use selectors::parser::LocalName as LocalNameSelector; use servo_atoms::Atom; use std::sync::Arc; @@ -25,7 +24,7 @@ fn get_mock_rules(css_selectors: &[&str]) -> (Vec>, SharedRwLock) { let locked = Arc::new(shared_lock.wrap(StyleRule { selectors: selectors, - block: Arc::new(RwLock::new(PropertyDeclarationBlock::with_one( + block: Arc::new(shared_lock.wrap(PropertyDeclarationBlock::with_one( PropertyDeclaration::Display( longhands::display::SpecifiedValue::block), Importance::Normal