mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +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) => {
|
||||
let mut guard = document.style_shared_lock().write();
|
||||
|
||||
Stylesheet::update_from_bytes(&stylesheet,
|
||||
&data,
|
||||
protocol_encoding_label,
|
||||
Some(environment_encoding),
|
||||
&mut guard,
|
||||
Some(&loader),
|
||||
win.css_error_reporter(),
|
||||
ParserContextExtraData::default());
|
||||
|
|
|
@ -12,7 +12,7 @@ use media_queries::MediaList;
|
|||
use parser::ParserContextExtraData;
|
||||
use self::encoding::{EncodingRef, DecoderTrap};
|
||||
use servo_url::ServoUrl;
|
||||
use shared_lock::{SharedRwLock, SharedRwLockWriteGuard};
|
||||
use shared_lock::SharedRwLock;
|
||||
use std::str;
|
||||
use stylesheets::{Stylesheet, StylesheetLoader, Origin};
|
||||
|
||||
|
@ -78,7 +78,6 @@ impl Stylesheet {
|
|||
bytes: &[u8],
|
||||
protocol_encoding_label: Option<&str>,
|
||||
environment_encoding: Option<EncodingRef>,
|
||||
guard: &mut SharedRwLockWriteGuard,
|
||||
stylesheet_loader: Option<&StylesheetLoader>,
|
||||
error_reporter: &ParseErrorReporter,
|
||||
extra_data: ParserContextExtraData) {
|
||||
|
@ -86,7 +85,6 @@ impl Stylesheet {
|
|||
bytes, protocol_encoding_label, environment_encoding);
|
||||
Self::update_from_str(existing,
|
||||
&string,
|
||||
guard,
|
||||
stylesheet_loader,
|
||||
error_reporter,
|
||||
extra_data)
|
||||
|
|
|
@ -21,8 +21,7 @@ use selector_parser::{SelectorImpl, SelectorParser};
|
|||
use selectors::parser::SelectorList;
|
||||
use servo_config::prefs::PREFS;
|
||||
use servo_url::ServoUrl;
|
||||
use shared_lock::{SharedRwLock, Locked, ToCssWithGuard};
|
||||
use shared_lock::{SharedRwLockReadGuard, SharedRwLockWriteGuard};
|
||||
use shared_lock::{SharedRwLock, Locked, ToCssWithGuard, SharedRwLockReadGuard};
|
||||
use std::cell::Cell;
|
||||
use std::fmt;
|
||||
use std::sync::Arc;
|
||||
|
@ -556,23 +555,42 @@ impl Stylesheet {
|
|||
/// Updates an empty stylesheet from a given string of text.
|
||||
pub fn update_from_str(existing: &Stylesheet,
|
||||
css: &str,
|
||||
guard: &mut SharedRwLockWriteGuard,
|
||||
stylesheet_loader: Option<&StylesheetLoader>,
|
||||
error_reporter: &ParseErrorReporter,
|
||||
extra_data: ParserContextExtraData) {
|
||||
let mut rules = existing.rules.write_with(guard);
|
||||
let mut namespaces = existing.namespaces.write();
|
||||
let mut namespaces = Namespaces::default();
|
||||
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 rule_parser = TopLevelRuleParser {
|
||||
stylesheet_origin: existing.origin,
|
||||
namespaces: &mut namespaces,
|
||||
shared_lock: &existing.shared_lock,
|
||||
stylesheet_origin: origin,
|
||||
namespaces: namespaces,
|
||||
shared_lock: shared_lock,
|
||||
loader: stylesheet_loader,
|
||||
context: ParserContext::new_with_extra_data(existing.origin,
|
||||
&existing.base_url,
|
||||
context: ParserContext::new_with_extra_data(origin,
|
||||
base_url,
|
||||
error_reporter,
|
||||
extra_data),
|
||||
state: Cell::new(State::Start),
|
||||
|
@ -584,7 +602,7 @@ impl Stylesheet {
|
|||
let mut iter = RuleListParser::new_for_stylesheet(&mut input, rule_parser);
|
||||
while let Some(result) = iter.next() {
|
||||
match result {
|
||||
Ok(rule) => rules.0.push(rule),
|
||||
Ok(rule) => rules.push(rule),
|
||||
Err(range) => {
|
||||
let pos = range.start;
|
||||
let message = format!("Invalid rule: '{}'", iter.input.slice(range));
|
||||
|
@ -594,8 +612,7 @@ impl Stylesheet {
|
|||
}
|
||||
}
|
||||
|
||||
existing.dirty_on_viewport_size_change
|
||||
.store(input.seen_viewport_percentages(), Ordering::Release);
|
||||
(rules, input.seen_viewport_percentages())
|
||||
}
|
||||
|
||||
/// Creates an empty stylesheet and parses it with a given base url, origin
|
||||
|
@ -611,28 +628,21 @@ impl Stylesheet {
|
|||
stylesheet_loader: Option<&StylesheetLoader>,
|
||||
error_reporter: &ParseErrorReporter,
|
||||
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,
|
||||
base_url: base_url,
|
||||
namespaces: RwLock::new(Namespaces::default()),
|
||||
rules: CssRules::new(Vec::new(), &shared_lock),
|
||||
namespaces: RwLock::new(namespaces),
|
||||
rules: CssRules::new(rules, &shared_lock),
|
||||
media: Arc::new(shared_lock.wrap(media)),
|
||||
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),
|
||||
};
|
||||
|
||||
{
|
||||
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.
|
||||
|
|
|
@ -362,8 +362,6 @@ pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheet
|
|||
referrer: *mut ThreadSafeURIHolder,
|
||||
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 extra_data = unsafe { ParserContextExtraData {
|
||||
base: Some(GeckoArcURI::new(base)),
|
||||
|
@ -384,10 +382,7 @@ pub extern "C" fn Servo_StyleSheet_ClearAndUpdate(stylesheet: RawServoStyleSheet
|
|||
};
|
||||
|
||||
let sheet = Stylesheet::as_arc(&stylesheet);
|
||||
sheet.rules.write_with(&mut guard).0.clear();
|
||||
|
||||
Stylesheet::update_from_str(&sheet, input, &mut guard, loader,
|
||||
&StdoutErrorReporter, extra_data);
|
||||
Stylesheet::update_from_str(&sheet, input, loader, &StdoutErrorReporter, extra_data);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue