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;
const EXCLUSIVE: isize = -1; const UNLOCKED: isize = 0; const SHARED_ONCE: isize = 1;
pub struct RwLockReadGuard<T> {
guarder: Arc<InnerRwLock<T>>, }
impl<T> Deref for RwLockReadGuard<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe {
&*self.guarder.inner.get()
}
}
}
impl<T> Drop for RwLockReadGuard<T> {
fn drop(&mut self) {
if let Some(waker) = {
let mut status = self.guarder.status.lock();
if status.0 <= UNLOCKED {
panic!("Free shared lock failed, current: {:?}, reason: invalid current status", status.0);
} else if status.0 > SHARED_ONCE {
(&mut status).0 -= 1;
return;
} else {
(&mut status).0 = UNLOCKED;
status.2.pop_front()
}
} {
waker.wake();
}
}
}
pub struct RwLockWriteGuard<T> {
guarder: Arc<InnerRwLock<T>>, }
impl<T> Deref for RwLockWriteGuard<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe {
&*self.guarder.inner.get()
}
}
}
impl<T> DerefMut for RwLockWriteGuard<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
&mut *self.guarder.inner.get()
}
}
}
impl<T> Drop for RwLockWriteGuard<T> {
fn drop(&mut self) {
if let wakers = {
let mut status = self.guarder.status.lock();
(&mut status).0 = UNLOCKED;
let mut wakers = Vec::new();
if status.1.len() > 0 {
while let Some(waker) = status.1.pop_front() {
wakers.push(waker);
}
} else if status.2.len() > 0 {
if let Some(waker) = status.2.pop_front() {
wakers.push(waker);
}
} else {
return;
}
wakers
} {
for waker in wakers {
waker.wake();
}
}
}
}
pub struct RwLock<T> {
inner: Arc<InnerRwLock<T>>, }
unsafe impl<T> Send for RwLock<T> {}
unsafe impl<T> Sync for RwLock<T> {}
impl<T> RwLock<T> {
pub fn new(v: T) -> Self {
let inner = Arc::new(InnerRwLock {
status: SpinLock::new((UNLOCKED, VecDeque::new(), VecDeque::new())),
inner: UnsafeCell::new(v),
});
RwLock {
inner,
}
}
}
impl<T> RwLock<T> {
pub async fn read(&self) -> RwLockReadGuard<T> {
FutureShared {
inner: self.inner.clone(),
}.await
}
pub async fn write(&self) -> RwLockWriteGuard<T> {
FutureExclusive {
inner: self.inner.clone(),
}.await
}
}
struct InnerRwLock<T> {
status: SpinLock<(isize, VecDeque<Waker>, VecDeque<Waker>)>, inner: UnsafeCell<T>, }
unsafe impl<T> Send for InnerRwLock<T> {}
unsafe impl<T> Sync for InnerRwLock<T> {}
struct FutureShared<T> {
inner: Arc<InnerRwLock<T>>, }
impl<T> Future for FutureShared<T> {
type Output = RwLockReadGuard<T>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut status = self.inner.status.lock();
if status.0 >= UNLOCKED {
(&mut status).0 += 1; return Poll::Ready(RwLockReadGuard {
guarder: (&self).inner.clone()
});
}
status.1.push_back(cx.waker().clone());
Poll::Pending
}
}
struct FutureExclusive<T> {
inner: Arc<InnerRwLock<T>>, }
impl<T> Future for FutureExclusive<T> {
type Output = RwLockWriteGuard<T>;
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let mut status = self.inner.status.lock();
if status.0 == UNLOCKED {
(&mut status).0 = EXCLUSIVE;
return Poll::Ready(RwLockWriteGuard {
guarder: (&self).inner.clone()
});
}
status.2.push_back(cx.waker().clone());
Poll::Pending
}
}