1use std::{mem, ops, sync::Arc};
2
3use parking_lot::RwLock;
4
5pub struct RwLockReadGuardOwned<T: 'static> {
7 lock: parking_lot::RwLockReadGuard<'static, T>,
8 _owned: Arc<RwLock<T>>,
9}
10impl<T> RwLockReadGuardOwned<T> {
11 pub fn lock(own: Arc<RwLock<T>>) -> Self {
15 Self {
16 lock: unsafe { mem::transmute::<parking_lot::RwLockReadGuard<'_, T>, parking_lot::RwLockReadGuard<'static, T>>(own.read()) },
18 _owned: own,
19 }
20 }
21
22 pub fn lock_recursive(own: Arc<RwLock<T>>) -> Self {
26 Self {
27 lock: unsafe {
29 mem::transmute::<parking_lot::RwLockReadGuard<'_, T>, parking_lot::RwLockReadGuard<'static, T>>(own.read_recursive())
30 },
31 _owned: own,
32 }
33 }
34
35 pub fn try_lock(own: Arc<RwLock<T>>) -> Option<Self> {
39 let lock = own.try_read()?;
40 Some(Self {
41 lock: unsafe { mem::transmute::<parking_lot::RwLockReadGuard<'_, T>, parking_lot::RwLockReadGuard<'static, T>>(lock) },
43 _owned: own,
44 })
45 }
46
47 pub fn try_lock_recursive(own: Arc<RwLock<T>>) -> Option<Self> {
51 let lock = own.try_read_recursive()?;
52 Some(Self {
53 lock: unsafe { mem::transmute::<parking_lot::RwLockReadGuard<'_, T>, parking_lot::RwLockReadGuard<'static, T>>(lock) },
55 _owned: own,
56 })
57 }
58
59 pub fn map<O>(guard: Self, map: impl FnOnce(&T) -> &O) -> MappedRwLockReadGuardOwned<T, O> {
65 MappedRwLockReadGuardOwned {
66 lock: parking_lot::RwLockReadGuard::map(guard.lock, map),
67 _owned: guard._owned,
68 }
69 }
70}
71impl<T> ops::Deref for RwLockReadGuardOwned<T> {
72 type Target = T;
73
74 fn deref(&self) -> &Self::Target {
75 self.lock.deref()
76 }
77}
78
79pub struct MappedRwLockReadGuardOwned<T: 'static, O: 'static> {
81 lock: parking_lot::MappedRwLockReadGuard<'static, O>,
82 _owned: Arc<RwLock<T>>,
83}
84impl<T, O> MappedRwLockReadGuardOwned<T, O> {
85 pub fn map<O2>(guard: Self, map: impl FnOnce(&O) -> &O2) -> MappedRwLockReadGuardOwned<T, O2> {
91 MappedRwLockReadGuardOwned {
92 lock: parking_lot::MappedRwLockReadGuard::map(guard.lock, map),
93 _owned: guard._owned,
94 }
95 }
96}
97impl<T, O> ops::Deref for MappedRwLockReadGuardOwned<T, O> {
98 type Target = O;
99
100 fn deref(&self) -> &Self::Target {
101 self.lock.deref()
102 }
103}
104
105pub struct RwLockWriteGuardOwned<T: 'static> {
107 lock: parking_lot::RwLockWriteGuard<'static, T>,
108 _owned: Arc<RwLock<T>>,
109}
110impl<T> RwLockWriteGuardOwned<T> {
111 pub fn lock(own: Arc<RwLock<T>>) -> Self {
115 Self {
116 lock: unsafe { mem::transmute::<parking_lot::RwLockWriteGuard<'_, T>, parking_lot::RwLockWriteGuard<'static, T>>(own.write()) },
118 _owned: own,
119 }
120 }
121
122 pub fn try_lock(own: Arc<RwLock<T>>) -> Option<Self> {
126 let lock = own.try_write()?;
127 Some(Self {
128 lock: unsafe { mem::transmute::<parking_lot::RwLockWriteGuard<'_, T>, parking_lot::RwLockWriteGuard<'static, T>>(lock) },
130 _owned: own,
131 })
132 }
133
134 pub fn map<O>(guard: Self, map: impl FnOnce(&mut T) -> &mut O) -> MappedRwLockWriteGuardOwned<T, O> {
140 MappedRwLockWriteGuardOwned {
141 lock: parking_lot::RwLockWriteGuard::map(guard.lock, map),
142 _owned: guard._owned,
143 }
144 }
145}
146impl<T> ops::Deref for RwLockWriteGuardOwned<T> {
147 type Target = T;
148
149 fn deref(&self) -> &Self::Target {
150 self.lock.deref()
151 }
152}
153impl<T> ops::DerefMut for RwLockWriteGuardOwned<T> {
154 fn deref_mut(&mut self) -> &mut Self::Target {
155 self.lock.deref_mut()
156 }
157}
158
159pub struct MappedRwLockWriteGuardOwned<T: 'static, O: 'static> {
161 lock: parking_lot::MappedRwLockWriteGuard<'static, O>,
162 _owned: Arc<RwLock<T>>,
163}
164impl<T, O> MappedRwLockWriteGuardOwned<T, O> {
165 pub fn map<O2>(guard: Self, map: impl FnOnce(&mut O) -> &mut O2) -> MappedRwLockWriteGuardOwned<T, O2> {
171 MappedRwLockWriteGuardOwned {
172 lock: parking_lot::MappedRwLockWriteGuard::map(guard.lock, map),
173 _owned: guard._owned,
174 }
175 }
176}
177impl<T, O> ops::Deref for MappedRwLockWriteGuardOwned<T, O> {
178 type Target = O;
179
180 fn deref(&self) -> &Self::Target {
181 self.lock.deref()
182 }
183}
184impl<T, O> ops::DerefMut for MappedRwLockWriteGuardOwned<T, O> {
185 fn deref_mut(&mut self) -> &mut Self::Target {
186 self.lock.deref_mut()
187 }
188}
189
190pub struct ReadOnlyRwLock<T>(Arc<RwLock<T>>);
192impl<T> Clone for ReadOnlyRwLock<T> {
193 fn clone(&self) -> Self {
194 Self(self.0.clone())
195 }
196}
197impl<T> ReadOnlyRwLock<T> {
198 pub fn new(l: Arc<RwLock<T>>) -> Self {
200 Self(l)
201 }
202
203 pub fn read(&self) -> parking_lot::RwLockReadGuard<'_, T> {
207 self.0.read()
208 }
209
210 pub fn read_recursive(&self) -> parking_lot::RwLockReadGuard<'_, T> {
217 self.0.read_recursive()
218 }
219
220 pub fn try_read(&self) -> Option<parking_lot::RwLockReadGuard<'_, T>> {
224 self.0.try_read()
225 }
226
227 pub fn try_read_recursive(&self) -> Option<parking_lot::RwLockReadGuard<'_, T>> {
231 self.0.try_read_recursive()
232 }
233
234 pub fn ptr_eq(&self, other: &Self) -> bool {
236 Arc::ptr_eq(&self.0, &other.0)
237 }
238}
239
240#[must_use = "cleanup runs on drop"]
242pub struct RunOnDrop<F: FnOnce()>(Option<F>);
243impl<F: FnOnce()> RunOnDrop<F> {
244 pub fn new(clean: F) -> Self {
246 RunOnDrop(Some(clean))
247 }
248}
249impl<F: FnOnce()> Drop for RunOnDrop<F> {
250 fn drop(&mut self) {
251 if let Some(clean) = self.0.take() {
252 clean();
253 }
254 }
255}
256
257pub(crate) fn panic_str<'s>(payload: &'s Box<dyn std::any::Any + Send + 'static>) -> &'s str {
258 if let Some(s) = payload.downcast_ref::<&str>() {
259 s
260 } else if let Some(s) = payload.downcast_ref::<String>() {
261 s
262 } else {
263 "<unknown-panic-message-type>"
264 }
265}