arcswap.rs 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. use alloc::sync::Arc;
  2. use core::{
  3. fmt::{self, Debug, Formatter},
  4. ptr::NonNull,
  5. sync::atomic::{AtomicPtr, Ordering},
  6. };
  7. use pointers::BorrowedArc;
  8. unsafe impl<T> Send for ArcSwap<T> where T: Send + Sync {}
  9. unsafe impl<T> Sync for ArcSwap<T> where T: Send + Sync {}
  10. pub struct ArcSwap<T> {
  11. pointer: AtomicPtr<T>,
  12. }
  13. impl<T> ArcSwap<T> {
  14. pub fn new(data: T) -> Self {
  15. let pointer = Arc::into_raw(Arc::new(data));
  16. Self {
  17. pointer: AtomicPtr::new(pointer as *mut T),
  18. }
  19. }
  20. /// # Safety
  21. /// The caller must ensure that the pointer not used elsewhere before ACTUALLLY dropping that.
  22. pub fn swap(&self, data: Option<Arc<T>>) -> Option<Arc<T>> {
  23. let new_pointer = data.map(Arc::into_raw).unwrap_or(core::ptr::null());
  24. let old_pointer = self.pointer.swap(new_pointer as *mut _, Ordering::AcqRel);
  25. if old_pointer.is_null() {
  26. None
  27. } else {
  28. Some(unsafe { Arc::from_raw(old_pointer) })
  29. }
  30. }
  31. pub fn borrow(&self) -> BorrowedArc<T> {
  32. unsafe {
  33. BorrowedArc::from_raw(
  34. NonNull::new(self.pointer.load(Ordering::Acquire))
  35. .expect("ArcSwap: pointer should not be null."),
  36. )
  37. }
  38. }
  39. }
  40. impl<T> Debug for ArcSwap<T>
  41. where
  42. T: Debug,
  43. {
  44. fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  45. write!(f, "ArcSwap {{ {:?} }}", self.borrow().as_ref())
  46. }
  47. }