use super::*;
use crate::semaphore;
use alloc::sync::Arc;
#[must_use = "if unused, the `RwLock` will immediately unlock"]
pub struct OwnedRwLockReadGuard<T: ?Sized> {
data: cell::ConstPtr<T>,
_lock: AddPermits<1, T>,
}
#[must_use = "if unused, the `RwLock` will immediately unlock"]
pub struct OwnedRwLockWriteGuard<T: ?Sized> {
data: cell::MutPtr<T>,
_lock: AddPermits<{ semaphore::MAX_PERMITS }, T>,
}
struct AddPermits<const PERMITS: usize, T: ?Sized>(Arc<RwLock<T>>);
impl<T: ?Sized> RwLock<T> {
pub async fn read_owned(self: &Arc<Self>) -> OwnedRwLockReadGuard<T> {
let guard = self.read().await;
OwnedRwLockReadGuard::from_borrowed(self.clone(), guard)
}
pub async fn write_owned(self: &Arc<Self>) -> OwnedRwLockWriteGuard<T> {
let guard = self.write().await;
OwnedRwLockWriteGuard::from_borrowed(self.clone(), guard)
}
pub fn try_read_owned(self: &Arc<Self>) -> Option<OwnedRwLockReadGuard<T>> {
self.try_read()
.map(|guard| OwnedRwLockReadGuard::from_borrowed(self.clone(), guard))
}
pub fn try_write_owned(self: &Arc<Self>) -> Option<OwnedRwLockWriteGuard<T>> {
self.try_write()
.map(|guard| OwnedRwLockWriteGuard::from_borrowed(self.clone(), guard))
}
}
impl<T: ?Sized> OwnedRwLockReadGuard<T> {
fn from_borrowed(
lock: Arc<RwLock<T>>,
RwLockReadGuard { data, _permit }: RwLockReadGuard<'_, T>,
) -> Self {
_permit.forget();
Self {
_lock: AddPermits(lock),
data,
}
}
}
impl<T: ?Sized> Deref for OwnedRwLockReadGuard<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe {
self.data.deref()
}
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedRwLockReadGuard<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.deref().fmt(f)
}
}
unsafe impl<T> Send for OwnedRwLockReadGuard<T> where T: ?Sized + Sync {}
unsafe impl<T> Sync for OwnedRwLockReadGuard<T> where T: ?Sized + Send + Sync {}
impl<T: ?Sized> OwnedRwLockWriteGuard<T> {
fn from_borrowed(
lock: Arc<RwLock<T>>,
RwLockWriteGuard { data, _permit }: RwLockWriteGuard<'_, T>,
) -> Self {
_permit.forget();
Self {
_lock: AddPermits(lock),
data,
}
}
}
impl<T: ?Sized> Deref for OwnedRwLockWriteGuard<T> {
type Target = T;
#[inline]
fn deref(&self) -> &Self::Target {
unsafe {
self.data.deref()
}
}
}
impl<T: ?Sized> DerefMut for OwnedRwLockWriteGuard<T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
unsafe {
self.data.deref()
}
}
}
impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedRwLockWriteGuard<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
self.deref().fmt(f)
}
}
unsafe impl<T> Send for OwnedRwLockWriteGuard<T> where T: ?Sized + Send + Sync {}
unsafe impl<T> Sync for OwnedRwLockWriteGuard<T> where T: ?Sized + Send + Sync {}
impl<const PERMITS: usize, T: ?Sized> Drop for AddPermits<PERMITS, T> {
fn drop(&mut self) {
self.0.sem.add_permits(PERMITS);
}
}