lifeblood_os/src/worm.rs
2025-09-08 20:56:44 -07:00

66 lines
1.4 KiB
Rust

use core::cell::UnsafeCell;
use core::ops::{Deref, DerefMut};
use core::sync::atomic::{AtomicBool, Ordering};
pub struct Worm<T> {
inner: UnsafeCell<T>,
active: AtomicBool,
}
unsafe impl<T> Sync for Worm<T> {}
pub struct WormWriter<'a, T: 'a>(&'a Worm<T>);
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<T> Worm<T> {
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<T> Deref for Worm<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
if self.active.load(Ordering::Relaxed) {
panic!("worm is locked");
}
unsafe { &*self.inner.get() }
}
}