pub struct Brc<T: ?Sized + SupportedPointee, A: Allocator = Global> { /* private fields */ }Expand description
A thread-safe reference counted object, biased towards a particular thread.
§Differences from Arc
Most differences come from the fact that Self::strong_count is not exact.
This means that Brc::get_mut and Brc::try_unwrap can fail spuriously
even if the Arc is logically unique.
It also means that Brc::into_inner cannot provide the same guarantees as Arc::into_inner.
§Allocator
The Brc is parameterized by an Allocator just like Arc.
However, the allocator is stored in the object header and so is shared across
all references to a particular object.
Although this is mainly due to design limitations,
it obliviates the need for an A: Clone bound in some places that Arc requires that.
However, it does add an A: Clone bound to Brc::into_raw_with_allocator.
§Deferred Destruction & Deferred Panics
Destruction is not guaranteed to occur immediately when the last reference is dropped.
It may be deferred until collect is called on another thread.
Since collect is called implicitly by Brc::clone, Brc::clone and Brc::new,
any of these functions could panic while executing the deferred destructor of an unrelated object.
If this is unacceptable,
either use the Brc::drop_no_collect and Brc::clone_no_collect functions
or the nounwind crate.
Implementations§
Source§impl<T> Brc<[T]>
impl<T> Brc<[T]>
Sourcepub fn clone_from_slice(slice: &[T]) -> Selfwhere
T: Clone,
pub fn clone_from_slice(slice: &[T]) -> Selfwhere
T: Clone,
Create a new Brc, cloning each element from the specified slice.
Equivalent to From<[T]>, but potentially clearer.
Prefer using Brc::copy_from_slice wherever possible,
as copying is much faster than cloning.
§Panics
Will panic if T::clone does,
in addition to the cases that Self::new does.
Sourcepub fn copy_from_slice(slice: &[T]) -> Selfwhere
T: Copy,
pub fn copy_from_slice(slice: &[T]) -> Selfwhere
T: Copy,
Create a new Brc, using a memcpy of the specified slice
This is more efficient than Self::clone_from_slice or From<&[T]>,
by taking advantage of the T: Copy bound.
Even on nightly, this library avoids specialization as it is an “incomplete feature”
with soundness issues.
§Panics
This function should only panic in the cases Self::new does.
Source§impl<T> Brc<T>
impl<T> Brc<T>
Source§impl<T, A: Allocator> Brc<T, A>
impl<T, A: Allocator> Brc<T, A>
Sourcepub fn new_with_in(func: impl FnOnce() -> T, alloc: A) -> Self
pub fn new_with_in(func: impl FnOnce() -> T, alloc: A) -> Self
Construct a new Brc, using a closure to initialize the specified value,
along with using a particular allocator.
This can potentially improve performance by allowing values to be constructed in place.
§Panics
May panic in the same cases as Self::new_with,
or if any method on the allocator does.
Sourcepub fn try_unwrap(this: Self) -> Result<T, Self>where
T: Sized,
pub fn try_unwrap(this: Self) -> Result<T, Self>where
T: Sized,
If the Brc is uniquely owned,
return the inner value.
Like Self::get_mut, this may fail spuriously
(as Self::is_unique can have false positive).
This suffers from the same race condition described in Arc::try_unwrap.
In particular, this means that if all threads call Arc::try_unwrap,
it is possible that the value is dropped and no thread gets the value.
Unfortunately, there is no solution
§Errors
Returns an Err holding the original value,
if the value is not known to be unique.
Sourcepub fn into_inner(this: Self) -> Option<T>
pub fn into_inner(this: Self) -> Option<T>
If the Brc is uniquely owned,
return the inner value.
Like Self::get_mut, this may fail spuriously
(as Self::is_unique can have false positive).
Unlike Arc::into_inner,
this does not currently avoid the race condition present in Self::try_unwrap.
This means that if all threads call Arc::try_unwrap,
it is possible that the value is dropped and no thread gets the value.
This is because Self::strong_count is not always exact,
and dropping from the non-biased thread sometimes requires placing
objects in the internal queue.
In particular, if many refcounts are incremented on the biased threads,
but then have Self::into_inner called on a non-biased thread,
then the non-biased thread will not know when the value actually becomes unique,
and will have to wait until the object is placed in the queue and later processed.
Source§impl<T: ?Sized + SupportedPointee, A: Allocator> Brc<T, A>
impl<T: ?Sized + SupportedPointee, A: Allocator> Brc<T, A>
Sourcepub fn allocator(this: &Self) -> &A
pub fn allocator(this: &Self) -> &A
Return a reference to the underlying allocator.
Mirrors Arc::allocator.
Sourcepub fn strong_count(this: &Self) -> Result<usize, ImpreciseRefCountError>
pub fn strong_count(this: &Self) -> Result<usize, ImpreciseRefCountError>
Return the number of strong references to the object, or an error if that value cannot be pricelessly determined.
If this thread is the biased thread, then it can always determine the true reference count. If it is not the biased thread, then it can only approximate the value.
§Errors
Gives an ImpreciseRefCountError if not on the biased thread,
and the true reference count cannot be determined.
Sourcepub fn weak_count(this: &Self) -> Result<usize, ImpreciseRefCountError>
pub fn weak_count(this: &Self) -> Result<usize, ImpreciseRefCountError>
Returns the number of weak pointers to the object, or an error if that value cannot be precisely determined.
§Errors
Gives an ImpreciseRefCountError if not on the biased thread,
and the true reference count cannot be determined.
Sourcepub fn is_unique(this: &Self) -> bool
pub fn is_unique(this: &Self) -> bool
Determine if this Brc is uniquely owned.
Mirrors std::sync::Arc::is_unique.
Due to the nature of biased reference counting,
this may have false-negatives when called on a non-biased thread.
However, it will never have false positives.
See Self::strong_count for details.
Sourcepub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T
pub unsafe fn get_mut_unchecked(this: &mut Self) -> &mut T
Return a mutable reference to the value in this Brc,
unsafely assuming if it is uniquely owned.
See also Self::get_mut which clones the value instead of returning None.
§Safety
This is safe if Self::is_unique returns true,
but due to false negatives from this function may be true in other cases.
Trigger immediate undefined behavior if there are any other references to the inner value,
as a &mut T reference must always be unique.
Sourcepub fn get_mut(this: &mut Self) -> Option<&mut T>
pub fn get_mut(this: &mut Self) -> Option<&mut T>
Return a mutable reference to the value in this Brc,
or None if it is not uniquely owned.
This may fail spuriously on a non-biased thread,
due to inability to determine the true value of the reference count.
In other words, Self::is_unique has false negatives.
See also Self::make_mut which clones the value instead of returning None.
Sourcepub fn make_mut(this: &mut Self) -> &mut T
pub fn make_mut(this: &mut Self) -> &mut T
Return a mutable reference to this Brc if it is uniquely owned,
or Clone it to make it unique otherwise.
May Clone the value unnecessarily if uniqueness
can not be guaranteed by Self::is_unique.
See also Self::get_mut which returns None instead of cloning the value.
This mirrors the Arc::make_mut method, but may involve m
Sourcepub fn downgrade(this: &Self) -> Weak<T, A>where
T: SupportedWeakPointee,
pub fn downgrade(this: &Self) -> Weak<T, A>where
T: SupportedWeakPointee,
Downgrade into a new weak reference.
Mirrors Arc::downgrade.
Sourcepub unsafe fn from_raw(ptr: *const T) -> Self
pub unsafe fn from_raw(ptr: *const T) -> Self
Create a Brc from a raw pointer,
originating from Brc::into_raw.
Mirrors Arc::from_raw.
See also Brc::decrement_strong_count, which directly mutates the reference count
without creating a owned value.
This is subject to roughly the same safety requirements.
Because the Brc stores the allocator in the header (as discussed in the type docs),
this function works fine for any allocator.
However, a Brc::from_raw_in function is added for completeness.
§Safety
This must correspond exactly to an owned reference count from Brc::into_raw,
and is vulnerable to double-free if called multiple times on the same pointer.
This is only valid for the result of Brc::into_raw, not for any other piece of memory.
§Panics
This function is infallible.
Sourcepub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self
pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self
Create a Brc from a raw pointer along with its allocator,
originating from Brc::into_raw_with_allocator.
Mirrors Arc::from_raw_in.
This function currently discards the allocator and calls Self::into_raw.
For future-proofing and compatibility with Arc,
it is required that the allocator is
equivalent to calling Self::allocator on the original reference.
§Safety
Same requirements as Brc::from_raw.
§Panics
This function is infallible unless the allocator’s drop function panics.
Sourcepub fn into_raw(this: Self) -> *const T
pub fn into_raw(this: Self) -> *const T
Consumes this Brc, converting it into a raw pointer.
Mirrors Arc::into_raw.
Because the allocator is stored in the header,
this works well with any allocator.
§Safety
This is perfectly safe, but may leak memory.
§Panics
This function is infallible.
Sourcepub fn into_raw_with_allocator(this: Self) -> (*const T, A)where
A: Clone,
pub fn into_raw_with_allocator(this: Self) -> (*const T, A)where
A: Clone,
Consumes this Brc, converting it into a raw pointer
along with a copy of the underlying allocator.
Mirrors Arc::into_raw_with_allocator,
but needs to add a A: Clone bound because the allocator is stored in the header
(see type-level docs for details)
If you just want to call Brc::from_raw_in later,
prefer Brc::into_raw and Brc::from_raw which avoid cloning the allocator.
Because the allocator is stored in the header,
these functions work for any allocator (unlike Arc).
§Safety
This is perfectly safe, but may leak memory.
§Panics
This function is infallible unless the allocator clone function panics.
Sourcepub fn as_ptr(this: &Self) -> *const T
pub fn as_ptr(this: &Self) -> *const T
Convert this Brc into a raw pointer,
without affecting the reference count.
Mirrors Arc::as_ptr.
This will give the same result as Self::into_raw would,
but does not consume ownership.
§Panics
This function is infallible.
Sourcepub unsafe fn increment_strong_count(ptr: *const T)
pub unsafe fn increment_strong_count(ptr: *const T)
Increments the strong reference count on the Brc associated with the specified pointer.
Similarly to Self::clone_no_collect, this does not implicitly call collect.
This is a low-level function which leaves that choice to the user.
Mirrors Arc::increment_strong_count
§Panics
See Self::clone_no_collect for details.
§Safety
The pointer must have been obtained through Brc::into_raw or Brc::as_ptr,
have the correct type, and still point to valid memory (not dropped).
Sourcepub unsafe fn decrement_strong_count(ptr: *const T)
pub unsafe fn decrement_strong_count(ptr: *const T)
Decrements the strong reference count on the Brc associated with the specified pointer.
Similarly to Self::drop_no_collect, this does not implicitly call collect.
This is a low-level function which leaves that choice to the user.
Mirrors Arc::decrement_strong_count.
§Panics
See Self::drop_no_collect for details.
§Safety
The pointer must have been obtained through Brc::into_raw or Brc::as_ptr,
have the correct type, and still point to valid memory (not dropped).
Each decrement must match a corresponding increment,
or else use after free must occur.
Must not decrement the last reference count while other Brc references are active.
Sourcepub fn ptr_eq(this: &Self, other: &Self) -> bool
pub fn ptr_eq(this: &Self, other: &Self) -> bool
Checks if this points to the same object as the other.
This does not compare pointer metadata for trait objects,
just like std::sync::Arc::ptr_eq and core::ptr::addr_eq.
Source§impl<T: ?Sized + SupportedPointee, A: Allocator> Brc<T, A>
impl<T: ?Sized + SupportedPointee, A: Allocator> Brc<T, A>
Sourcepub fn clone_no_collect(this: &Self) -> Self
pub fn clone_no_collect(this: &Self) -> Self
Sourcepub fn drop_no_collect(this: Self)
pub fn drop_no_collect(this: Self)
Drop this reference without invoking collect.
§Panics
Unlike drop which can panic due to collect,
this function only panics if the underlying destructor does.
Similarly to drop the destructor may be deferred,
meaning a panicking destructor may not happen right away.
This function may abort if internal state appears corrupted.
Clone this reference count by incrementing the shared count.
This function works the same regardless of the thread its called on. Even if this is the biased thread, this still increments the shared count.
Trait Implementations§
Source§impl<T: ?Sized + SupportedPointee, A: Allocator> Clone for Brc<T, A>
impl<T: ?Sized + SupportedPointee, A: Allocator> Clone for Brc<T, A>
Source§fn clone(&self) -> Self
fn clone(&self) -> Self
Create a new reference to the underlying object.
This implicitly calls collect to help cleanup garbage from other threads.
Use Self::clone_no_collect to avoid this.
§Panics
This function will panic only if collect panics.
This function may abort if internal state appears corrupted, or if a reference count overflows.
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl<T, U: ?Sized + SupportedPointee, A: Allocator> CoerciblePtr<U> for Brc<T, A>
impl<T, U: ?Sized + SupportedPointee, A: Allocator> CoerciblePtr<U> for Brc<T, A>
Source§fn as_sized_ptr(&mut self) -> *mut Self::Pointee
fn as_sized_ptr(&mut self) -> *mut Self::Pointee
Source§impl<T: ?Sized + SupportedPointee, A: Allocator> Drop for Brc<T, A>
Available on non-crate feature nightly-may-dangle only.
impl<T: ?Sized + SupportedPointee, A: Allocator> Drop for Brc<T, A>
nightly-may-dangle only.Source§fn drop(&mut self)
fn drop(&mut self)
Drops a reference to the underlying object, potentially freeing it if there are otherwise no references.
This implicitly calls collect to help cleanup garbage from other threads.
Use Self::drop_no_collect to avoid this.
Due to the nature of biased reference counting, there are some cases where destruction may be deferred.
§Panics
This may panic if the underlying destructor panics,
or if collect panics while executing a deferred destructor.
This may abort if internal state appears corrupted.
Source§impl<T: ?Sized + SupportedPointee + Error, A: Allocator> Error for Brc<T, A>
impl<T: ?Sized + SupportedPointee + Error, A: Allocator> Error for Brc<T, A>
Source§fn source(&self) -> Option<&(dyn Error + 'static)>
fn source(&self) -> Option<&(dyn Error + 'static)>
Source§fn description(&self) -> &str
fn description(&self) -> &str
use the Display impl or to_string()
Source§impl<T: Clone> From<&[T]> for Brc<[T]>
Create a new Brc<[T]> by cloning the contents of the specified slice.
impl<T: Clone> From<&[T]> for Brc<[T]>
Create a new Brc<[T]> by cloning the contents of the specified slice.
Equivalent to calling Brc::clone_from_slice.
Prefer using Brc::copy_from_slice wherever possible,
as copying is much faster than cloning.
Source§impl<T: ?Sized + SupportedPointee> From<Box<T>> for Brc<T>
impl<T: ?Sized + SupportedPointee> From<Box<T>> for Brc<T>
This conversion is guaranteed not to copy values to the stack, which means large values cannot trigger stack overflow.
However, this cannot reuse the allocation as a Box has no room to hold the reference count.
Source§impl<T> FromIterator<T> for Brc<[T]>
impl<T> FromIterator<T> for Brc<[T]>
Source§fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
Source§impl<T: ?Sized + SupportedPointee + Ord, A: Allocator> Ord for Brc<T, A>
impl<T: ?Sized + SupportedPointee + Ord, A: Allocator> Ord for Brc<T, A>
Source§impl<T: ?Sized + SupportedPointee + PartialOrd, A: Allocator> PartialOrd for Brc<T, A>
impl<T: ?Sized + SupportedPointee + PartialOrd, A: Allocator> PartialOrd for Brc<T, A>
impl<T: ?Sized + SupportedPointee, A: Allocator> CloneStableDeref for Brc<T, A>
impl<T: ?Sized + SupportedPointee + Eq, A: Allocator> Eq for Brc<T, A>
impl<T: ?Sized + SupportedPointee + Sync + Send, A: Allocator + Send + Sync> Send for Brc<T, A>
impl<T: ?Sized + SupportedPointee, A: Allocator> StableDeref for Brc<T, A>
impl<T: ?Sized + SupportedPointee + Sync + Send, A: Allocator + Send + Sync> Sync for Brc<T, A>
impl<T: ?Sized + SupportedPointee, A: Allocator> Unpin for Brc<T, A>
impl<T> ZeroableInOption for Brc<T>
This requires T: Sized because not all pointer metadata is safe to zero-initialize.