1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
use std::ops::{Deref, DerefMut};
use std::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard, TryLockError};
use crate::type_name::TypeName;
#[derive(Debug, Default)]
pub struct Lock<Value>
where
Value: TypeName,
{
inner: RwLock<Value>,
}
impl<Value> Lock<Value>
where
Value: TypeName,
{
pub fn new(value: Value) -> Self
{
Self { inner: RwLock::new(value) }
}
pub fn read_nonblock(&self) -> Result<ReadGuard<Value>, Error>
{
let guard = self.inner.try_read().or_else(|err| match err {
TryLockError::WouldBlock => Err(Error::Unavailable),
TryLockError::Poisoned(poison_err) => Ok(poison_err.into_inner()),
})?;
#[cfg(feature = "debug")]
tracing::trace!("Acquired lock to value of type {}", guard.type_name());
Ok(ReadGuard { inner: guard })
}
pub fn write_nonblock(&self) -> Result<WriteGuard<Value>, Error>
{
let guard = self.inner.try_write().or_else(|err| match err {
TryLockError::WouldBlock => Err(Error::Unavailable),
TryLockError::Poisoned(poison_err) => Ok(poison_err.into_inner()),
})?;
#[cfg(feature = "debug")]
tracing::trace!(
"Acquired mutable lock to value of type {}",
guard.type_name()
);
Ok(WriteGuard { inner: guard })
}
}
#[derive(Debug, thiserror::Error)]
pub enum Error
{
#[error("Lock is unavailable")]
Unavailable,
}
#[derive(Debug)]
pub struct ReadGuard<'guard, Value>
where
Value: TypeName,
{
inner: RwLockReadGuard<'guard, Value>,
}
impl<'guard, Value> Deref for ReadGuard<'guard, Value>
where
Value: TypeName,
{
type Target = Value;
fn deref(&self) -> &Self::Target
{
&self.inner
}
}
impl<'guard, Value> Drop for ReadGuard<'guard, Value>
where
Value: TypeName,
{
fn drop(&mut self)
{
#[cfg(feature = "debug")]
tracing::trace!("Dropped lock to value of type {}", self.type_name());
}
}
#[derive(Debug)]
pub struct WriteGuard<'guard, Value>
where
Value: TypeName,
{
inner: RwLockWriteGuard<'guard, Value>,
}
impl<'guard, Value> Deref for WriteGuard<'guard, Value>
where
Value: TypeName,
{
type Target = Value;
fn deref(&self) -> &Self::Target
{
&self.inner
}
}
impl<'guard, Value> DerefMut for WriteGuard<'guard, Value>
where
Value: TypeName,
{
fn deref_mut(&mut self) -> &mut Self::Target
{
&mut self.inner
}
}
impl<'guard, Value> Drop for WriteGuard<'guard, Value>
where
Value: TypeName,
{
fn drop(&mut self)
{
#[cfg(feature = "debug")]
tracing::trace!("Dropped mutable lock to value of type {}", self.type_name());
}
}
|