Replace RwLock<CssRules> with Locked<CssRules>

This commit is contained in:
Simon Sapin 2017-03-17 11:01:13 +01:00
parent b213daaa88
commit f35b4e27b3
15 changed files with 85 additions and 52 deletions

View file

@ -508,7 +508,7 @@ unsafe impl JSTraceable for RwLock<FontFaceRule> {
} }
} }
unsafe impl JSTraceable for RwLock<CssRules> { unsafe impl JSTraceable for StyleLocked<CssRules> {
unsafe fn trace(&self, _trc: *mut JSTracer) { unsafe fn trace(&self, _trc: *mut JSTracer) {
// Do nothing. // Do nothing.
} }

View file

@ -10,9 +10,8 @@ use dom::cssmediarule::CSSMediaRule;
use dom::cssstylesheet::CSSStyleSheet; use dom::cssstylesheet::CSSStyleSheet;
use dom::csssupportsrule::CSSSupportsRule; use dom::csssupportsrule::CSSSupportsRule;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use parking_lot::RwLock;
use std::sync::Arc; use std::sync::Arc;
use style::shared_lock::SharedRwLock; use style::shared_lock::{SharedRwLock, Locked};
use style::stylesheets::CssRules as StyleCssRules; use style::stylesheets::CssRules as StyleCssRules;
#[dom_struct] #[dom_struct]
@ -22,7 +21,7 @@ pub struct CSSConditionRule {
impl CSSConditionRule { impl CSSConditionRule {
pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, pub fn new_inherited(parent_stylesheet: &CSSStyleSheet,
rules: Arc<RwLock<StyleCssRules>>) -> CSSConditionRule { rules: Arc<Locked<StyleCssRules>>) -> CSSConditionRule {
CSSConditionRule { CSSConditionRule {
cssgroupingrule: CSSGroupingRule::new_inherited(parent_stylesheet, rules), cssgroupingrule: CSSGroupingRule::new_inherited(parent_stylesheet, rules),
} }

View file

@ -12,22 +12,21 @@ use dom::cssrule::CSSRule;
use dom::cssrulelist::{CSSRuleList, RulesSource}; use dom::cssrulelist::{CSSRuleList, RulesSource};
use dom::cssstylesheet::CSSStyleSheet; use dom::cssstylesheet::CSSStyleSheet;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use parking_lot::RwLock;
use std::sync::Arc; use std::sync::Arc;
use style::shared_lock::SharedRwLock; use style::shared_lock::{SharedRwLock, Locked};
use style::stylesheets::CssRules as StyleCssRules; use style::stylesheets::CssRules as StyleCssRules;
#[dom_struct] #[dom_struct]
pub struct CSSGroupingRule { pub struct CSSGroupingRule {
cssrule: CSSRule, cssrule: CSSRule,
#[ignore_heap_size_of = "Arc"] #[ignore_heap_size_of = "Arc"]
rules: Arc<RwLock<StyleCssRules>>, rules: Arc<Locked<StyleCssRules>>,
rulelist: MutNullableJS<CSSRuleList>, rulelist: MutNullableJS<CSSRuleList>,
} }
impl CSSGroupingRule { impl CSSGroupingRule {
pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, pub fn new_inherited(parent_stylesheet: &CSSStyleSheet,
rules: Arc<RwLock<StyleCssRules>>) -> CSSGroupingRule { rules: Arc<Locked<StyleCssRules>>) -> CSSGroupingRule {
CSSGroupingRule { CSSGroupingRule {
cssrule: CSSRule::new_inherited(parent_stylesheet), cssrule: CSSRule::new_inherited(parent_stylesheet),
rules: rules, rules: rules,

View file

@ -15,6 +15,7 @@ use dom::window::Window;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use parking_lot::RwLock; use parking_lot::RwLock;
use std::sync::Arc; use std::sync::Arc;
use style::shared_lock::Locked;
use style::stylesheets::{CssRules, KeyframesRule, RulesMutateError}; use style::stylesheets::{CssRules, KeyframesRule, RulesMutateError};
#[allow(unsafe_code)] #[allow(unsafe_code)]
@ -43,7 +44,7 @@ pub struct CSSRuleList {
} }
pub enum RulesSource { pub enum RulesSource {
Rules(Arc<RwLock<CssRules>>), Rules(Arc<Locked<CssRules>>),
Keyframes(Arc<RwLock<KeyframesRule>>), Keyframes(Arc<RwLock<KeyframesRule>>),
} }
@ -52,7 +53,8 @@ impl CSSRuleList {
pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, rules: RulesSource) -> CSSRuleList { pub fn new_inherited(parent_stylesheet: &CSSStyleSheet, rules: RulesSource) -> CSSRuleList {
let dom_rules = match rules { let dom_rules = match rules {
RulesSource::Rules(ref rules) => { RulesSource::Rules(ref rules) => {
rules.read().0.iter().map(|_| MutNullableJS::new(None)).collect() let guard = parent_stylesheet.shared_lock().read();
rules.read_with(&guard).0.iter().map(|_| MutNullableJS::new(None)).collect()
} }
RulesSource::Keyframes(ref rules) => { RulesSource::Keyframes(ref rules) => {
rules.read().keyframes.iter().map(|_| MutNullableJS::new(None)).collect() rules.read().keyframes.iter().map(|_| MutNullableJS::new(None)).collect()
@ -89,7 +91,9 @@ impl CSSRuleList {
let index = idx as usize; let index = idx as usize;
let parent_stylesheet = self.parent_stylesheet.style_stylesheet(); let parent_stylesheet = self.parent_stylesheet.style_stylesheet();
let new_rule = css_rules.write().insert_rule(rule, parent_stylesheet, index, nested)?; let mut guard = parent_stylesheet.shared_lock.write();
let new_rule = css_rules.write_with(&mut guard)
.insert_rule(rule, parent_stylesheet, index, nested)?;
let parent_stylesheet = &*self.parent_stylesheet; let parent_stylesheet = &*self.parent_stylesheet;
let dom_rule = CSSRule::new_specific(&window, parent_stylesheet, new_rule); let dom_rule = CSSRule::new_specific(&window, parent_stylesheet, new_rule);
@ -103,7 +107,8 @@ impl CSSRuleList {
match self.rules { match self.rules {
RulesSource::Rules(ref css_rules) => { RulesSource::Rules(ref css_rules) => {
css_rules.write().remove_rule(index)?; let mut guard = self.parent_stylesheet.shared_lock().write();
css_rules.write_with(&mut guard).remove_rule(index)?;
let mut dom_rules = self.dom_rules.borrow_mut(); let mut dom_rules = self.dom_rules.borrow_mut();
dom_rules[index].get().map(|r| r.detach()); dom_rules[index].get().map(|r| r.detach());
dom_rules.remove(index); dom_rules.remove(index);
@ -133,9 +138,10 @@ impl CSSRuleList {
let parent_stylesheet = &self.parent_stylesheet; let parent_stylesheet = &self.parent_stylesheet;
match self.rules { match self.rules {
RulesSource::Rules(ref rules) => { RulesSource::Rules(ref rules) => {
let guard = parent_stylesheet.shared_lock().read();
CSSRule::new_specific(self.global().as_window(), CSSRule::new_specific(self.global().as_window(),
parent_stylesheet, parent_stylesheet,
rules.read().0[idx as usize].clone()) rules.read_with(&guard).0[idx as usize].clone())
} }
RulesSource::Keyframes(ref rules) => { RulesSource::Keyframes(ref rules) => {
Root::upcast(CSSKeyframeRule::new(self.global().as_window(), Root::upcast(CSSKeyframeRule::new(self.global().as_window(),

View file

@ -16,6 +16,7 @@ use dom::window::Window;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use std::cell::Cell; use std::cell::Cell;
use std::sync::Arc; use std::sync::Arc;
use style::shared_lock::SharedRwLock;
use style::stylesheets::Stylesheet as StyleStyleSheet; use style::stylesheets::Stylesheet as StyleStyleSheet;
#[dom_struct] #[dom_struct]
@ -72,6 +73,10 @@ impl CSSStyleSheet {
} }
} }
pub fn shared_lock(&self) -> &SharedRwLock {
&self.style_stylesheet.shared_lock
}
pub fn style_stylesheet(&self) -> &StyleStyleSheet { pub fn style_stylesheet(&self) -> &StyleStyleSheet {
&self.style_stylesheet &self.style_stylesheet
} }

View file

@ -101,8 +101,9 @@ impl HTMLMetaElement {
if let Some(translated_rule) = ViewportRule::from_meta(&**content) { if let Some(translated_rule) = ViewportRule::from_meta(&**content) {
let document = self.upcast::<Node>().owner_doc(); let document = self.upcast::<Node>().owner_doc();
let shared_lock = document.style_shared_lock(); let shared_lock = document.style_shared_lock();
let rule = CssRule::Viewport(Arc::new(RwLock::new(translated_rule)));
*self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet { *self.stylesheet.borrow_mut() = Some(Arc::new(Stylesheet {
rules: CssRules::new(vec![CssRule::Viewport(Arc::new(RwLock::new(translated_rule)))]), rules: CssRules::new(vec![rule], shared_lock),
origin: Origin::Author, origin: Origin::Author,
shared_lock: shared_lock.clone(), shared_lock: shared_lock.clone(),
base_url: window_from_node(self).get_url(), base_url: window_from_node(self).get_url(),

View file

@ -175,10 +175,12 @@ impl FetchResponseListener for StylesheetContext {
} }
StylesheetContextSource::Import(ref import) => { StylesheetContextSource::Import(ref import) => {
let import = import.read(); let import = import.read();
let mut guard = document.style_shared_lock().write();
Stylesheet::update_from_bytes(&import.stylesheet, Stylesheet::update_from_bytes(&import.stylesheet,
&data, &data,
protocol_encoding_label, protocol_encoding_label,
Some(environment_encoding), Some(environment_encoding),
&mut guard,
Some(&loader), Some(&loader),
win.css_error_reporter(), win.css_error_reporter(),
ParserContextExtraData::default()); ParserContextExtraData::default());

View file

@ -12,7 +12,7 @@ use media_queries::MediaList;
use parser::ParserContextExtraData; use parser::ParserContextExtraData;
use self::encoding::{EncodingRef, DecoderTrap}; use self::encoding::{EncodingRef, DecoderTrap};
use servo_url::ServoUrl; use servo_url::ServoUrl;
use shared_lock::SharedRwLock; use shared_lock::{SharedRwLock, SharedRwLockWriteGuard};
use std::str; use std::str;
use stylesheets::{Stylesheet, StylesheetLoader, Origin}; use stylesheets::{Stylesheet, StylesheetLoader, Origin};
@ -78,6 +78,7 @@ impl Stylesheet {
bytes: &[u8], bytes: &[u8],
protocol_encoding_label: Option<&str>, protocol_encoding_label: Option<&str>,
environment_encoding: Option<EncodingRef>, environment_encoding: Option<EncodingRef>,
guard: &mut SharedRwLockWriteGuard,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter, error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData) { extra_data: ParserContextExtraData) {
@ -85,6 +86,7 @@ impl Stylesheet {
bytes, protocol_encoding_label, environment_encoding); bytes, protocol_encoding_label, environment_encoding);
Self::update_from_str(existing, Self::update_from_str(existing,
&string, &string,
guard,
stylesheet_loader, stylesheet_loader,
error_reporter, error_reporter,
extra_data) extra_data)

View file

@ -39,7 +39,7 @@ macro_rules! impl_arc_ffi {
} }
} }
impl_arc_ffi!(RwLock<CssRules> => ServoCssRules impl_arc_ffi!(Locked<CssRules> => ServoCssRules
[Servo_CssRules_AddRef, Servo_CssRules_Release]); [Servo_CssRules_AddRef, Servo_CssRules_Release]);
impl_arc_ffi!(Stylesheet => RawServoStyleSheet impl_arc_ffi!(Stylesheet => RawServoStyleSheet

View file

@ -21,7 +21,8 @@ use selector_parser::{SelectorImpl, SelectorParser};
use selectors::parser::SelectorList; use selectors::parser::SelectorList;
use servo_config::prefs::PREFS; use servo_config::prefs::PREFS;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use shared_lock::{SharedRwLock, Locked, SharedRwLockReadGuard, ToCssWithGuard}; use shared_lock::{SharedRwLock, Locked, ToCssWithGuard};
use shared_lock::{SharedRwLockReadGuard, SharedRwLockWriteGuard};
use std::cell::Cell; use std::cell::Cell;
use std::fmt; use std::fmt;
use std::sync::Arc; use std::sync::Arc;
@ -87,8 +88,8 @@ impl From<SingleRuleParseError> for RulesMutateError {
impl CssRules { impl CssRules {
#[allow(missing_docs)] #[allow(missing_docs)]
pub fn new(rules: Vec<CssRule>) -> Arc<RwLock<CssRules>> { pub fn new(rules: Vec<CssRule>, shared_lock: &SharedRwLock) -> Arc<Locked<CssRules>> {
Arc::new(RwLock::new(CssRules(rules))) Arc::new(shared_lock.wrap(CssRules(rules)))
} }
fn only_ns_or_import(&self) -> bool { fn only_ns_or_import(&self) -> bool {
@ -174,7 +175,7 @@ impl CssRules {
pub struct Stylesheet { pub struct Stylesheet {
/// List of rules in the order they were found (important for /// List of rules in the order they were found (important for
/// cascading order) /// cascading order)
pub rules: Arc<RwLock<CssRules>>, pub rules: Arc<Locked<CssRules>>,
/// List of media associated with the Stylesheet. /// List of media associated with the Stylesheet.
pub media: Arc<Locked<MediaList>>, pub media: Arc<Locked<MediaList>>,
/// The origin of this stylesheet. /// The origin of this stylesheet.
@ -302,7 +303,7 @@ impl CssRule {
CssRule::Import(ref lock) => { CssRule::Import(ref lock) => {
let rule = lock.read(); let rule = lock.read();
let media = rule.stylesheet.media.read_with(guard); let media = rule.stylesheet.media.read_with(guard);
let rules = rule.stylesheet.rules.read(); let rules = rule.stylesheet.rules.read_with(guard);
// FIXME(emilio): Include the nested rules if the stylesheet is // FIXME(emilio): Include the nested rules if the stylesheet is
// loaded. // loaded.
f(&rules.0, Some(&media)) f(&rules.0, Some(&media))
@ -317,14 +318,14 @@ impl CssRule {
CssRule::Media(ref lock) => { CssRule::Media(ref lock) => {
let media_rule = lock.read(); let media_rule = lock.read();
let mq = media_rule.media_queries.read_with(guard); let mq = media_rule.media_queries.read_with(guard);
let rules = &media_rule.rules.read().0; let rules = &media_rule.rules.read_with(guard).0;
f(rules, Some(&mq)) f(rules, Some(&mq))
} }
CssRule::Supports(ref lock) => { CssRule::Supports(ref lock) => {
let supports_rule = lock.read(); let supports_rule = lock.read();
let enabled = supports_rule.enabled; let enabled = supports_rule.enabled;
if enabled { if enabled {
let rules = &supports_rule.rules.read().0; let rules = &supports_rule.rules.read_with(guard).0;
f(rules, None) f(rules, None)
} else { } else {
f(&[], None) f(&[], None)
@ -478,7 +479,7 @@ impl ToCssWithGuard for KeyframesRule {
#[derive(Debug)] #[derive(Debug)]
pub struct MediaRule { pub struct MediaRule {
pub media_queries: Arc<Locked<MediaList>>, pub media_queries: Arc<Locked<MediaList>>,
pub rules: Arc<RwLock<CssRules>>, pub rules: Arc<Locked<CssRules>>,
} }
impl ToCssWithGuard for MediaRule { impl ToCssWithGuard for MediaRule {
@ -489,7 +490,7 @@ impl ToCssWithGuard for MediaRule {
try!(dest.write_str("@media ")); try!(dest.write_str("@media "));
try!(self.media_queries.read_with(guard).to_css(dest)); try!(self.media_queries.read_with(guard).to_css(dest));
try!(dest.write_str(" {")); try!(dest.write_str(" {"));
for rule in self.rules.read().0.iter() { for rule in self.rules.read_with(guard).0.iter() {
try!(dest.write_str(" ")); try!(dest.write_str(" "));
try!(rule.to_css(guard, dest)); try!(rule.to_css(guard, dest));
} }
@ -504,7 +505,7 @@ pub struct SupportsRule {
/// The parsed condition /// The parsed condition
pub condition: SupportsCondition, pub condition: SupportsCondition,
/// Child rules /// Child rules
pub rules: Arc<RwLock<CssRules>>, pub rules: Arc<Locked<CssRules>>,
/// The result of evaluating the condition /// The result of evaluating the condition
pub enabled: bool, pub enabled: bool,
} }
@ -515,7 +516,7 @@ impl ToCssWithGuard for SupportsRule {
try!(dest.write_str("@supports ")); try!(dest.write_str("@supports "));
try!(self.condition.to_css(dest)); try!(self.condition.to_css(dest));
try!(dest.write_str(" {")); try!(dest.write_str(" {"));
for rule in self.rules.read().0.iter() { for rule in self.rules.read_with(guard).0.iter() {
try!(dest.write_str(" ")); try!(dest.write_str(" "));
try!(rule.to_css(guard, dest)); try!(rule.to_css(guard, dest));
} }
@ -555,10 +556,11 @@ impl Stylesheet {
/// Updates an empty stylesheet from a given string of text. /// Updates an empty stylesheet from a given string of text.
pub fn update_from_str(existing: &Stylesheet, pub fn update_from_str(existing: &Stylesheet,
css: &str, css: &str,
guard: &mut SharedRwLockWriteGuard,
stylesheet_loader: Option<&StylesheetLoader>, stylesheet_loader: Option<&StylesheetLoader>,
error_reporter: &ParseErrorReporter, error_reporter: &ParseErrorReporter,
extra_data: ParserContextExtraData) { extra_data: ParserContextExtraData) {
let mut rules = existing.rules.write(); let mut rules = existing.rules.write_with(guard);
let mut namespaces = existing.namespaces.write(); let mut namespaces = existing.namespaces.write();
assert!(rules.is_empty()); assert!(rules.is_empty());
@ -613,18 +615,22 @@ impl Stylesheet {
origin: origin, origin: origin,
base_url: base_url, base_url: base_url,
namespaces: RwLock::new(Namespaces::default()), namespaces: RwLock::new(Namespaces::default()),
rules: CssRules::new(vec![]), rules: CssRules::new(Vec::new(), &shared_lock),
media: Arc::new(shared_lock.wrap(media)), media: Arc::new(shared_lock.wrap(media)),
shared_lock: shared_lock.clone(), shared_lock: shared_lock,
dirty_on_viewport_size_change: AtomicBool::new(false), dirty_on_viewport_size_change: AtomicBool::new(false),
disabled: AtomicBool::new(false), disabled: AtomicBool::new(false),
}; };
{
let mut guard = s.shared_lock.write();
Self::update_from_str(&s, Self::update_from_str(&s,
css, css,
&mut guard,
stylesheet_loader, stylesheet_loader,
error_reporter, error_reporter,
extra_data); extra_data);
}
s s
} }
@ -666,7 +672,7 @@ impl Stylesheet {
#[inline] #[inline]
pub fn effective_rules<F>(&self, device: &Device, guard: &SharedRwLockReadGuard, mut f: F) pub fn effective_rules<F>(&self, device: &Device, guard: &SharedRwLockReadGuard, mut f: F)
where F: FnMut(&CssRule) { where F: FnMut(&CssRule) {
effective_rules(&self.rules.read().0, device, guard, &mut f); effective_rules(&self.rules.read_with(guard).0, device, guard, &mut f);
} }
/// Returns whether the stylesheet has been explicitly disabled through the /// Returns whether the stylesheet has been explicitly disabled through the
@ -809,7 +815,7 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
ImportRule { ImportRule {
url: url, url: url,
stylesheet: Arc::new(Stylesheet { stylesheet: Arc::new(Stylesheet {
rules: Arc::new(RwLock::new(CssRules(vec![]))), rules: CssRules::new(Vec::new(), self.shared_lock),
media: media, media: media,
shared_lock: self.shared_lock.clone(), shared_lock: self.shared_lock.clone(),
origin: self.context.stylesheet_origin, origin: self.context.stylesheet_origin,
@ -907,7 +913,7 @@ struct NestedRuleParser<'a, 'b: 'a> {
} }
impl<'a, 'b> NestedRuleParser<'a, 'b> { impl<'a, 'b> NestedRuleParser<'a, 'b> {
fn parse_nested_rules(&self, input: &mut Parser) -> Arc<RwLock<CssRules>> { fn parse_nested_rules(&self, input: &mut Parser) -> Arc<Locked<CssRules>> {
let mut iter = RuleListParser::new_for_nested_rule(input, self.clone()); let mut iter = RuleListParser::new_for_nested_rule(input, self.clone());
let mut rules = Vec::new(); let mut rules = Vec::new();
while let Some(result) = iter.next() { while let Some(result) = iter.next() {
@ -920,7 +926,7 @@ impl<'a, 'b> NestedRuleParser<'a, 'b> {
} }
} }
} }
CssRules::new(rules) CssRules::new(rules, self.shared_lock)
} }
} }

View file

@ -502,7 +502,7 @@ impl Stylist {
return true return true
} }
mq_eval_changed(guard, &stylesheet.rules.read().0, &self.device, &device) mq_eval_changed(guard, &stylesheet.rules.read_with(guard).0, &self.device, &device)
}); });
self.device = Arc::new(device); self.device = Arc::new(device);

View file

@ -402,6 +402,8 @@ pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheet
referrer: *mut ThreadSafeURIHolder, referrer: *mut ThreadSafeURIHolder,
principal: *mut ThreadSafePrincipalHolder) principal: *mut ThreadSafePrincipalHolder)
{ {
let global_style_data = &*GLOBAL_STYLE_DATA;
let mut guard = global_style_data.shared_lock.write();
let input = unsafe { data.as_ref().unwrap().as_str_unchecked() }; let input = unsafe { data.as_ref().unwrap().as_str_unchecked() };
let extra_data = unsafe { ParserContextExtraData { let extra_data = unsafe { ParserContextExtraData {
base: Some(GeckoArcURI::new(base)), base: Some(GeckoArcURI::new(base)),
@ -422,9 +424,9 @@ pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheet
}; };
let sheet = Stylesheet::as_arc(&stylesheet); let sheet = Stylesheet::as_arc(&stylesheet);
sheet.rules.write().0.clear(); sheet.rules.write_with(&mut guard).0.clear();
Stylesheet::update_from_str(&sheet, input, loader, Stylesheet::update_from_str(&sheet, input, &mut guard, loader,
&StdoutErrorReporter, extra_data); &StdoutErrorReporter, extra_data);
} }
@ -510,7 +512,9 @@ pub extern "C" fn Servo_StyleSet_NoteStyleSheetsChanged(raw_data: RawServoStyleS
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool { pub extern "C" fn Servo_StyleSheet_HasRules(raw_sheet: RawServoStyleSheetBorrowed) -> bool {
!Stylesheet::as_arc(&raw_sheet).rules.read().0.is_empty() let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
!Stylesheet::as_arc(&raw_sheet).rules.read_with(&guard).0.is_empty()
} }
#[no_mangle] #[no_mangle]
@ -521,7 +525,9 @@ pub extern "C" fn Servo_StyleSheet_GetRules(sheet: RawServoStyleSheetBorrowed) -
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed, pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
result: nsTArrayBorrowed_uintptr_t) { result: nsTArrayBorrowed_uintptr_t) {
let rules = RwLock::<CssRules>::as_arc(&rules).read(); let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
let iter = rules.0.iter().map(|rule| rule.rule_type() as usize); let iter = rules.0.iter().map(|rule| rule.rule_type() as usize);
let (size, upper) = iter.size_hint(); let (size, upper) = iter.size_hint();
debug_assert_eq!(size, upper.unwrap()); debug_assert_eq!(size, upper.unwrap());
@ -533,10 +539,12 @@ pub extern "C" fn Servo_CssRules_ListTypes(rules: ServoCssRulesBorrowed,
pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed, sheet: RawServoStyleSheetBorrowed, pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed, sheet: RawServoStyleSheetBorrowed,
rule: *const nsACString, index: u32, nested: bool, rule: *const nsACString, index: u32, nested: bool,
rule_type: *mut u16) -> nsresult { rule_type: *mut u16) -> nsresult {
let rules = RwLock::<CssRules>::as_arc(&rules); let global_style_data = &*GLOBAL_STYLE_DATA;
let mut guard = global_style_data.shared_lock.write();
let rules = Locked::<CssRules>::as_arc(&rules);
let sheet = Stylesheet::as_arc(&sheet); let sheet = Stylesheet::as_arc(&sheet);
let rule = unsafe { rule.as_ref().unwrap().as_str_unchecked() }; let rule = unsafe { rule.as_ref().unwrap().as_str_unchecked() };
match rules.write().insert_rule(rule, sheet, index as usize, nested) { match rules.write_with(&mut guard).insert_rule(rule, sheet, index as usize, nested) {
Ok(new_rule) => { Ok(new_rule) => {
*unsafe { rule_type.as_mut().unwrap() } = new_rule.rule_type() as u16; *unsafe { rule_type.as_mut().unwrap() } = new_rule.rule_type() as u16;
nsresult::NS_OK nsresult::NS_OK
@ -547,8 +555,10 @@ pub extern "C" fn Servo_CssRules_InsertRule(rules: ServoCssRulesBorrowed, sheet:
#[no_mangle] #[no_mangle]
pub extern "C" fn Servo_CssRules_DeleteRule(rules: ServoCssRulesBorrowed, index: u32) -> nsresult { pub extern "C" fn Servo_CssRules_DeleteRule(rules: ServoCssRulesBorrowed, index: u32) -> nsresult {
let rules = RwLock::<CssRules>::as_arc(&rules); let global_style_data = &*GLOBAL_STYLE_DATA;
match rules.write().remove_rule(index as usize) { let mut guard = global_style_data.shared_lock.write();
let rules = Locked::<CssRules>::as_arc(&rules);
match rules.write_with(&mut guard).remove_rule(index as usize) {
Ok(_) => nsresult::NS_OK, Ok(_) => nsresult::NS_OK,
Err(err) => err.into() Err(err) => err.into()
} }
@ -562,7 +572,9 @@ macro_rules! impl_basic_rule_funcs {
} => { } => {
#[no_mangle] #[no_mangle]
pub extern "C" fn $getter(rules: ServoCssRulesBorrowed, index: u32) -> Strong<$raw_type> { pub extern "C" fn $getter(rules: ServoCssRulesBorrowed, index: u32) -> Strong<$raw_type> {
let rules = RwLock::<CssRules>::as_arc(&rules).read(); let global_style_data = &*GLOBAL_STYLE_DATA;
let guard = global_style_data.shared_lock.read();
let rules = Locked::<CssRules>::as_arc(&rules).read_with(&guard);
match rules.0[index as usize] { match rules.0[index as usize] {
CssRule::$name(ref rule) => rule.clone().into_strong(), CssRule::$name(ref rule) => rule.clone().into_strong(),
_ => { _ => {

View file

@ -35,7 +35,7 @@ fn test_media_rule<F>(css: &str, callback: F)
ParserContextExtraData::default()); ParserContextExtraData::default());
let mut rule_count = 0; let mut rule_count = 0;
let guard = stylesheet.shared_lock.read(); let guard = stylesheet.shared_lock.read();
media_queries(&guard, &stylesheet.rules.read().0, &mut |mq| { media_queries(&guard, &stylesheet.rules.read_with(&guard).0, &mut |mq| {
rule_count += 1; rule_count += 1;
callback(mq, css); callback(mq, css);
}); });

View file

@ -49,7 +49,8 @@ fn parse_rules(css: &str) -> Vec<(StyleSource, CascadeLevel)> {
None, None,
&ErrorringErrorReporter, &ErrorringErrorReporter,
ParserContextExtraData {}); ParserContextExtraData {});
let rules = s.rules.read(); let guard = s.shared_lock.read();
let rules = s.rules.read_with(&guard);
rules.0.iter().filter_map(|rule| { rules.0.iter().filter_map(|rule| {
match *rule { match *rule {
CssRule::Style(ref style_rule) => Some(style_rule), CssRule::Style(ref style_rule) => Some(style_rule),

View file

@ -263,7 +263,7 @@ fn test_parse_stylesheet() {
] ]
}))) })))
]), ], &stylesheet.shared_lock),
}; };
assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected)); assert_eq!(format!("{:#?}", stylesheet), format!("{:#?}", expected));