use std::sync::{
Arc,
Mutex,
};
use crate::lock::{
Lock,
TryLockError,
};
pub struct ArcStdMutex<T> {
inner: Arc<Mutex<T>>,
}
impl<T> ArcStdMutex<T> {
#[inline]
pub fn new(data: T) -> Self {
Self {
inner: Arc::new(Mutex::new(data)),
}
}
}
impl<T> Lock<T> for ArcStdMutex<T> {
#[inline]
fn read<R, F>(&self, f: F) -> R
where
F: FnOnce(&T) -> R,
{
let guard = self.inner.lock().unwrap();
f(&*guard)
}
#[inline]
fn write<R, F>(&self, f: F) -> R
where
F: FnOnce(&mut T) -> R,
{
let mut guard = self.inner.lock().unwrap();
f(&mut *guard)
}
#[inline]
fn try_read<R, F>(&self, f: F) -> Result<R, TryLockError>
where
F: FnOnce(&T) -> R,
{
match self.inner.try_lock() {
Ok(guard) => Ok(f(&*guard)),
Err(std::sync::TryLockError::WouldBlock) => Err(TryLockError::WouldBlock),
Err(std::sync::TryLockError::Poisoned(_)) => Err(TryLockError::Poisoned),
}
}
#[inline]
fn try_write<R, F>(&self, f: F) -> Result<R, TryLockError>
where
F: FnOnce(&mut T) -> R,
{
match self.inner.try_lock() {
Ok(mut guard) => Ok(f(&mut *guard)),
Err(std::sync::TryLockError::WouldBlock) => Err(TryLockError::WouldBlock),
Err(std::sync::TryLockError::Poisoned(_)) => Err(TryLockError::Poisoned),
}
}
}
impl<T> Clone for ArcStdMutex<T> {
#[inline]
fn clone(&self) -> Self {
Self {
inner: self.inner.clone(),
}
}
}