Hoist SendElement into dom.rs, label construction as unsafe, and add corresponding SendNode.

This commit is contained in:
Bobby Holley 2016-12-21 12:11:27 -08:00
parent b6e948dc5d
commit 96dc0d1eac
2 changed files with 42 additions and 13 deletions

View file

@ -16,6 +16,7 @@ use selector_parser::{ElementExt, PreExistingComputedValues, PseudoElement};
use sink::Push; use sink::Push;
use std::fmt; use std::fmt;
use std::fmt::Debug; use std::fmt::Debug;
use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use stylist::ApplicableDeclarationBlock; use stylist::ApplicableDeclarationBlock;
@ -262,3 +263,38 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
/// native anonymous content can opt out of this style fixup.) /// native anonymous content can opt out of this style fixup.)
fn skip_root_and_item_based_display_fixup(&self) -> bool; fn skip_root_and_item_based_display_fixup(&self) -> bool;
} }
/// TNode and TElement aren't Send because we want to be careful and explicit
/// about our parallel traversal. However, there are certain situations
/// (including but not limited to the traversal) where we need to send DOM
/// objects to other threads.
#[derive(Debug, PartialEq)]
pub struct SendNode<N: TNode>(N);
unsafe impl<N: TNode> Send for SendNode<N> {}
impl<N: TNode> SendNode<N> {
pub unsafe fn new(node: N) -> Self {
SendNode(node)
}
}
impl<N: TNode> Deref for SendNode<N> {
type Target = N;
fn deref(&self) -> &N {
&self.0
}
}
#[derive(Debug, PartialEq)]
pub struct SendElement<E: TElement>(E);
unsafe impl<E: TElement> Send for SendElement<E> {}
impl<E: TElement> SendElement<E> {
pub unsafe fn new(el: E) -> Self {
SendElement(el)
}
}
impl<E: TElement> Deref for SendElement<E> {
type Target = E;
fn deref(&self) -> &E {
&self.0
}
}

View file

@ -13,7 +13,7 @@ use cache::LRUCache;
use cascade_info::CascadeInfo; use cascade_info::CascadeInfo;
use context::{SharedStyleContext, StyleContext}; use context::{SharedStyleContext, StyleContext};
use data::{ComputedStyle, ElementData, ElementStyles, PseudoStyles}; use data::{ComputedStyle, ElementData, ElementStyles, PseudoStyles};
use dom::{TElement, TNode}; use dom::{SendElement, TElement, TNode};
use properties::{CascadeFlags, ComputedValues, SHAREABLE, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade}; use properties::{CascadeFlags, ComputedValues, SHAREABLE, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade};
use properties::longhands::display::computed_value as display; use properties::longhands::display::computed_value as display;
use rule_tree::StrongRuleNode; use rule_tree::StrongRuleNode;
@ -65,19 +65,13 @@ impl MatchResults {
} }
} }
// TElement isn't Send because we want to be careful and explicit about our
// parallel traversal, but we need the candidates to be Send so that we can stick
// them in ScopedTLS.
#[derive(Debug, PartialEq)]
struct SendElement<E: TElement>(pub E);
unsafe impl<E: TElement> Send for SendElement<E> {}
/// Information regarding a candidate. /// Information regarding a candidate.
/// ///
/// TODO: We can stick a lot more info here. /// TODO: We can stick a lot more info here.
#[derive(Debug)] #[derive(Debug)]
struct StyleSharingCandidate<E: TElement> { struct StyleSharingCandidate<E: TElement> {
/// The element. /// The element. We use SendElement here so that the cache may live in
/// ScopedTLS.
element: SendElement<E>, element: SendElement<E>,
/// The cached common style affecting attribute info. /// The cached common style affecting attribute info.
common_style_affecting_attributes: Option<CommonStyleAffectingAttributes>, common_style_affecting_attributes: Option<CommonStyleAffectingAttributes>,
@ -353,7 +347,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
element, parent); element, parent);
self.cache.insert(StyleSharingCandidate { self.cache.insert(StyleSharingCandidate {
element: SendElement(*element), element: unsafe { SendElement::new(*element) },
common_style_affecting_attributes: None, common_style_affecting_attributes: None,
class_attributes: None, class_attributes: None,
}, ()); }, ());
@ -501,9 +495,8 @@ trait PrivateMatchMethods: TElement {
shared_context: &SharedStyleContext, shared_context: &SharedStyleContext,
candidate: &mut StyleSharingCandidate<Self>) candidate: &mut StyleSharingCandidate<Self>)
-> Result<ComputedStyle, CacheMiss> { -> Result<ComputedStyle, CacheMiss> {
let candidate_element = candidate.element.0; let candidate_element = *candidate.element;
element_matches_candidate(self, candidate, &candidate_element, element_matches_candidate(self, candidate, &candidate_element, shared_context)
shared_context)
} }
} }