Skip to main content

wgpu_core/lock/
vanilla.rs

1//! Plain, uninstrumented wrappers around [`wgpu_sync`] lock types.
2//!
3//! These definitions are used when no particular lock instrumentation
4//! Cargo feature is selected.
5
6use core::{fmt, ops};
7
8use crate::lock::rank::LockRank;
9
10pub struct RankData;
11
12/// A plain wrapper around [`wgpu_sync::Mutex`].
13///
14/// This is just like [`wgpu_sync::Mutex`], except that our [`new`]
15/// method takes a rank, indicating where the new mutex should sit in
16/// `wgpu-core`'s lock ordering. The rank is ignored.
17///
18/// See the [`lock`] module documentation for other wrappers.
19///
20/// [`new`]: Mutex::new
21/// [`lock`]: crate::lock
22pub struct Mutex<T>(wgpu_sync::Mutex<T>);
23
24/// A guard produced by locking [`Mutex`].
25///
26/// This is just a wrapper around a [`wgpu_sync::MutexGuard`].
27pub struct MutexGuard<'a, T>(wgpu_sync::MutexGuard<'a, T>);
28
29impl<T> Mutex<T> {
30    pub fn new(_rank: LockRank, value: T) -> Mutex<T> {
31        Mutex(wgpu_sync::Mutex::new(value))
32    }
33
34    pub fn lock(&self) -> MutexGuard<'_, T> {
35        MutexGuard(self.0.lock())
36    }
37
38    pub fn into_inner(self) -> T {
39        self.0.into_inner()
40    }
41}
42
43impl<'a, T> ops::Deref for MutexGuard<'a, T> {
44    type Target = T;
45
46    fn deref(&self) -> &Self::Target {
47        self.0.deref()
48    }
49}
50
51impl<'a, T> ops::DerefMut for MutexGuard<'a, T> {
52    fn deref_mut(&mut self) -> &mut Self::Target {
53        self.0.deref_mut()
54    }
55}
56
57impl<T: fmt::Debug> fmt::Debug for Mutex<T> {
58    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
59        self.0.fmt(f)
60    }
61}
62
63/// A plain wrapper around [`wgpu_sync::RwLock`].
64///
65/// This is just like [`wgpu_sync::RwLock`], except that our [`new`]
66/// method takes a rank, indicating where the new mutex should sit in
67/// `wgpu-core`'s lock ordering. The rank is ignored.
68///
69/// See the [`lock`] module documentation for other wrappers.
70///
71/// [`new`]: RwLock::new
72/// [`lock`]: crate::lock
73pub struct RwLock<T>(wgpu_sync::RwLock<T>);
74
75/// A read guard produced by locking [`RwLock`] as a reader.
76///
77/// This is just a wrapper around a [`wgpu_sync::RwLockReadGuard`].
78pub struct RwLockReadGuard<'a, T>(wgpu_sync::RwLockReadGuard<'a, T>);
79
80/// A write guard produced by locking [`RwLock`] as a writer.
81///
82/// This is just a wrapper around a [`wgpu_sync::RwLockWriteGuard`].
83pub struct RwLockWriteGuard<'a, T>(wgpu_sync::RwLockWriteGuard<'a, T>);
84
85impl<T> RwLock<T> {
86    pub fn new(_rank: LockRank, value: T) -> RwLock<T> {
87        RwLock(wgpu_sync::RwLock::new(value))
88    }
89
90    pub fn read(&self) -> RwLockReadGuard<'_, T> {
91        RwLockReadGuard(self.0.read())
92    }
93
94    pub fn write(&self) -> RwLockWriteGuard<'_, T> {
95        RwLockWriteGuard(self.0.write())
96    }
97
98    /// Force an read-unlock operation on this lock.
99    ///
100    /// Safety:
101    /// - A read lock must be held which is not held by a guard.
102    pub unsafe fn force_unlock_read(&self, _data: RankData) {
103        unsafe { self.0.force_unlock_read() };
104    }
105
106    /// Returns a reference to the underlying [`wgpu_sync::RwLock`].
107    ///
108    /// Marked as unsafe because it allows bypassing the rank system,
109    /// defeating the purpose of this type.
110    pub unsafe fn underlying(&self) -> &wgpu_sync::RwLock<T> {
111        &self.0
112    }
113}
114
115impl<'a, T> RwLockReadGuard<'a, T> {
116    // Forget the read guard, leaving the lock in a locked state with no guard.
117    //
118    // Equivalent to std::mem::forget, but preserves the information about the lock
119    // rank.
120    pub fn forget(this: Self) -> RankData {
121        core::mem::forget(this.0);
122
123        RankData
124    }
125}
126
127impl<T: fmt::Debug> fmt::Debug for RwLock<T> {
128    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129        self.0.fmt(f)
130    }
131}
132
133impl<'a, T> ops::Deref for RwLockReadGuard<'a, T> {
134    type Target = T;
135
136    fn deref(&self) -> &Self::Target {
137        self.0.deref()
138    }
139}
140
141impl<'a, T> ops::Deref for RwLockWriteGuard<'a, T> {
142    type Target = T;
143
144    fn deref(&self) -> &Self::Target {
145        self.0.deref()
146    }
147}
148
149impl<'a, T> ops::DerefMut for RwLockWriteGuard<'a, T> {
150    fn deref_mut(&mut self) -> &mut Self::Target {
151        self.0.deref_mut()
152    }
153}