use crate::lib::*;
#[cfg(feature = "std")]
use parking_lot::Mutex;
#[cfg(not(feature = "std"))]
use spin::Mutex;
#[derive(Clone)]
pub(crate) struct ThreadsafeWrapper<T>
where
T: fmt::Debug + Default + Clone + PartialEq + Eq,
{
data: Arc<Mutex<T>>,
}
impl<T> Default for ThreadsafeWrapper<T>
where
T: fmt::Debug + Default + Clone + PartialEq + Eq,
{
fn default() -> Self {
ThreadsafeWrapper {
data: Arc::new(Mutex::new(T::default())),
}
}
}
impl<T> PartialEq<Self> for ThreadsafeWrapper<T>
where
T: fmt::Debug + Default + Clone + PartialEq + Eq,
{
fn eq(&self, other: &Self) -> bool {
let mine = self.data.lock();
let other = other.data.lock();
*other == *mine
}
}
impl<T> Eq for ThreadsafeWrapper<T> where T: fmt::Debug + Default + Clone + PartialEq + Eq {}
impl<T> fmt::Debug for ThreadsafeWrapper<T>
where
T: fmt::Debug + Default + Clone + PartialEq + Eq,
{
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
let data = self.data.lock();
data.fmt(f)
}
}
#[cfg(feature = "std")]
mod std {
use super::*;
use evmap::ShallowCopy;
impl<T> ShallowCopy for ThreadsafeWrapper<T>
where
T: fmt::Debug + Default + Clone + PartialEq + Eq,
{
unsafe fn shallow_copy(&mut self) -> Self {
ThreadsafeWrapper {
data: self.data.shallow_copy(),
}
}
}
}
impl<T> ThreadsafeWrapper<T>
where
T: fmt::Debug + Default + Clone + PartialEq + Eq,
{
#[inline]
pub(crate) fn measure_and_replace<F, E>(&self, f: F) -> Result<(), E>
where
F: Fn(&T) -> (Result<(), E>, Option<T>),
{
let mut data = self.data.lock();
let (decision, new_data) = f(&*data);
if let Some(new_data) = new_data {
*data = new_data;
}
decision
}
pub(crate) fn snapshot(&self) -> T {
let data = self.data.lock();
data.clone()
}
}