use crate::semaphore::Semaphore;
use core::{
cell::UnsafeCell,
ops::{Deref, DerefMut},
};
pub struct Mutex<T> {
data: UnsafeCell<T>,
semaphore: Semaphore,
}
impl<T> Mutex<T> {
pub const fn new(data: T) -> Self {
Self {
data: UnsafeCell::new(data),
semaphore: Semaphore::new(1),
}
}
pub async fn lock<'a>(&'a self) -> Guard<'a, T>
where
T: 'a,
{
self.semaphore.acquire(1).await;
Guard { mutex: self }
}
}
unsafe impl<T: Send> Send for Mutex<T> {}
unsafe impl<T: Send> Sync for Mutex<T> {}
pub struct Guard<'a, T> {
mutex: &'a Mutex<T>,
}
impl<T> Deref for Guard<'_, T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.mutex.data.get() }
}
}
impl<T> DerefMut for Guard<'_, T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe { &mut *self.mutex.data.get() }
}
}
impl<T> Drop for Guard<'_, T> {
fn drop(&mut self) {
self.mutex.semaphore.release(1);
}
}