use std::pin::Pin;
use std::sync::Arc;
use std::future::Future;
use std::cell::UnsafeCell;
use std::collections::VecDeque;
use std::ops::{Deref, DerefMut};
use std::task::{Waker, Context, Poll};
use super::spin_lock::SpinLock;
pub struct MutexGuard<T> {
guarder: Arc<InnerMutex<T>>, }
impl<T> Deref for MutexGuard<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe {
&*self.guarder.inner.get()
}
}
}
impl<T> DerefMut for MutexGuard<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
&mut *self.guarder.inner.get()
}
}
}
impl<T> Drop for MutexGuard<T> {
fn drop(&mut self) {
if let Some(waker) = {
let mut status = self.guarder.status.lock();
(&mut status).0 = true;
status.1.pop_front()
} {
waker.wake();
}
}
}
pub struct Mutex<T> {
inner: Arc<InnerMutex<T>>, }
unsafe impl<T> Send for Mutex<T> {}
unsafe impl<T> Sync for Mutex<T> {}
impl<T> Mutex<T> {
pub fn new(v: T) -> Self {
let inner = Arc::new(InnerMutex {
status: SpinLock::new((true, VecDeque::new())),
inner: UnsafeCell::new(v),
});
Mutex {
inner,
}
}
}
impl<T> Mutex<T> {
pub async fn lock(&self) -> MutexGuard<T> {
FutureMutex {
inner: self.inner.clone(),
}.await
}
}
struct InnerMutex<T> {
status: SpinLock<(bool, VecDeque<Waker>)>, inner: UnsafeCell<T>, }
unsafe impl<T> Send for InnerMutex<T> {}
unsafe impl<T> Sync for InnerMutex<T> {}
struct FutureMutex<T> {
inner: Arc<InnerMutex<T>>, }
impl<T> Future for FutureMutex<T> {
type Output = MutexGuard<T>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut status = self.inner.status.lock();
if status.0 {
(&mut status).0 = false;
return Poll::Ready(MutexGuard {
guarder: (&self).inner.clone()
});
}
status.1.push_back(cx.waker().clone());
Poll::Pending
}
}