#[cfg(all(feature = "parking_lot", not(target_arch = "wasm32")))]
pub use parking_lot::RwLock;
#[cfg(all(feature = "parking_lot", not(target_arch = "wasm32")))]
pub use parking_lot::RwLockReadGuard;
#[cfg(all(feature = "parking_lot", not(target_arch = "wasm32")))]
pub use parking_lot::RwLockWriteGuard;
#[cfg(any(not(feature = "parking_lot"), target_arch = "wasm32"))]
#[derive(Debug, Default)]
pub struct RwLock<T>(std::sync::RwLock<T>);
#[cfg(any(not(feature = "parking_lot"), target_arch = "wasm32"))]
impl<T> RwLock<T> {
#[inline]
pub const fn new(value: T) -> Self {
RwLock(std::sync::RwLock::new(value))
}
#[inline]
pub fn read(&self) -> std::sync::RwLockReadGuard<'_, T> {
self.0.read().expect("RwLock poisoned")
}
#[inline]
pub fn write(&self) -> std::sync::RwLockWriteGuard<'_, T> {
self.0.write().expect("RwLock poisoned")
}
#[inline]
pub fn try_read(&self) -> Option<std::sync::RwLockReadGuard<'_, T>> {
self.0.try_read().ok()
}
#[inline]
pub fn try_write(&self) -> Option<std::sync::RwLockWriteGuard<'_, T>> {
self.0.try_write().ok()
}
#[inline]
pub fn get_mut(&mut self) -> &mut T {
self.0.get_mut().expect("RwLock poisoned")
}
#[inline]
pub fn into_inner(self) -> T {
self.0.into_inner().expect("RwLock poisoned")
}
}
#[cfg(any(not(feature = "parking_lot"), target_arch = "wasm32"))]
pub use std::sync::RwLockReadGuard;
#[cfg(any(not(feature = "parking_lot"), target_arch = "wasm32"))]
pub use std::sync::RwLockWriteGuard;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rwlock_read() {
let lock = RwLock::new(42);
let value = lock.read();
assert_eq!(*value, 42);
}
#[test]
fn test_rwlock_write() {
let lock = RwLock::new(42);
{
let mut value = lock.write();
*value = 100;
}
let value = lock.read();
assert_eq!(*value, 100);
}
#[test]
fn test_rwlock_multiple_readers() {
let lock = RwLock::new(42);
let r1 = lock.read();
assert_eq!(*r1, 42);
}
#[test]
fn test_rwlock_get_mut() {
let mut lock = RwLock::new(42);
*lock.get_mut() = 100;
assert_eq!(*lock.read(), 100);
}
#[test]
fn test_rwlock_into_inner() {
let lock = RwLock::new(42);
assert_eq!(lock.into_inner(), 42);
}
#[test]
fn test_rwlock_try_read_succeeds_when_unlocked() {
let lock = RwLock::new(42);
let guard = lock
.try_read()
.expect("uncontended try_read should succeed");
assert_eq!(*guard, 42);
}
#[test]
fn test_rwlock_try_write_succeeds_when_unlocked() {
let lock = RwLock::new(42);
{
let mut guard = lock
.try_write()
.expect("uncontended try_write should succeed");
*guard = 100;
}
assert_eq!(*lock.read(), 100);
}
}