pub struct HazardPointer<'domain, F = Global> { /* private fields */ }
Expand description

A type that can protect a referenced object from reclamation.

Protects up to a single address from concurrent reclamation in the referenced Domain.

A hazard pointer does nothing when initially constructed. You need to load the pointer stored by an std::sync::atomic::AtomicPtr through it with HazardPointer::protect in order for it to protect an object. That protection is tied to the exclusive (&mut) borrow of the HazardPointer that protect takes; the moment the exclusive borrow ends (such as when the HazardPointer is dropped), the protection ends.

Note that a hazard pointer can only protect an object if any call to retire for said object happens in the same domain as the one the hazard pointer was created in. The generic argument F is a domain family, which helps enforce that statically. Families are discussed in the documentation for Domain. F defaults to the global domain.

If you want a (slightly) higher-level interface, use AtomicPtr.

If you need to protect multiple referenced objects at the same time, use HazardPointerArray.

Implementations§

source§

impl HazardPointer<'static, Global>

source

pub fn new() -> Self

Create a new hazard pointer in the global domain.

source

pub fn many<const N: usize>() -> HazardPointerArray<'static, Global, N>

Create a new hazard pointer array in the global domain.

source§

impl<'domain, F> HazardPointer<'domain, F>

source

pub fn new_in_domain(domain: &'domain Domain<F>) -> Self

Create a new hazard pointer in the given domain.

source

pub fn many_in_domain<const N: usize>( domain: &'domain Domain<F> ) -> HazardPointerArray<'domain, F, N>

Create a new hazard pointer array in the given domain.

source

pub unsafe fn protect<'l, T>(&'l mut self, src: &AtomicPtr<T>) -> Option<&'l T>
where T: Sync, F: 'static,

Protect the value loaded from the given AtomicPtr, and dereference it to &T.

This operation will load the AtomicPtr multiple times:

  1. load to get the currently stored pointer, ptr
  2. store ptr into the hazard pointer to protect it from reclamation
  3. load again to check that the pointer didn’t change between 1 and 2. if it did, set the loaded value to ptr and goto 2.

Returns None if the loaded pointer is null.

T must be Sync since we do not know which thread stored the pointer in the first place.

Safety
  1. The value loaded from AtomicPtr is a valid &T, or null.
  2. The loaded &T will only be deallocated through calls to retire functions on the same Domain as this holder is associated with.
source

pub fn protect_ptr<'l, T>( &'l mut self, src: &AtomicPtr<T> ) -> Option<(NonNull<T>, PhantomData<&'l T>)>
where F: 'static,

Protect the value loaded from the given AtomicPtr, and return it as NonNull<T>.

This operation will load the AtomicPtr multiple times:

  1. load to get the currently stored pointer, ptr
  2. store ptr into the hazard pointer to protect it from reclamation
  3. load again to check that the pointer didn’t change between 1 and 2. if it did, set the loaded value to ptr and goto 2.

Note that protecting a given pointer only has an effect if any thread that may drop the pointer does so through the same Domain as this hazard pointer is associated with.

Returns None if the loaded pointer is null.

source

pub unsafe fn try_protect<'l, T>( &'l mut self, ptr: *mut T, src: &AtomicPtr<T> ) -> Result<Option<&'l T>, *mut T>
where T: Sync, F: 'static,

Protect ptr and dereference it to &T if it’s safe to do so.

Unlike HazardPointer::protect, this operation will not load the AtomicPtr multiple times. It will only perform a single load to check that the stored pointer does not change before we have a chance to protect ptr.

If the value has changed, the new pointer is returned wrapped in Err.

T must be Sync since we do not know which thread stored the pointer in the first place.

Returns Ok(None) if ptr.is_null().

Safety
  1. The value loaded from AtomicPtr is a valid &T, or null.
  2. The loaded &T will only be deallocated through calls to retire functions on the same Domain as this holder is associated with.
source

pub fn try_protect_ptr<'l, T>( &'l mut self, ptr: *mut T, src: &AtomicPtr<T> ) -> Result<Option<(NonNull<T>, PhantomData<&'l T>)>, *mut T>
where F: 'static,

Protect ptr and dereference it to NonNull<T> if it’s safe to do so.

Unlike HazardPointer::protect_ptr, this operation will not load the AtomicPtr multiple times. It will only perform a single load to check that the stored pointer does not change before we have a chance to protect ptr.

Note that protecting a given pointer only has an effect if any thread that may drop the pointer does so through the same Domain as this hazard pointer is associated with.

If the value has changed, the new pointer is returned wrapped in Err.

Returns Ok(None) if ptr.is_null().

source

pub fn reset_protection(&mut self)

Release the protection awarded by this hazard pointer, if any.

If the hazard pointer was protecting an object, that object may now be reclaimed when retired (assuming it isn’t protected by any other hazard pointers).

source

pub fn protect_raw<T>(&mut self, ptr: *mut T)
where F: 'static,

Protect the given address.

You will very rarely want to use this method, and should prefer the other protection methods instead, as they guard against races between when the value of a shared pointer was read and any changes to the shared pointer address.

Note that protecting a given pointer only has an effect if any thread that may drop the pointer does so through the same Domain as this hazard pointer is associated with.

Trait Implementations§

source§

impl Default for HazardPointer<'static, Global>

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<F> Drop for HazardPointer<'_, F>

source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'domain, F> RefUnwindSafe for HazardPointer<'domain, F>
where F: RefUnwindSafe,

§

impl<'domain, F> Send for HazardPointer<'domain, F>
where F: Sync,

§

impl<'domain, F> Sync for HazardPointer<'domain, F>
where F: Sync,

§

impl<'domain, F> Unpin for HazardPointer<'domain, F>

§

impl<'domain, F> UnwindSafe for HazardPointer<'domain, F>
where F: RefUnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> Reclaim for T