#[cfg(feature = "loom")]
pub(crate) use loom::sync::{
Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
};
#[cfg(all(feature = "parking_lot", not(feature = "loom")))]
pub(crate) use parking_lot::{
Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
};
#[cfg(not(any(feature = "parking_lot", feature = "loom")))]
pub(crate) use std::sync::{Condvar, Mutex, MutexGuard, RwLock, RwLockReadGuard, RwLockWriteGuard};
#[cfg(feature = "loom")]
#[inline(always)]
pub(crate) fn lock<T>(mutex: &Mutex<T>) -> MutexGuard<'_, T> {
mutex.lock().expect("loom mutex poisoned")
}
#[cfg(feature = "loom")]
#[inline(always)]
pub(crate) fn read<T>(lock: &RwLock<T>) -> RwLockReadGuard<'_, T> {
lock.read().expect("loom rwlock poisoned")
}
#[cfg(all(feature = "parking_lot", not(feature = "loom")))]
#[allow(dead_code)]
#[inline(always)]
pub(crate) fn read<T>(lock: &RwLock<T>) -> RwLockReadGuard<'_, T> {
lock.read()
}
#[cfg(not(any(feature = "parking_lot", feature = "loom")))]
#[inline(always)]
pub(crate) fn read<T>(lock: &RwLock<T>) -> RwLockReadGuard<'_, T> {
lock.read().unwrap_or_else(|poisoned| poisoned.into_inner())
}
#[cfg(feature = "loom")]
#[inline(always)]
pub(crate) fn write<T>(lock: &RwLock<T>) -> RwLockWriteGuard<'_, T> {
lock.write().expect("loom rwlock poisoned")
}
#[cfg(all(feature = "parking_lot", not(feature = "loom")))]
#[allow(dead_code)]
#[inline(always)]
pub(crate) fn write<T>(lock: &RwLock<T>) -> RwLockWriteGuard<'_, T> {
lock.write()
}
#[cfg(not(any(feature = "parking_lot", feature = "loom")))]
#[inline(always)]
pub(crate) fn write<T>(lock: &RwLock<T>) -> RwLockWriteGuard<'_, T> {
lock.write()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}
#[cfg(all(feature = "parking_lot", not(feature = "loom")))]
#[inline(always)]
pub(crate) fn lock<T>(mutex: &Mutex<T>) -> MutexGuard<'_, T> {
mutex.lock()
}
#[cfg(not(any(feature = "parking_lot", feature = "loom")))]
#[inline(always)]
pub(crate) fn lock<T>(mutex: &Mutex<T>) -> MutexGuard<'_, T> {
mutex.lock().unwrap_or_else(|e| e.into_inner())
}
#[cfg(all(test, feature = "parking_lot", not(feature = "loom")))]
#[inline(always)]
pub(crate) fn try_lock<T>(mutex: &Mutex<T>) -> Option<MutexGuard<'_, T>> {
mutex.try_lock()
}
#[cfg(all(test, feature = "loom"))]
#[inline(always)]
pub(crate) fn try_lock<T>(mutex: &Mutex<T>) -> Option<MutexGuard<'_, T>> {
match mutex.try_lock() {
Ok(guard) => Some(guard),
Err(std::sync::TryLockError::WouldBlock) => None,
Err(std::sync::TryLockError::Poisoned(error)) => {
panic!("loom mutex poisoned: {error}")
}
}
}
#[cfg(all(test, not(any(feature = "parking_lot", feature = "loom"))))]
#[inline(always)]
pub(crate) fn try_lock<T>(mutex: &Mutex<T>) -> Option<MutexGuard<'_, T>> {
match mutex.try_lock() {
Ok(guard) => Some(guard),
Err(std::sync::TryLockError::Poisoned(error)) => Some(error.into_inner()),
Err(std::sync::TryLockError::WouldBlock) => None,
}
}
#[cfg(all(feature = "parking_lot", not(feature = "loom")))]
#[inline(always)]
pub(crate) fn cv_wait<'a, T>(cv: &Condvar, mut guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> {
cv.wait(&mut guard);
guard
}
#[cfg(feature = "loom")]
#[inline(always)]
pub(crate) fn cv_wait<'a, T>(cv: &Condvar, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> {
cv.wait(guard).expect("loom mutex poisoned")
}
#[cfg(not(any(feature = "parking_lot", feature = "loom")))]
#[inline(always)]
pub(crate) fn cv_wait<'a, T>(cv: &Condvar, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T> {
cv.wait(guard).unwrap_or_else(|e| e.into_inner())
}
#[cfg(all(feature = "parking_lot", not(feature = "loom")))]
#[inline(always)]
pub(crate) fn cv_wait_timeout<'a, T>(
cv: &Condvar,
_mutex: &'a Mutex<T>,
mut guard: MutexGuard<'a, T>,
timeout: std::time::Duration,
) -> MutexGuard<'a, T> {
cv.wait_for(&mut guard, timeout);
guard
}
#[cfg(feature = "loom")]
#[inline(always)]
pub(crate) fn cv_wait_timeout<'a, T>(
_cv: &Condvar,
mutex: &'a Mutex<T>,
guard: MutexGuard<'a, T>,
_timeout: std::time::Duration,
) -> MutexGuard<'a, T> {
drop(guard);
loom::thread::yield_now();
lock(mutex)
}
#[cfg(not(any(feature = "parking_lot", feature = "loom")))]
#[inline(always)]
pub(crate) fn cv_wait_timeout<'a, T>(
cv: &Condvar,
_mutex: &'a Mutex<T>,
guard: MutexGuard<'a, T>,
timeout: std::time::Duration,
) -> MutexGuard<'a, T> {
cv.wait_timeout(guard, timeout)
.unwrap_or_else(|e| e.into_inner())
.0
}