use core::cell::UnsafeCell; use core::ops::{Deref, DerefMut}; use core::sync::atomic::{AtomicBool, Ordering}; pub struct Worm { inner: UnsafeCell, active: AtomicBool, } unsafe impl Sync for Worm {} pub struct WormWriter<'a, T: 'a>(&'a Worm); impl<'a, T: 'a> Drop for WormWriter<'a, T> { fn drop(&mut self) { self.0.active.store(false, Ordering::Relaxed); } } impl<'a, T: 'a> Deref for WormWriter<'a, T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.0.inner.get() } } } impl<'a, T: 'a> DerefMut for WormWriter<'a, T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.0.inner.get() } } } impl Worm { pub const fn new(inner: T) -> Self { Self { inner: UnsafeCell::new(inner), active: AtomicBool::new(false), } } pub unsafe fn lock(&self) -> WormWriter<'_, T> { if self.active.swap(true, Ordering::Relaxed) { panic!("worm is locked"); } WormWriter(self) } pub unsafe fn force_unlock(&self) { self.active.store(false, Ordering::Relaxed); } pub fn is_locked(&self) -> bool { self.active.load(Ordering::Relaxed) } } impl Deref for Worm { type Target = T; fn deref(&self) -> &Self::Target { if self.active.load(Ordering::Relaxed) { panic!("worm is locked"); } unsafe { &*self.inner.get() } } }