pub struct RcuArc<T: Send + Sync + 'static> { /* private fields */ }Expand description
A version of crate::RcuOptionArc which does not require T: RcuDroppable in exchange for
some extra atomic checking on reads.
RcuArc allows arbitrary types to be used with RCU by separating Droping the type,
which may not be safe to do on the RCU advancer thread, and freeing the allocation for the
type, which is safe to do, once an RCU grace period has elapsed.
We do the former by Droping the old Arc<T> synchronously on the calling thread when we
do a replace. We do the latter by first placing a Weak<T> in the RCU callback queue to hold
the memory alive (but with a potential strong count of zero) until an RCU grace period has
elapsed.
Since the strong count of the memory may drop to zero even while a reader holds an RcuReadScope, readers must verify the memory is safe to read. Readers safely do this by using a Weak::upgrade, which serializes with a compare_exchange loop on the strong count.
Implementations§
Source§impl<T: Send + Sync + 'static> RcuArc<T>
impl<T: Send + Sync + 'static> RcuArc<T>
Sourcepub fn new(data: impl Into<Option<Arc<T>>>) -> Self
pub fn new(data: impl Into<Option<Arc<T>>>) -> Self
Create a new RcuArc from an Option<Arc<T>>.
Sourcepub fn upgrade(&self) -> Option<Arc<T>>
pub fn upgrade(&self) -> Option<Arc<T>>
Read the contents of the RcuArc.
Returns None if the wrapped Arc is None or is no longer valid.
Sourcepub fn update(&self, data: impl Into<Option<Arc<T>>>)
pub fn update(&self, data: impl Into<Option<Arc<T>>>)
Write a new Option<Arc<T>> to the RcuArc.
The old Arc<T> (if any) is dropped on the caller’s thread, running T::drop()
synchronously if it was the last strong reference.
Sourcepub fn is_some(&self) -> bool
pub fn is_some(&self) -> bool
Returns true if the RCU wrapper currently contains a value.
Unlike self.upgrade().is_some(), this neither takes a transient strong reference nor
enters an RcuReadScope. A non-null pointer stored in the RcuArc always owns a strong
count, and the pointer is never dereferenced, so observing a non-null pointer is sufficient.
This guarantees that calling is_some() can never result in the caller running T::drop(),
which matters when T::drop() may acquire locks.
Sourcepub fn is_none(&self) -> bool
pub fn is_none(&self) -> bool
Returns true if the RCU wrapper does not contain a value.
See Self::is_some for why this does not upgrade.