diff options
-rw-r--r-- | components/script/dom/bindings/trace.rs | 4 | ||||
-rw-r--r-- | components/script/dom/cssconditionrule.rs | 4 | ||||
-rw-r--r-- | components/script/dom/cssgroupingrule.rs | 4 | ||||
-rw-r--r-- | components/script/dom/cssmediarule.rs | 7 | ||||
-rw-r--r-- | components/script/dom/medialist.rs | 44 | ||||
-rw-r--r-- | components/style/gecko/arc_types.rs | 3 | ||||
-rw-r--r-- | components/style/stylesheets.rs | 13 | ||||
-rw-r--r-- | ports/geckolib/glue.rs | 38 |
8 files changed, 79 insertions, 38 deletions
diff --git a/components/script/dom/bindings/trace.rs b/components/script/dom/bindings/trace.rs index b0828ab6d56..b0fabb5fd45 100644 --- a/components/script/dom/bindings/trace.rs +++ b/components/script/dom/bindings/trace.rs @@ -99,7 +99,7 @@ use style::keyframes::Keyframe; use style::media_queries::MediaList; use style::properties::PropertyDeclarationBlock; use style::selector_parser::{PseudoElement, Snapshot}; -use style::shared_lock::SharedRwLock as StyleSharedRwLock; +use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked}; use style::stylesheets::{CssRules, KeyframesRule, MediaRule, NamespaceRule, StyleRule, ImportRule}; use style::stylesheets::SupportsRule; use style::values::specified::Length; @@ -574,7 +574,7 @@ unsafe impl JSTraceable for RwLock<SharedRt> { } } -unsafe impl JSTraceable for RwLock<MediaList> { +unsafe impl JSTraceable for StyleLocked<MediaList> { unsafe fn trace(&self, _trc: *mut JSTracer) { // Do nothing. } diff --git a/components/script/dom/cssconditionrule.rs b/components/script/dom/cssconditionrule.rs index 42fca721759..44d10c21dd3 100644 --- a/components/script/dom/cssconditionrule.rs +++ b/components/script/dom/cssconditionrule.rs @@ -28,6 +28,10 @@ impl CSSConditionRule { } } + pub fn parent_stylesheet(&self) -> &CSSStyleSheet { + self.cssgroupingrule.parent_stylesheet() + } + pub fn shared_lock(&self) -> &SharedRwLock { self.cssgroupingrule.shared_lock() } diff --git a/components/script/dom/cssgroupingrule.rs b/components/script/dom/cssgroupingrule.rs index 29f6bc361a2..7204b8447f9 100644 --- a/components/script/dom/cssgroupingrule.rs +++ b/components/script/dom/cssgroupingrule.rs @@ -42,6 +42,10 @@ impl CSSGroupingRule { RulesSource::Rules(self.rules.clone()))) } + pub fn parent_stylesheet(&self) -> &CSSStyleSheet { + self.cssrule.parent_stylesheet() + } + pub fn shared_lock(&self) -> &SharedRwLock { self.cssrule.shared_lock() } diff --git a/components/script/dom/cssmediarule.rs b/components/script/dom/cssmediarule.rs index 9242ee01bb7..1d1f0846a51 100644 --- a/components/script/dom/cssmediarule.rs +++ b/components/script/dom/cssmediarule.rs @@ -50,22 +50,25 @@ impl CSSMediaRule { fn medialist(&self) -> Root<MediaList> { self.medialist.or_init(|| MediaList::new(self.global().as_window(), + self.cssconditionrule.parent_stylesheet(), self.mediarule.read().media_queries.clone())) } /// https://drafts.csswg.org/css-conditional-3/#the-cssmediarule-interface pub fn get_condition_text(&self) -> DOMString { + let guard = self.cssconditionrule.shared_lock().read(); let rule = self.mediarule.read(); - let list = rule.media_queries.read(); + let list = rule.media_queries.read_with(&guard); list.to_css_string().into() } /// https://drafts.csswg.org/css-conditional-3/#the-cssmediarule-interface pub fn set_condition_text(&self, text: DOMString) { + let mut guard = self.cssconditionrule.shared_lock().write(); let mut input = Parser::new(&text); let new_medialist = parse_media_query_list(&mut input); let rule = self.mediarule.read(); - let mut list = rule.media_queries.write(); + let mut list = rule.media_queries.write_with(&mut guard); *list = new_medialist; } } diff --git a/components/script/dom/medialist.rs b/components/script/dom/medialist.rs index 806946f6356..0020f7f3a08 100644 --- a/components/script/dom/medialist.rs +++ b/components/script/dom/medialist.rs @@ -6,13 +6,14 @@ use core::default::Default; use cssparser::Parser; use dom::bindings::codegen::Bindings::MediaListBinding; use dom::bindings::codegen::Bindings::MediaListBinding::MediaListMethods; -use dom::bindings::js::Root; +use dom::bindings::js::{JS, Root}; use dom::bindings::reflector::{Reflector, reflect_dom_object}; use dom::bindings::str::DOMString; +use dom::cssstylesheet::CSSStyleSheet; use dom::window::Window; use dom_struct::dom_struct; -use parking_lot::RwLock; use std::sync::Arc; +use style::shared_lock::{SharedRwLock, Locked}; use style::media_queries::{MediaQuery, parse_media_query_list}; use style::media_queries::MediaList as StyleMediaList; use style_traits::ToCss; @@ -20,38 +21,47 @@ use style_traits::ToCss; #[dom_struct] pub struct MediaList { reflector_: Reflector, + parent_stylesheet: JS<CSSStyleSheet>, #[ignore_heap_size_of = "Arc"] - media_queries: Arc<RwLock<StyleMediaList>>, + media_queries: Arc<Locked<StyleMediaList>>, } impl MediaList { #[allow(unrooted_must_root)] - pub fn new_inherited(media_queries: Arc<RwLock<StyleMediaList>>) -> MediaList { + pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, + media_queries: Arc<Locked<StyleMediaList>>) -> MediaList { MediaList { + parent_stylesheet: JS::from_ref(parent_stylesheet), reflector_: Reflector::new(), media_queries: media_queries, } } #[allow(unrooted_must_root)] - pub fn new(window: &Window, media_queries: Arc<RwLock<StyleMediaList>>) + pub fn new(window: &Window, parent_stylesheet: &CSSStyleSheet, + media_queries: Arc<Locked<StyleMediaList>>) -> Root<MediaList> { - reflect_dom_object(box MediaList::new_inherited(media_queries), + reflect_dom_object(box MediaList::new_inherited(parent_stylesheet, media_queries), window, MediaListBinding::Wrap) } + fn shared_lock(&self) -> &SharedRwLock { + &self.parent_stylesheet.style_stylesheet().shared_lock + } } impl MediaListMethods for MediaList { // https://drafts.csswg.org/cssom/#dom-medialist-mediatext fn MediaText(&self) -> DOMString { - DOMString::from(self.media_queries.read().to_css_string()) + let guard = self.shared_lock().read(); + DOMString::from(self.media_queries.read_with(&guard).to_css_string()) } // https://drafts.csswg.org/cssom/#dom-medialist-mediatext fn SetMediaText(&self, value: DOMString) { - let mut media_queries = self.media_queries.write(); + let mut guard = self.shared_lock().write(); + let mut media_queries = self.media_queries.write_with(&mut guard); // Step 2 if value.is_empty() { // Step 1 @@ -65,13 +75,15 @@ impl MediaListMethods for MediaList { // https://drafts.csswg.org/cssom/#dom-medialist-length fn Length(&self) -> u32 { - self.media_queries.read().media_queries.len() as u32 + let guard = self.shared_lock().read(); + self.media_queries.read_with(&guard).media_queries.len() as u32 } // https://drafts.csswg.org/cssom/#dom-medialist-item fn Item(&self, index: u32) -> Option<DOMString> { - self.media_queries.read().media_queries.get(index as usize) - .and_then(|query| { + let guard = self.shared_lock().read(); + self.media_queries.read_with(&guard).media_queries + .get(index as usize).and_then(|query| { let mut s = String::new(); query.to_css(&mut s).unwrap(); Some(DOMString::from_string(s)) @@ -94,13 +106,14 @@ impl MediaListMethods for MediaList { } // Step 3 let m_serialized = m.clone().unwrap().to_css_string(); - let any = self.media_queries.read().media_queries.iter() - .any(|q| m_serialized == q.to_css_string()); + let mut guard = self.shared_lock().write(); + let mq = self.media_queries.write_with(&mut guard); + let any = mq.media_queries.iter().any(|q| m_serialized == q.to_css_string()); if any { return; } // Step 4 - self.media_queries.write().media_queries.push(m.unwrap()); + mq.media_queries.push(m.unwrap()); } // https://drafts.csswg.org/cssom/#dom-medialist-deletemedium @@ -114,7 +127,8 @@ impl MediaListMethods for MediaList { } // Step 3 let m_serialized = m.unwrap().to_css_string(); - let mut media_list = self.media_queries.write(); + let mut guard = self.shared_lock().write(); + let mut media_list = self.media_queries.write_with(&mut guard); let new_vec = media_list.media_queries.drain(..) .filter(|q| m_serialized != q.to_css_string()) .collect(); diff --git a/components/style/gecko/arc_types.rs b/components/style/gecko/arc_types.rs index d822857a9e6..daf0454c81e 100644 --- a/components/style/gecko/arc_types.rs +++ b/components/style/gecko/arc_types.rs @@ -17,6 +17,7 @@ use media_queries::MediaList; use parking_lot::RwLock; use properties::{ComputedValues, PropertyDeclarationBlock}; use properties::animated_properties::{AnimationValue, AnimationValueMap}; +use shared_lock::Locked; use stylesheets::{CssRules, Stylesheet, StyleRule, ImportRule, MediaRule, NamespaceRule}; macro_rules! impl_arc_ffi { @@ -62,7 +63,7 @@ impl_arc_ffi!(AnimationValue => RawServoAnimationValue impl_arc_ffi!(RwLock<AnimationValueMap> => RawServoAnimationValueMap [Servo_AnimationValueMap_AddRef, Servo_AnimationValueMap_Release]); -impl_arc_ffi!(RwLock<MediaList> => RawServoMediaList +impl_arc_ffi!(Locked<MediaList> => RawServoMediaList [Servo_MediaList_AddRef, Servo_MediaList_Release]); impl_arc_ffi!(RwLock<MediaRule> => RawServoMediaRule diff --git a/components/style/stylesheets.rs b/components/style/stylesheets.rs index df6a9641f0d..3f3d78c1e16 100644 --- a/components/style/stylesheets.rs +++ b/components/style/stylesheets.rs @@ -316,7 +316,7 @@ impl CssRule { } CssRule::Media(ref lock) => { let media_rule = lock.read(); - let mq = media_rule.media_queries.read(); + let mq = media_rule.media_queries.read_with(guard); let rules = &media_rule.rules.read().0; f(rules, Some(&mq)) } @@ -477,7 +477,7 @@ impl ToCssWithGuard for KeyframesRule { #[allow(missing_docs)] #[derive(Debug)] pub struct MediaRule { - pub media_queries: Arc<RwLock<MediaList>>, + pub media_queries: Arc<Locked<MediaList>>, pub rules: Arc<RwLock<CssRules>>, } @@ -487,7 +487,7 @@ impl ToCssWithGuard for MediaRule { fn to_css<W>(&self, guard: &SharedRwLockReadGuard, dest: &mut W) -> fmt::Result where W: fmt::Write { try!(dest.write_str("@media ")); - try!(self.media_queries.read().to_css(dest)); + try!(self.media_queries.read_with(guard).to_css(dest)); try!(dest.write_str(" {")); for rule in self.rules.read().0.iter() { try!(dest.write_str(" ")); @@ -753,6 +753,7 @@ impl<'b> TopLevelRuleParser<'b> { fn nested<'a: 'b>(&'a self) -> NestedRuleParser<'a, 'b> { NestedRuleParser { stylesheet_origin: self.stylesheet_origin, + shared_lock: self.shared_lock, context: &self.context, namespaces: self.namespaces, } @@ -774,7 +775,7 @@ enum AtRulePrelude { /// A @font-face rule prelude. FontFace, /// A @media rule prelude, with its media queries. - Media(Arc<RwLock<MediaList>>), + Media(Arc<Locked<MediaList>>), /// An @supports rule, with its conditional Supports(SupportsCondition), /// A @viewport rule prelude. @@ -900,6 +901,7 @@ impl<'a> QualifiedRuleParser for TopLevelRuleParser<'a> { #[derive(Clone)] // shallow, relatively cheap .clone struct NestedRuleParser<'a, 'b: 'a> { stylesheet_origin: Origin, + shared_lock: &'a SharedRwLock, context: &'a ParserContext<'b>, namespaces: &'b Namespaces, } @@ -931,7 +933,8 @@ impl<'a, 'b> AtRuleParser for NestedRuleParser<'a, 'b> { match_ignore_ascii_case! { name, "media" => { let media_queries = parse_media_query_list(input); - Ok(AtRuleType::WithBlock(AtRulePrelude::Media(Arc::new(RwLock::new(media_queries))))) + let arc = Arc::new(self.shared_lock.wrap(media_queries)); + Ok(AtRuleType::WithBlock(AtRulePrelude::Media(arc))) }, "supports" => { let cond = SupportsCondition::parse(input)?; diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index cdc0a530f09..e0335ee0005 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -76,7 +76,7 @@ use style::properties::parse_one_declaration; use style::restyle_hints::{self, RestyleHint}; use style::selector_parser::PseudoElementCascadeType; use style::sequential; -use style::shared_lock::{SharedRwLock, ToCssWithGuard}; +use style::shared_lock::{SharedRwLock, ToCssWithGuard, Locked}; use style::string_cache::Atom; use style::stylesheets::{CssRule, CssRules, ImportRule, MediaRule, NamespaceRule}; use style::stylesheets::{Origin, Stylesheet, StyleRule}; @@ -964,29 +964,37 @@ pub extern "C" fn Servo_DeclarationBlock_RemovePropertyById(declarations: RawSer #[no_mangle] pub extern "C" fn Servo_MediaList_GetText(list: RawServoMediaListBorrowed, result: *mut nsAString) { - let list = RwLock::<MediaList>::as_arc(&list); - list.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 list = Locked::<MediaList>::as_arc(&list); + list.read_with(&guard).to_css(unsafe { result.as_mut().unwrap() }).unwrap(); } #[no_mangle] pub extern "C" fn Servo_MediaList_SetText(list: RawServoMediaListBorrowed, text: *const nsACString) { - let list = RwLock::<MediaList>::as_arc(&list); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + let list = Locked::<MediaList>::as_arc(&list); let text = unsafe { text.as_ref().unwrap().as_str_unchecked() }; let mut parser = Parser::new(&text); - *list.write() = parse_media_query_list(&mut parser); + *list.write_with(&mut guard) = parse_media_query_list(&mut parser); } #[no_mangle] pub extern "C" fn Servo_MediaList_GetLength(list: RawServoMediaListBorrowed) -> u32 { - let list = RwLock::<MediaList>::as_arc(&list); - list.read().media_queries.len() as u32 + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let list = Locked::<MediaList>::as_arc(&list); + list.read_with(&guard).media_queries.len() as u32 } #[no_mangle] pub extern "C" fn Servo_MediaList_GetMediumAt(list: RawServoMediaListBorrowed, index: u32, result: *mut nsAString) -> bool { - let list = RwLock::<MediaList>::as_arc(&list); - if let Some(media_query) = list.read().media_queries.get(index as usize) { + let global_style_data = &*GLOBAL_STYLE_DATA; + let guard = global_style_data.shared_lock.read(); + let list = Locked::<MediaList>::as_arc(&list); + if let Some(media_query) = list.read_with(&guard).media_queries.get(index as usize) { media_query.to_css(unsafe { result.as_mut().unwrap() }).unwrap(); true } else { @@ -997,17 +1005,21 @@ pub extern "C" fn Servo_MediaList_GetMediumAt(list: RawServoMediaListBorrowed, i #[no_mangle] pub extern "C" fn Servo_MediaList_AppendMedium(list: RawServoMediaListBorrowed, new_medium: *const nsACString) { - let list = RwLock::<MediaList>::as_arc(&list); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + let list = Locked::<MediaList>::as_arc(&list); let new_medium = unsafe { new_medium.as_ref().unwrap().as_str_unchecked() }; - list.write().append_medium(new_medium); + list.write_with(&mut guard).append_medium(new_medium); } #[no_mangle] pub extern "C" fn Servo_MediaList_DeleteMedium(list: RawServoMediaListBorrowed, old_medium: *const nsACString) -> bool { - let list = RwLock::<MediaList>::as_arc(&list); + let global_style_data = &*GLOBAL_STYLE_DATA; + let mut guard = global_style_data.shared_lock.write(); + let list = Locked::<MediaList>::as_arc(&list); let old_medium = unsafe { old_medium.as_ref().unwrap().as_str_unchecked() }; - list.write().delete_medium(old_medium) + list.write_with(&mut guard).delete_medium(old_medium) } macro_rules! get_longhand_from_id { |