arc_swap

Trait RefCnt

source
pub unsafe trait RefCnt: Clone {
    type Base;

    // Required methods
    fn into_ptr(me: Self) -> *mut Self::Base;
    fn as_ptr(me: &Self) -> *mut Self::Base;
    unsafe fn from_ptr(ptr: *const Self::Base) -> Self;

    // Provided methods
    fn inc(me: &Self) -> *mut Self::Base { ... }
    unsafe fn dec(ptr: *const Self::Base) { ... }
}
Expand description

A trait describing smart reference counted pointers.

Note that in a way Option<Arc<T>> is also a smart reference counted pointer, just one that can hold NULL.

The trait is unsafe, because a wrong implementation will break the ArcSwapAny implementation and lead to UB.

This is not actually expected for downstream crate to implement, this is just means to reuse code for Arc and Option<Arc> variants. However, it is theoretically possible (if you have your own Arc implementation).

It is also implemented for Rc, but that is not considered very useful (because the ArcSwapAny is not Send or Sync, therefore there’s very little advantage for it to be atomic).

§Safety

Aside from the obvious properties (like that incrementing and decrementing a reference count cancel each out and that having less references tracked than how many things actually point to the value is fine as long as the count doesn’t drop to 0), it also must satisfy that if two pointers have the same value, they point to the same object. This is specifically not true for ZSTs, but it is true for Arcs of ZSTs, because they have the reference counts just after the value. It would be fine to point to a type-erased version of the same object, though (if one could use this trait with unsized types in the first place).

Furthermore, the type should be Pin (eg. if the type is cloned or moved, it should still point/deref to the same place in memory).

Required Associated Types§

source

type Base

The base type the pointer points to.

Required Methods§

source

fn into_ptr(me: Self) -> *mut Self::Base

Converts the smart pointer into a raw pointer, without affecting the reference count.

This can be seen as kind of freezing the pointer ‒ it’ll be later converted back using from_ptr.

The pointer must point to the value stored (and the value must be the same as one returned by as_ptr.

source

fn as_ptr(me: &Self) -> *mut Self::Base

Provides a view into the smart pointer as a raw pointer.

This must not affect the reference count ‒ the pointer is only borrowed.

source

unsafe fn from_ptr(ptr: *const Self::Base) -> Self

Converts a raw pointer back into the smart pointer, without affecting the reference count.

This is only called on values previously returned by into_ptr. However, it is not guaranteed to be 1:1 relation ‒ from_ptr may be called more times than into_ptr temporarily provided the reference count never drops under 1 during that time (the implementation sometimes owes a reference). These extra pointers will either be converted back using into_ptr or forgotten.

§Safety

This must not be called by code outside of this crate.

Provided Methods§

source

fn inc(me: &Self) -> *mut Self::Base

Increments the reference count by one.

Return the pointer to the inner thing as a side effect.

source

unsafe fn dec(ptr: *const Self::Base)

Decrements the reference count by one.

Note this is called on a raw pointer (one previously returned by into_ptr. This may lead to dropping of the reference count to 0 and destruction of the internal pointer.

§Safety

This must not be called by code outside of this crate.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl<T> RefCnt for Rc<T>

source§

type Base = T

source§

fn into_ptr(me: Rc<T>) -> *mut T

source§

fn as_ptr(me: &Rc<T>) -> *mut T

source§

unsafe fn from_ptr(ptr: *const T) -> Rc<T>

source§

impl<T> RefCnt for Arc<T>

source§

type Base = T

source§

fn into_ptr(me: Arc<T>) -> *mut T

source§

fn as_ptr(me: &Arc<T>) -> *mut T

source§

unsafe fn from_ptr(ptr: *const T) -> Arc<T>

source§

impl<T: RefCnt> RefCnt for Option<T>

source§

type Base = <T as RefCnt>::Base

source§

fn into_ptr(me: Option<T>) -> *mut T::Base

source§

fn as_ptr(me: &Option<T>) -> *mut T::Base

source§

unsafe fn from_ptr(ptr: *const T::Base) -> Option<T>

Implementors§