struct RuleNode {
root: Option<WeakRuleNode>,
parent: Option<StrongRuleNode>,
source: Option<StyleSource>,
cascade_priority: CascadePriority,
refcount: AtomicUsize,
approximate_free_count: AtomicUsize,
children: RwLock<Map<ChildKey, WeakRuleNode>>,
next_free: AtomicPtr<RuleNode>,
}
Expand description
A node in the rule tree.
Fields§
§root: Option<WeakRuleNode>
The root node. Only the root has no root pointer, for obvious reasons.
parent: Option<StrongRuleNode>
The parent rule node. Only the root has no parent.
source: Option<StyleSource>
The actual style source, either coming from a selector in a StyleRule, or a raw property declaration block (like the style attribute).
None for the root node.
cascade_priority: CascadePriority
The cascade level + layer order this rule is positioned at.
refcount: AtomicUsize
The refcount of this node.
Starts at one. Incremented in StrongRuleNode::clone
and
WeakRuleNode::upgrade
. Decremented in StrongRuleNode::drop
and RuleTree::swap_free_list_and_gc
.
If a non-root node’s refcount reaches zero, it is incremented back to at
least one in RuleNode::pretend_to_be_on_free_list
until the caller who
observed it dropping to zero had a chance to try to remove it from its
parent’s children list.
The refcount should never be decremented to zero if the value in
next_free
is not null.
approximate_free_count: AtomicUsize
Only used for the root, stores the number of free rule nodes that are around.
children: RwLock<Map<ChildKey, WeakRuleNode>>
The children of a given rule node. Children remove themselves from here when they go away.
next_free: AtomicPtr<RuleNode>
This field has two different meanings depending on whether this is the root node or not.
If it is the root, it represents the head of the free list. It may be
null, which means the free list is gone because the tree was dropped,
and it may be RuleNode::DANGLING_PTR
, which means the free list is
empty.
If it is not the root node, this field is either null if the node is
not on the free list, RuleNode::DANGLING_PTR
if it is the last item
on the free list or the node is pretending to be on the free list, or
any valid non-null pointer representing the next item on the free list
after this one.
See RuleNode::push_on_free_list
, swap_free_list_and_gc
, and
WeakRuleNode::upgrade
.
Two threads should never attempt to put the same node on the free list both at the same time.
Implementations§
source§impl RuleNode
impl RuleNode
const DANGLING_PTR: *mut Self = {0x8 as *mut rule_tree::core::RuleNode}
unsafe fn new( root: WeakRuleNode, parent: StrongRuleNode, source: StyleSource, cascade_priority: CascadePriority, ) -> Self
fn root() -> Self
fn key(&self) -> ChildKey
sourceunsafe fn drop_without_free_list(this: &mut UnsafeBox<Self>)
unsafe fn drop_without_free_list(this: &mut UnsafeBox<Self>)
Drops a node without ever putting it on the free list.
Note that the node may not be dropped if we observe that its refcount isn’t zero anymore when we write-lock its parent’s children map to remove it.
This loops over parents of dropped nodes if their own refcount reaches zero to avoid recursion when dropping deep hierarchies of nodes.
For non-root nodes, this should always be preceded by a call of
RuleNode::pretend_to_be_on_free_list
.
sourceunsafe fn push_on_free_list(this: &UnsafeBox<Self>) -> bool
unsafe fn push_on_free_list(this: &UnsafeBox<Self>) -> bool
Pushes this node on the tree’s free list. Returns false if the free list is gone. Should only be called after we decremented a node’s refcount to zero and pretended to be on the free list.
sourceunsafe fn pretend_to_be_on_free_list(this: &UnsafeBox<Self>)
unsafe fn pretend_to_be_on_free_list(this: &UnsafeBox<Self>)
Makes the node pretend to be on the free list. This will increment the
refcount by 1 and store Self::DANGLING_PTR
in next_free
. This
method should only be called after caller decremented the refcount to
zero, with the null pointer stored in next_free
.
fn as_mut_ptr(&self) -> *mut RuleNode
Auto Trait Implementations§
impl !Freeze for RuleNode
impl !RefUnwindSafe for RuleNode
impl Send for RuleNode
impl Sync for RuleNode
impl Unpin for RuleNode
impl !UnwindSafe for RuleNode
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more