wgpu_core/lock/
vanilla.rs

1//! Plain, uninstrumented wrappers around [`parking_lot`] lock types.
2//!
3//! These definitions are used when no particular lock instrumentation
4//! Cargo feature is selected.
5
6use core::{fmt, ops};
7
8/// A plain wrapper around [`parking_lot::Mutex`].
9///
10/// This is just like [`parking_lot::Mutex`], except that our [`new`]
11/// method takes a rank, indicating where the new mutex should sit in
12/// `wgpu-core`'s lock ordering. The rank is ignored.
13///
14/// See the [`lock`] module documentation for other wrappers.
15///
16/// [`new`]: Mutex::new
17/// [`lock`]: crate::lock
18pub struct Mutex<T>(parking_lot::Mutex<T>);
19
20/// A guard produced by locking [`Mutex`].
21///
22/// This is just a wrapper around a [`parking_lot::MutexGuard`].
23pub struct MutexGuard<'a, T>(parking_lot::MutexGuard<'a, T>);
24
25impl<T> Mutex<T> {
26    pub fn new(_rank: super::rank::LockRank, value: T) -> Mutex<T> {
27        Mutex(parking_lot::Mutex::new(value))
28    }
29
30    pub fn lock(&self) -> MutexGuard<T> {
31        MutexGuard(self.0.lock())
32    }
33
34    pub fn into_inner(self) -> T {
35        self.0.into_inner()
36    }
37}
38
39impl<'a, T> ops::Deref for MutexGuard<'a, T> {
40    type Target = T;
41
42    fn deref(&self) -> &Self::Target {
43        self.0.deref()
44    }
45}
46
47impl<'a, T> ops::DerefMut for MutexGuard<'a, T> {
48    fn deref_mut(&mut self) -> &mut Self::Target {
49        self.0.deref_mut()
50    }
51}
52
53impl<T: fmt::Debug> fmt::Debug for Mutex<T> {
54    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55        self.0.fmt(f)
56    }
57}
58
59/// A plain wrapper around [`parking_lot::RwLock`].
60///
61/// This is just like [`parking_lot::RwLock`], except that our [`new`]
62/// method takes a rank, indicating where the new mutex should sit in
63/// `wgpu-core`'s lock ordering. The rank is ignored.
64///
65/// See the [`lock`] module documentation for other wrappers.
66///
67/// [`new`]: RwLock::new
68/// [`lock`]: crate::lock
69pub struct RwLock<T>(parking_lot::RwLock<T>);
70
71/// A read guard produced by locking [`RwLock`] as a reader.
72///
73/// This is just a wrapper around a [`parking_lot::RwLockReadGuard`].
74pub struct RwLockReadGuard<'a, T>(parking_lot::RwLockReadGuard<'a, T>);
75
76/// A write guard produced by locking [`RwLock`] as a writer.
77///
78/// This is just a wrapper around a [`parking_lot::RwLockWriteGuard`].
79pub struct RwLockWriteGuard<'a, T>(parking_lot::RwLockWriteGuard<'a, T>);
80
81impl<T> RwLock<T> {
82    pub fn new(_rank: super::rank::LockRank, value: T) -> RwLock<T> {
83        RwLock(parking_lot::RwLock::new(value))
84    }
85
86    pub fn read(&self) -> RwLockReadGuard<T> {
87        RwLockReadGuard(self.0.read())
88    }
89
90    pub fn write(&self) -> RwLockWriteGuard<T> {
91        RwLockWriteGuard(self.0.write())
92    }
93}
94
95impl<'a, T> RwLockWriteGuard<'a, T> {
96    pub fn downgrade(this: Self) -> RwLockReadGuard<'a, T> {
97        RwLockReadGuard(parking_lot::RwLockWriteGuard::downgrade(this.0))
98    }
99}
100
101impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
102    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
103        self.0.fmt(f)
104    }
105}
106
107impl<'a, T> ops::Deref for RwLockReadGuard<'a, T> {
108    type Target = T;
109
110    fn deref(&self) -> &Self::Target {
111        self.0.deref()
112    }
113}
114
115impl<'a, T> ops::Deref for RwLockWriteGuard<'a, T> {
116    type Target = T;
117
118    fn deref(&self) -> &Self::Target {
119        self.0.deref()
120    }
121}
122
123impl<'a, T> ops::DerefMut for RwLockWriteGuard<'a, T> {
124    fn deref_mut(&mut self) -> &mut Self::Target {
125        self.0.deref_mut()
126    }
127}