mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Replace RwLock<StyleRule> with Locked<StyleRule>
This commit is contained in:
parent
57724e5a37
commit
aeffca2a59
33 changed files with 279 additions and 334 deletions
|
@ -10,9 +10,9 @@
|
|||
use arc_ptr_eq;
|
||||
#[cfg(feature = "servo")]
|
||||
use heapsize::HeapSizeOf;
|
||||
use owning_handle::OwningHandle;
|
||||
use parking_lot::{RwLock, RwLockReadGuard};
|
||||
use properties::{Importance, PropertyDeclarationBlock};
|
||||
use shared_lock::{Locked, ReadGuards, SharedRwLockReadGuard};
|
||||
use std::io::{self, Write};
|
||||
use std::ptr;
|
||||
use std::sync::Arc;
|
||||
|
@ -52,35 +52,11 @@ pub struct RuleTree {
|
|||
#[derive(Debug, Clone)]
|
||||
pub enum StyleSource {
|
||||
/// A style rule stable pointer.
|
||||
Style(Arc<RwLock<StyleRule>>),
|
||||
Style(Arc<Locked<StyleRule>>),
|
||||
/// A declaration block stable pointer.
|
||||
Declarations(Arc<RwLock<PropertyDeclarationBlock>>),
|
||||
}
|
||||
|
||||
type StyleSourceGuardHandle<'a> =
|
||||
OwningHandle<
|
||||
RwLockReadGuard<'a, StyleRule>,
|
||||
RwLockReadGuard<'a, PropertyDeclarationBlock>>;
|
||||
|
||||
/// A guard for a given style source.
|
||||
pub enum StyleSourceGuard<'a> {
|
||||
/// A guard for a style rule.
|
||||
Style(StyleSourceGuardHandle<'a>),
|
||||
/// A guard for a declaration block.
|
||||
Declarations(RwLockReadGuard<'a, PropertyDeclarationBlock>),
|
||||
}
|
||||
|
||||
impl<'a> ::std::ops::Deref for StyleSourceGuard<'a> {
|
||||
type Target = PropertyDeclarationBlock;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
match *self {
|
||||
StyleSourceGuard::Declarations(ref block) => &*block,
|
||||
StyleSourceGuard::Style(ref handle) => &*handle,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StyleSource {
|
||||
#[inline]
|
||||
fn ptr_equals(&self, other: &Self) -> bool {
|
||||
|
@ -92,28 +68,27 @@ impl StyleSource {
|
|||
}
|
||||
}
|
||||
|
||||
fn dump<W: Write>(&self, writer: &mut W) {
|
||||
fn dump<W: Write>(&self, guard: &SharedRwLockReadGuard, writer: &mut W) {
|
||||
use self::StyleSource::*;
|
||||
|
||||
if let Style(ref rule) = *self {
|
||||
let _ = write!(writer, "{:?}", rule.read().selectors);
|
||||
let rule = rule.read_with(guard);
|
||||
let _ = write!(writer, "{:?}", rule.selectors);
|
||||
}
|
||||
|
||||
let _ = write!(writer, " -> {:?}", self.read().declarations());
|
||||
let _ = write!(writer, " -> {:?}", self.read(guard).declarations());
|
||||
}
|
||||
|
||||
/// Read the style source guard, and obtain thus read access to the
|
||||
/// underlying property declaration block.
|
||||
#[inline]
|
||||
pub fn read<'a>(&'a self) -> StyleSourceGuard<'a> {
|
||||
use self::StyleSource::*;
|
||||
match *self {
|
||||
Style(ref rule) => {
|
||||
let owning_ref = OwningHandle::new(rule.read(), |r| unsafe { &*r }.block.read());
|
||||
StyleSourceGuard::Style(owning_ref)
|
||||
}
|
||||
Declarations(ref block) => StyleSourceGuard::Declarations(block.read()),
|
||||
}
|
||||
pub fn read<'a>(&'a self, guard: &'a SharedRwLockReadGuard)
|
||||
-> RwLockReadGuard<'a, PropertyDeclarationBlock> {
|
||||
let block = match *self {
|
||||
StyleSource::Style(ref rule) => &rule.read_with(guard).block,
|
||||
StyleSource::Declarations(ref block) => block,
|
||||
};
|
||||
block.read()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -137,15 +112,15 @@ impl RuleTree {
|
|||
self.root.clone()
|
||||
}
|
||||
|
||||
fn dump<W: Write>(&self, writer: &mut W) {
|
||||
fn dump<W: Write>(&self, guards: &ReadGuards, writer: &mut W) {
|
||||
let _ = writeln!(writer, " + RuleTree");
|
||||
self.root.get().dump(writer, 0);
|
||||
self.root.get().dump(guards, writer, 0);
|
||||
}
|
||||
|
||||
/// Dump the rule tree to stdout.
|
||||
pub fn dump_stdout(&self) {
|
||||
pub fn dump_stdout(&self, guards: &ReadGuards) {
|
||||
let mut stdout = io::stdout();
|
||||
self.dump(&mut stdout);
|
||||
self.dump(guards, &mut stdout);
|
||||
}
|
||||
|
||||
/// Insert the given rules, that must be in proper order by specifity, and
|
||||
|
@ -307,6 +282,17 @@ pub enum CascadeLevel {
|
|||
}
|
||||
|
||||
impl CascadeLevel {
|
||||
/// Select a lock guard for this level
|
||||
pub fn guard<'a>(&self, guards: &'a ReadGuards<'a>) -> &'a SharedRwLockReadGuard<'a> {
|
||||
match *self {
|
||||
CascadeLevel::UANormal |
|
||||
CascadeLevel::UserNormal |
|
||||
CascadeLevel::UserImportant |
|
||||
CascadeLevel::UAImportant => guards.ua_or_user,
|
||||
_ => guards.author,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns whether this cascade level is unique per element, in which case
|
||||
/// we can replace the path in the cascade without fear.
|
||||
pub fn is_unique_per_element(&self) -> bool {
|
||||
|
@ -450,7 +436,7 @@ impl RuleNode {
|
|||
}
|
||||
}
|
||||
|
||||
fn dump<W: Write>(&self, writer: &mut W, indent: usize) {
|
||||
fn dump<W: Write>(&self, guards: &ReadGuards, writer: &mut W, indent: usize) {
|
||||
const INDENT_INCREMENT: usize = 4;
|
||||
|
||||
for _ in 0..indent {
|
||||
|
@ -467,7 +453,7 @@ impl RuleNode {
|
|||
|
||||
match self.source {
|
||||
Some(ref source) => {
|
||||
source.dump(writer);
|
||||
source.dump(self.level.guard(guards), writer);
|
||||
}
|
||||
None => {
|
||||
if indent != 0 {
|
||||
|
@ -479,7 +465,7 @@ impl RuleNode {
|
|||
|
||||
let _ = write!(writer, "\n");
|
||||
for child in self.iter_children() {
|
||||
child.get().dump(writer, indent + INDENT_INCREMENT);
|
||||
child.get().dump(guards, writer, indent + INDENT_INCREMENT);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -627,6 +613,11 @@ impl StrongRuleNode {
|
|||
self.get().source.as_ref()
|
||||
}
|
||||
|
||||
/// The cascade level for this node
|
||||
pub fn cascade_level(&self) -> CascadeLevel {
|
||||
self.get().level
|
||||
}
|
||||
|
||||
/// Get the importance that this rule node represents.
|
||||
pub fn importance(&self) -> Importance {
|
||||
self.get().level.importance()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue