pub struct AtomicOption<T>(_, _);
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
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));
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::Relaxed);
assert!(old.is_ok());
let failed_to_store = option.try_store(10, Ordering::Relaxed);
assert!(failed_to_store.is_err());
assert_eq!(option.into_inner().map(|a| *a), Some(5));
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::Relaxed);
assert_eq!(option.into_inner().map(|a| *a), Some(3));
Stores value into AtomicOption
returning old value
use std::sync::atomic::Ordering;
let option = AtomicOption::default();
assert_eq!(option.swap(Box::new(5), Ordering::Relaxed), None);
assert_eq!(option.swap(None, Ordering::Relaxed), Some(Box::new(5)));
Replaces AtomicOption
value with None
returning old value
use std::sync::atomic::Ordering;
let option = AtomicOption::from(5);
assert_eq!(option.take(Ordering::Relaxed), Some(Box::new(5)));
assert_eq!(option.take(Ordering::Relaxed), None);
Gives access to inner AtomicPtr
(AtomicOption
is an abstraction of it).
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::Relaxed) }, &10);
Converts itself into a Option<Box<T>>
let ten = AtomicOption::from(10);
assert_eq!(ten.into_inner().map(|a| *a), Some(10));
Creates new AtomicOption
based on raw pointer
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));
Atomically extracts current pointer stored, this function should probably not be called
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::Relaxed), null_mut());
let ptr = Box::into_raw(10u8.into());
let filled = unsafe { AtomicOption::from_raw(ptr) };
assert_eq!(filled.get_raw(Ordering::Relaxed), ptr);
Executes the destructor for this type. Read more
Returns the "default value" for a type. Read more
Formats the value using the given formatter. Read more
Formats the value using the given formatter.
🔬 This is a nightly-only experimental API. (try_from
)
The type returned in the event of a conversion error.
🔬 This is a nightly-only experimental API. (try_from
)
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more
🔬 This is a nightly-only experimental API. (try_from
)
The type returned in the event of a conversion error.
🔬 This is a nightly-only experimental API. (try_from
)
🔬 This is a nightly-only experimental API. (get_type_id
)
this method will likely be replaced by an associated static