use super::Sel;
use std::{
os::raw::c_void,
ptr::{self, NonNull},
sync::atomic::{AtomicPtr, Ordering},
};
#[repr(transparent)]
pub(crate) struct AtomicSel(AtomicPtr<c_void>);
impl AtomicSel {
#[inline]
pub const fn null() -> Self {
Self(AtomicPtr::new(ptr::null_mut()))
}
#[inline]
pub fn load_or_store_with<F>(&self, make_sel: F) -> Sel
where
F: FnOnce() -> Sel,
{
if let Some(ptr) = NonNull::new(self.0.load(Ordering::Relaxed)) {
unsafe { Sel::from_non_null_ptr(ptr) }
} else {
let selector = make_sel();
self.0.store(selector.as_ptr() as _, Ordering::Relaxed);
selector
}
}
}