mirror of
https://github.com/servo/servo.git
synced 2025-07-24 07:40:27 +01:00
Parse stylesheets without acquiring a shared lock.
This commit is contained in:
parent
cc046300f0
commit
d9491187dc
4 changed files with 42 additions and 42 deletions
|
@ -159,13 +159,10 @@ impl FetchResponseListener for StylesheetContext {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StylesheetContextSource::Import(ref stylesheet) => {
|
StylesheetContextSource::Import(ref stylesheet) => {
|
||||||
let mut guard = document.style_shared_lock().write();
|
|
||||||
|
|
||||||
Stylesheet::update_from_bytes(&stylesheet,
|
Stylesheet::update_from_bytes(&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());
|
||||||
|
|
|
@ -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, SharedRwLockWriteGuard};
|
use shared_lock::SharedRwLock;
|
||||||
use std::str;
|
use std::str;
|
||||||
use stylesheets::{Stylesheet, StylesheetLoader, Origin};
|
use stylesheets::{Stylesheet, StylesheetLoader, Origin};
|
||||||
|
|
||||||
|
@ -78,7 +78,6 @@ 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) {
|
||||||
|
@ -86,7 +85,6 @@ 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)
|
||||||
|
|
|
@ -21,8 +21,7 @@ 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, ToCssWithGuard};
|
use shared_lock::{SharedRwLock, Locked, ToCssWithGuard, SharedRwLockReadGuard};
|
||||||
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;
|
||||||
|
@ -556,23 +555,42 @@ 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_with(guard);
|
let mut namespaces = Namespaces::default();
|
||||||
let mut namespaces = existing.namespaces.write();
|
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
|
||||||
|
css, &existing.base_url, existing.origin, &mut namespaces, &existing.shared_lock,
|
||||||
|
stylesheet_loader, error_reporter, extra_data,
|
||||||
|
);
|
||||||
|
|
||||||
assert!(rules.is_empty());
|
*existing.namespaces.write() = namespaces;
|
||||||
|
existing.dirty_on_viewport_size_change
|
||||||
|
.store(dirty_on_viewport_size_change, Ordering::Release);
|
||||||
|
|
||||||
|
// Acquire the lock *after* parsing, to minimize the exclusive section.
|
||||||
|
let mut guard = existing.shared_lock.write();
|
||||||
|
*existing.rules.write_with(&mut guard) = CssRules(rules);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_rules(css: &str,
|
||||||
|
base_url: &ServoUrl,
|
||||||
|
origin: Origin,
|
||||||
|
namespaces: &mut Namespaces,
|
||||||
|
shared_lock: &SharedRwLock,
|
||||||
|
stylesheet_loader: Option<&StylesheetLoader>,
|
||||||
|
error_reporter: &ParseErrorReporter,
|
||||||
|
extra_data: ParserContextExtraData)
|
||||||
|
-> (Vec<CssRule>, bool) {
|
||||||
|
let mut rules = Vec::new();
|
||||||
let mut input = Parser::new(css);
|
let mut input = Parser::new(css);
|
||||||
let rule_parser = TopLevelRuleParser {
|
let rule_parser = TopLevelRuleParser {
|
||||||
stylesheet_origin: existing.origin,
|
stylesheet_origin: origin,
|
||||||
namespaces: &mut namespaces,
|
namespaces: namespaces,
|
||||||
shared_lock: &existing.shared_lock,
|
shared_lock: shared_lock,
|
||||||
loader: stylesheet_loader,
|
loader: stylesheet_loader,
|
||||||
context: ParserContext::new_with_extra_data(existing.origin,
|
context: ParserContext::new_with_extra_data(origin,
|
||||||
&existing.base_url,
|
base_url,
|
||||||
error_reporter,
|
error_reporter,
|
||||||
extra_data),
|
extra_data),
|
||||||
state: Cell::new(State::Start),
|
state: Cell::new(State::Start),
|
||||||
|
@ -584,7 +602,7 @@ impl Stylesheet {
|
||||||
let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
|
let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
|
||||||
while let Some(result) = iter.next() {
|
while let Some(result) = iter.next() {
|
||||||
match result {
|
match result {
|
||||||
Ok(rule) => rules.0.push(rule),
|
Ok(rule) => rules.push(rule),
|
||||||
Err(range) => {
|
Err(range) => {
|
||||||
let pos = range.start;
|
let pos = range.start;
|
||||||
let message = format!("Invalid rule: '{}'", iter.input.slice(range));
|
let message = format!("Invalid rule: '{}'", iter.input.slice(range));
|
||||||
|
@ -594,8 +612,7 @@ impl Stylesheet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
existing.dirty_on_viewport_size_change
|
(rules, input.seen_viewport_percentages())
|
||||||
.store(input.seen_viewport_percentages(), Ordering::Release);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates an empty stylesheet and parses it with a given base url, origin
|
/// Creates an empty stylesheet and parses it with a given base url, origin
|
||||||
|
@ -611,28 +628,21 @@ impl Stylesheet {
|
||||||
stylesheet_loader: Option<&StylesheetLoader>,
|
stylesheet_loader: Option<&StylesheetLoader>,
|
||||||
error_reporter: &ParseErrorReporter,
|
error_reporter: &ParseErrorReporter,
|
||||||
extra_data: ParserContextExtraData) -> Stylesheet {
|
extra_data: ParserContextExtraData) -> Stylesheet {
|
||||||
let s = Stylesheet {
|
let mut namespaces = Namespaces::default();
|
||||||
|
let (rules, dirty_on_viewport_size_change) = Stylesheet::parse_rules(
|
||||||
|
css, &base_url, origin, &mut namespaces, &shared_lock,
|
||||||
|
stylesheet_loader, error_reporter, extra_data,
|
||||||
|
);
|
||||||
|
Stylesheet {
|
||||||
origin: origin,
|
origin: origin,
|
||||||
base_url: base_url,
|
base_url: base_url,
|
||||||
namespaces: RwLock::new(Namespaces::default()),
|
namespaces: RwLock::new(namespaces),
|
||||||
rules: CssRules::new(Vec::new(), &shared_lock),
|
rules: CssRules::new(rules, &shared_lock),
|
||||||
media: Arc::new(shared_lock.wrap(media)),
|
media: Arc::new(shared_lock.wrap(media)),
|
||||||
shared_lock: shared_lock,
|
shared_lock: shared_lock,
|
||||||
dirty_on_viewport_size_change: AtomicBool::new(false),
|
dirty_on_viewport_size_change: AtomicBool::new(dirty_on_viewport_size_change),
|
||||||
disabled: AtomicBool::new(false),
|
disabled: AtomicBool::new(false),
|
||||||
};
|
|
||||||
|
|
||||||
{
|
|
||||||
let mut guard = s.shared_lock.write();
|
|
||||||
Self::update_from_str(&s,
|
|
||||||
css,
|
|
||||||
&mut guard,
|
|
||||||
stylesheet_loader,
|
|
||||||
error_reporter,
|
|
||||||
extra_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether this stylesheet can be dirty on viewport size change.
|
/// Whether this stylesheet can be dirty on viewport size change.
|
||||||
|
|
|
@ -362,8 +362,6 @@ 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)),
|
||||||
|
@ -384,10 +382,7 @@ pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheet
|
||||||
};
|
};
|
||||||
|
|
||||||
let sheet = Stylesheet::as_arc(&stylesheet);
|
let sheet = Stylesheet::as_arc(&stylesheet);
|
||||||
sheet.rules.write_with(&mut guard).0.clear();
|
Stylesheet::update_from_str(&sheet, input, loader, &StdoutErrorReporter, extra_data);
|
||||||
|
|
||||||
Stylesheet::update_from_str(&sheet, input, &mut guard, loader,
|
|
||||||
&StdoutErrorReporter, extra_data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue