use std::{mem, ops, sync::Arc};
use parking_lot::RwLock;
pub struct RwLockReadGuardOwned<T: 'static> {
lock: parking_lot::RwLockReadGuard<'static, T>,
_owned: Arc<RwLock<T>>,
}
impl<T> RwLockReadGuardOwned<T> {
pub fn lock(own: Arc<RwLock<T>>) -> Self {
Self {
lock: unsafe { mem::transmute::<parking_lot::RwLockReadGuard<'_, T>, parking_lot::RwLockReadGuard<'static, T>>(own.read()) },
_owned: own,
}
}
pub fn lock_recursive(own: Arc<RwLock<T>>) -> Self {
Self {
lock: unsafe {
mem::transmute::<parking_lot::RwLockReadGuard<'_, T>, parking_lot::RwLockReadGuard<'static, T>>(own.read_recursive())
},
_owned: own,
}
}
pub fn try_lock(own: Arc<RwLock<T>>) -> Option<Self> {
let lock = own.try_read()?;
Some(Self {
lock: unsafe { mem::transmute::<parking_lot::RwLockReadGuard<'_, T>, parking_lot::RwLockReadGuard<'static, T>>(lock) },
_owned: own,
})
}
pub fn try_lock_recursive(own: Arc<RwLock<T>>) -> Option<Self> {
let lock = own.try_read_recursive()?;
Some(Self {
lock: unsafe { mem::transmute::<parking_lot::RwLockReadGuard<'_, T>, parking_lot::RwLockReadGuard<'static, T>>(lock) },
_owned: own,
})
}
pub fn map<O>(guard: Self, map: impl FnOnce(&T) -> &O) -> MappedRwLockReadGuardOwned<T, O> {
MappedRwLockReadGuardOwned {
lock: parking_lot::RwLockReadGuard::map(guard.lock, map),
_owned: guard._owned,
}
}
}
impl<T> ops::Deref for RwLockReadGuardOwned<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.lock.deref()
}
}
pub struct MappedRwLockReadGuardOwned<T: 'static, O: 'static> {
lock: parking_lot::MappedRwLockReadGuard<'static, O>,
_owned: Arc<RwLock<T>>,
}
impl<T, O> MappedRwLockReadGuardOwned<T, O> {
pub fn map<O2>(guard: Self, map: impl FnOnce(&O) -> &O2) -> MappedRwLockReadGuardOwned<T, O2> {
MappedRwLockReadGuardOwned {
lock: parking_lot::MappedRwLockReadGuard::map(guard.lock, map),
_owned: guard._owned,
}
}
}
impl<T, O> ops::Deref for MappedRwLockReadGuardOwned<T, O> {
type Target = O;
fn deref(&self) -> &Self::Target {
self.lock.deref()
}
}
pub struct RwLockWriteGuardOwned<T: 'static> {
lock: parking_lot::RwLockWriteGuard<'static, T>,
_owned: Arc<RwLock<T>>,
}
impl<T> RwLockWriteGuardOwned<T> {
pub fn lock(own: Arc<RwLock<T>>) -> Self {
Self {
lock: unsafe { mem::transmute::<parking_lot::RwLockWriteGuard<'_, T>, parking_lot::RwLockWriteGuard<'static, T>>(own.write()) },
_owned: own,
}
}
pub fn try_lock(own: Arc<RwLock<T>>) -> Option<Self> {
let lock = own.try_write()?;
Some(Self {
lock: unsafe { mem::transmute::<parking_lot::RwLockWriteGuard<'_, T>, parking_lot::RwLockWriteGuard<'static, T>>(lock) },
_owned: own,
})
}
pub fn map<O>(guard: Self, map: impl FnOnce(&mut T) -> &mut O) -> MappedRwLockWriteGuardOwned<T, O> {
MappedRwLockWriteGuardOwned {
lock: parking_lot::RwLockWriteGuard::map(guard.lock, map),
_owned: guard._owned,
}
}
}
impl<T> ops::Deref for RwLockWriteGuardOwned<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
self.lock.deref()
}
}
impl<T> ops::DerefMut for RwLockWriteGuardOwned<T> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.lock.deref_mut()
}
}
pub struct MappedRwLockWriteGuardOwned<T: 'static, O: 'static> {
lock: parking_lot::MappedRwLockWriteGuard<'static, O>,
_owned: Arc<RwLock<T>>,
}
impl<T, O> MappedRwLockWriteGuardOwned<T, O> {
pub fn map<O2>(guard: Self, map: impl FnOnce(&mut O) -> &mut O2) -> MappedRwLockWriteGuardOwned<T, O2> {
MappedRwLockWriteGuardOwned {
lock: parking_lot::MappedRwLockWriteGuard::map(guard.lock, map),
_owned: guard._owned,
}
}
}
impl<T, O> ops::Deref for MappedRwLockWriteGuardOwned<T, O> {
type Target = O;
fn deref(&self) -> &Self::Target {
self.lock.deref()
}
}
impl<T, O> ops::DerefMut for MappedRwLockWriteGuardOwned<T, O> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.lock.deref_mut()
}
}
pub struct ReadOnlyRwLock<T>(Arc<RwLock<T>>);
impl<T> Clone for ReadOnlyRwLock<T> {
fn clone(&self) -> Self {
Self(self.0.clone())
}
}
impl<T> ReadOnlyRwLock<T> {
pub fn new(l: Arc<RwLock<T>>) -> Self {
Self(l)
}
pub fn read(&self) -> parking_lot::RwLockReadGuard<'_, T> {
self.0.read()
}
pub fn read_recursive(&self) -> parking_lot::RwLockReadGuard<'_, T> {
self.0.read_recursive()
}
pub fn try_read(&self) -> Option<parking_lot::RwLockReadGuard<'_, T>> {
self.0.try_read()
}
pub fn try_read_recursive(&self) -> Option<parking_lot::RwLockReadGuard<'_, T>> {
self.0.try_read_recursive()
}
pub fn ptr_eq(&self, other: &Self) -> bool {
Arc::ptr_eq(&self.0, &other.0)
}
}
pub struct RunOnDrop<F: FnOnce()>(Option<F>);
impl<F: FnOnce()> RunOnDrop<F> {
pub fn new(clean: F) -> Self {
RunOnDrop(Some(clean))
}
}
impl<F: FnOnce()> Drop for RunOnDrop<F> {
fn drop(&mut self) {
if let Some(clean) = self.0.take() {
clean();
}
}
}
pub(crate) fn panic_str<'s>(payload: &'s Box<dyn std::any::Any + Send + 'static>) -> &'s str {
if let Some(s) = payload.downcast_ref::<&str>() {
s
} else if let Some(s) = payload.downcast_ref::<String>() {
s
} else {
"<unknown-panic-message-type>"
}
}