use parking_lot::RawRwLock;
pub type RwLock<T> = lock_api::RwLock<RawRwLock, T>;
pub type RwLockReadGuardDetached<'a> = detail::RwLockReadGuardDetached<'a, RawRwLock>;
pub type RwLockWriteGuardDetached<'a> = detail::RwLockWriteGuardDetached<'a, RawRwLock>;
mod detail {
use lock_api::{RawRwLock, RwLockReadGuard, RwLockWriteGuard};
use std::marker::PhantomData;
use std::mem::ManuallyDrop;
pub(crate) struct RwLockReadGuardDetached<'a, R: RawRwLock> {
lock: &'a R,
_marker: PhantomData<R::GuardMarker>,
}
impl<R: RawRwLock> Drop for RwLockReadGuardDetached<'_, R> {
fn drop(&mut self) {
unsafe {
self.lock.unlock_shared();
}
}
}
impl<'a, R: RawRwLock> RwLockReadGuardDetached<'a, R> {
pub(crate) unsafe fn detach_from<T>(guard: RwLockReadGuard<'a, R, T>) -> (Self, &'a T) {
let rwlock = RwLockReadGuard::rwlock(&ManuallyDrop::new(guard));
let data = unsafe { &*rwlock.data_ptr() };
let guard = RwLockReadGuardDetached {
lock: unsafe { rwlock.raw() },
_marker: PhantomData,
};
(guard, data)
}
}
pub(crate) struct RwLockWriteGuardDetached<'a, R: RawRwLock> {
lock: &'a R,
_marker: PhantomData<R::GuardMarker>,
}
impl<R: RawRwLock> Drop for RwLockWriteGuardDetached<'_, R> {
fn drop(&mut self) {
unsafe {
self.lock.unlock_exclusive();
}
}
}
impl<'a, R: RawRwLock> RwLockWriteGuardDetached<'a, R> {
pub(crate) unsafe fn detach_from<T>(
guard: RwLockWriteGuard<'a, R, T>,
) -> (Self, &'a mut T) {
let rwlock = RwLockWriteGuard::rwlock(&ManuallyDrop::new(guard));
let data = unsafe { &mut *rwlock.data_ptr() };
let guard = RwLockWriteGuardDetached {
lock: unsafe { rwlock.raw() },
_marker: PhantomData,
};
(guard, data)
}
}
}