]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use std::marker::PhantomData; |
2 | use std::sync::atomic::{AtomicPtr, Ordering}; | |
3 | ||
4 | /// This is essentially an `AtomicPtr` but is guaranteed to always be valid | |
5 | pub struct AtomicRef<T: 'static>(AtomicPtr<T>, PhantomData<&'static T>); | |
6 | ||
7 | impl<T: 'static> AtomicRef<T> { | |
8 | pub const fn new(initial: &'static T) -> AtomicRef<T> { | |
9 | AtomicRef(AtomicPtr::new(initial as *const T as *mut T), PhantomData) | |
10 | } | |
11 | ||
12 | pub fn swap(&self, new: &'static T) -> &'static T { | |
13 | // We never allow storing anything but a `'static` reference so it's safe to | |
14 | // return it for the same. | |
15 | unsafe { &*self.0.swap(new as *const T as *mut T, Ordering::SeqCst) } | |
16 | } | |
17 | } | |
18 | ||
19 | impl<T: 'static> std::ops::Deref for AtomicRef<T> { | |
20 | type Target = T; | |
21 | fn deref(&self) -> &Self::Target { | |
22 | // We never allow storing anything but a `'static` reference so it's safe to lend | |
23 | // it out for any amount of time. | |
24 | unsafe { &*self.0.load(Ordering::SeqCst) } | |
25 | } | |
26 | } |