Struct voluntary_servitude::atomics::AtomicOption
source · pub struct AtomicOption<T>(_, _);
Expand description
Atomic Option<Box<T>>
It can’t provide a reference to the current value since it may be dropped at any time
You must swap the element to access it
FillOnceAtomicOption
provides a API that enables access to the reference, but only enables try_store
to write to it
Implementations
sourceimpl<T> AtomicOption<T>
impl<T> AtomicOption<T>
sourcepub fn new<V>(value: V) -> Selfwhere
V: Into<Option<Box<T>>>,
pub fn new<V>(value: V) -> Selfwhere
V: Into<Option<Box<T>>>,
Creates new AtomicOption
let empty: AtomicOption<()> = AtomicOption::new(None);
assert!(empty.into_inner().is_none());
let filled = AtomicOption::new(Box::new(10));
assert_eq!(filled.into_inner().map(|a| *a), Some(10));
sourcepub fn try_store<V>(&self, new: V, order: Ordering) -> Result<(), NotEmpty>where
V: Into<Box<T>>,
pub fn try_store<V>(&self, new: V, order: Ordering) -> Result<(), NotEmpty>where
V: Into<Box<T>>,
Stores new value if AtomicOption
currently contains a None
This operation is implemented as a single atomic compare_and_swap
.
use std::sync::atomic::Ordering;
let option = AtomicOption::default();
let old = option.try_store(5, Ordering::SeqCst);
assert!(old.is_ok());
let failed_to_store = option.try_store(10, Ordering::SeqCst);
assert!(failed_to_store.is_err());
assert_eq!(option.into_inner().map(|a| *a), Some(5));
sourcepub fn store<V>(&self, new: V, order: Ordering)where
V: Into<Option<Box<T>>>,
pub fn store<V>(&self, new: V, order: Ordering)where
V: Into<Option<Box<T>>>,
Stores value into AtomicOption
and drops old one
use std::sync::atomic::Ordering;
let option: AtomicOption<u8> = AtomicOption::new(None);
option.store(Box::new(3), Ordering::SeqCst);
assert_eq!(option.into_inner().map(|a| *a), Some(3));
sourcepub fn swap<V>(&self, new: V, order: Ordering) -> Option<Box<T>>where
V: Into<Option<Box<T>>>,
pub fn swap<V>(&self, new: V, order: Ordering) -> Option<Box<T>>where
V: Into<Option<Box<T>>>,
Stores value into AtomicOption
returning old value
use std::sync::atomic::Ordering;
let option = AtomicOption::default();
assert_eq!(option.swap(Box::new(5), Ordering::SeqCst), None);
assert_eq!(option.swap(None, Ordering::SeqCst), Some(Box::new(5)));
sourcepub fn take(&self, order: Ordering) -> Option<Box<T>>
pub fn take(&self, order: Ordering) -> Option<Box<T>>
Replaces AtomicOption
value with None
returning old value
use std::sync::atomic::Ordering;
let option = AtomicOption::from(5);
assert_eq!(option.take(Ordering::SeqCst), Some(Box::new(5)));
assert_eq!(option.take(Ordering::SeqCst), None);
sourcepub unsafe fn atomic_ptr(&self) -> &AtomicPtr<T>
pub unsafe fn atomic_ptr(&self) -> &AtomicPtr<T>
Gives access to inner AtomicPtr
(AtomicOption
is an abstraction of it).
Safety
This is heavily unsafe.
It’s unsafe because you are responsible for making sure T
is not dropped nor replaced with a invalid pointer (or that will be invalidated while still stored).
use std::sync::atomic::Ordering;
let ten = AtomicOption::from(10);
assert_eq!(unsafe { &*ten.atomic_ptr().load(Ordering::SeqCst) }, &10);
sourcepub fn into_inner(self) -> Option<Box<T>>
pub fn into_inner(self) -> Option<Box<T>>
Converts itself into a Option<Box<T>>
let ten = AtomicOption::from(10);
assert_eq!(ten.into_inner().map(|a| *a), Some(10));
sourcepub unsafe fn from_raw(ptr: *mut T) -> Self
pub unsafe fn from_raw(ptr: *mut T) -> Self
Creates new AtomicOption
based on raw pointer
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
use std::ptr::null_mut;
let empty = unsafe { AtomicOption::<()>::from_raw(null_mut()) };
assert!(empty.into_inner().is_none());
let filled = unsafe { AtomicOption::from_raw(Box::into_raw(10.into())) };
assert_eq!(filled.into_inner().map(|a| *a), Some(10));
sourcepub fn get_raw(&self, order: Ordering) -> *mut T
pub fn get_raw(&self, order: Ordering) -> *mut T
Atomically extracts current pointer stored, 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
)
use std::{sync::atomic::Ordering, ptr::null_mut};
let empty: AtomicOption<()> = AtomicOption::new(None);
assert_eq!(empty.get_raw(Ordering::SeqCst), null_mut());
let ptr = Box::into_raw(10u8.into());
let filled = unsafe { AtomicOption::from_raw(ptr) };
assert_eq!(filled.get_raw(Ordering::SeqCst), ptr);
// You should probably never deref `ptr`
// You should probably never use this method
// UB will be everywhere, FillOnceAtomicOption is a safe an alternative
Trait Implementations
sourceimpl<T: Debug> Debug for AtomicOption<T>
impl<T: Debug> Debug for AtomicOption<T>
sourceimpl<T> Default for AtomicOption<T>
impl<T> Default for AtomicOption<T>
sourceimpl<T> Drop for AtomicOption<T>
impl<T> Drop for AtomicOption<T>
sourceimpl<T> From<Atomic<T>> for AtomicOption<T>
impl<T> From<Atomic<T>> for AtomicOption<T>
sourceimpl<T> From<AtomicOption<T>> for FillOnceAtomicOption<T>
impl<T> From<AtomicOption<T>> for FillOnceAtomicOption<T>
sourcefn from(atomic: AtomicOption<T>) -> Self
fn from(atomic: AtomicOption<T>) -> Self
sourceimpl<T> From<Box<T, Global>> for AtomicOption<T>
impl<T> From<Box<T, Global>> for AtomicOption<T>
sourceimpl<T> From<FillOnceAtomicOption<T>> for AtomicOption<T>
impl<T> From<FillOnceAtomicOption<T>> for AtomicOption<T>
sourcefn from(atomic: FillOnceAtomicOption<T>) -> Self
fn from(atomic: FillOnceAtomicOption<T>) -> Self
sourceimpl<T> From<Option<T>> for AtomicOption<T>
impl<T> From<Option<T>> for AtomicOption<T>
sourceimpl<T> From<T> for AtomicOption<T>
impl<T> From<T> for AtomicOption<T>
Auto Trait Implementations
impl<T> RefUnwindSafe for AtomicOption<T>where
T: RefUnwindSafe,
impl<T> Send for AtomicOption<T>where
T: Send,
impl<T> Sync for AtomicOption<T>where
T: Sync,
impl<T> Unpin for AtomicOption<T>
impl<T> UnwindSafe for AtomicOption<T>where
T: UnwindSafe + RefUnwindSafe,
Blanket Implementations
sourceimpl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
const: unstable · sourcefn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
sourceimpl<T> IntoSql for T
impl<T> IntoSql for T
sourcefn into_sql<T>(self) -> Self::Expressionwhere
Self: AsExpression<T> + Sized,
fn into_sql<T>(self) -> Self::Expressionwhere
Self: AsExpression<T> + Sized,
self
to an expression for Diesel’s query builder. Read moresourcefn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expressionwhere
&'a Self: AsExpression<T>,
fn as_sql<'a, T>(&'a self) -> <&'a Self as AsExpression<T>>::Expressionwhere
&'a Self: AsExpression<T>,
&self
to an expression for Diesel’s query builder. Read more