Struct voluntary_servitude::Atomic
source · pub struct Atomic<T>(_, _);
Expand description
Atomic abstractions of a Box<T>
Implementations
sourceimpl<T> Atomic<T>
impl<T> Atomic<T>
sourcepub fn new(data: Box<T>) -> Self
pub fn new(data: Box<T>) -> Self
Creates new Atomic
let filled = Atomic::from(10);
assert_eq!(*filled.into_inner(), 10);
sourcepub fn store(&self, new: Box<T>, order: Ordering)
pub fn store(&self, new: Box<T>, order: Ordering)
Stores value into Atomic
and drops old one
let filled = Atomic::from(10);
filled.store(5.into(), Ordering::SeqCst);
assert_eq!(*filled.into_inner(), 5);
sourcepub fn swap(&self, new: Box<T>, order: Ordering) -> Box<T>
pub fn swap(&self, new: Box<T>, order: Ordering) -> Box<T>
Stores value into Atomic
returning old value
let option = Atomic::from(10);
assert_eq!(*option.into_inner(), 10);
sourcepub fn into_inner(self) -> Box<T>
pub fn into_inner(self) -> Box<T>
Converts itself into a Box<T>
let ten = Atomic::from(10);
assert_eq!(*ten.into_inner(), 10);
sourcepub unsafe fn from_raw(ptr: *mut T) -> Option<Self>
pub unsafe fn from_raw(ptr: *mut T) -> Option<Self>
Creates new Atomic
if pointer is not null (like NonNull
)
Safety
Unsafe because it uses a raw pointer, so it can’t be sure of its origin (and ownership)
You must own the pointer to call this
let empty = unsafe { Atomic::<()>::from_raw(null_mut()) };
assert!(empty.is_none());
let filled = unsafe { Atomic::from_raw(Box::into_raw(Box::new(10))) };
assert_eq!(filled.map(|a| *a.into_inner()), Some(10));
sourcepub unsafe fn from_raw_unchecked(ptr: *mut T) -> Self
pub unsafe fn from_raw_unchecked(ptr: *mut T) -> Self
Creates new Atomic
based on raw pointer without checking for null pointer
Safety
Unsafe because it trusts that the pointer is not null and because it can’t be sure of the origin of T
(and ownership)
You must own the pointer to call this
let filled = unsafe { Atomic::from_raw_unchecked(Box::into_raw(Box::new(10))) };
assert_eq!(*filled.into_inner(), 10);
// It's UB for `ptr` to be `null_mut()`
// let empty = unsafe { Atomic::<()>::from_raw_unchecked(null_mut()) };
sourcepub fn get_raw(&self, order: Ordering) -> *mut T
pub fn get_raw(&self, order: Ordering) -> *mut T
Atomically extracts the current stored pointer, this function should probably not be called
Safety
It’s almost never safe to deref this value, it could have been dropped from the moment you extracted it to the moment you deref/access it in any way, it will cause UB
It exists to provide a way of implementing safe wrappers (like FillOnceAtomicOption
)
let empty = unsafe { Atomic::<()>::from_raw_unchecked(null_mut()) };
assert_eq!(empty.get_raw(Ordering::SeqCst), null_mut());
let ptr = Box::into_raw(Box::new(10u8));
let filled = unsafe { Atomic::from_raw(ptr) };
assert_eq!(filled.map(|a| a.get_raw(Ordering::SeqCst)), Some(ptr));
// You should probably never deref `ptr`
// You should probably never use this method
// UB will be everywhere, FillOnceAtomicOption is a safe an alternative
sourcepub unsafe fn dangle(&mut self) -> Box<T>
pub unsafe fn dangle(&mut self) -> Box<T>
Empties Atomic
, this function should probably never be called
You should probably use into_inner
Safety
This is extremely unsafe, you don’t want to call this unless you are implementing Drop
for a chained T
All reference will endup invalidated and any function call other than dropping will cause UB
This is useful to obtain ownership of the inner value and implement a custom drop
(like a linked list iteratively dropped - VS
)