9
9
//! as long as you want. This is useful when you want to spawn a task and move a guard into its
10
10
//! future.
11
11
//!
12
+ //! The locking mechanism uses eventual fairness to ensure locking will be fair on average without
13
+ //! sacrificing performance. This is done by forcing a fair lock whenever a lock operation is
14
+ //! starved for longer than 0.5 milliseconds.
15
+ //!
12
16
//! # Examples
13
17
//!
14
18
//! ```
@@ -137,7 +141,7 @@ impl<T> Lock<T> {
137
141
. locked
138
142
. compare_and_swap ( false , true , Ordering :: Acquire )
139
143
{
140
- Some ( LockGuard ( self . 0 . clone ( ) ) )
144
+ Some ( LockGuard ( self . clone ( ) ) )
141
145
} else {
142
146
None
143
147
}
@@ -173,15 +177,34 @@ impl<T: Default> Default for Lock<T> {
173
177
}
174
178
175
179
/// A guard that releases the lock when dropped.
176
- pub struct LockGuard < T > ( Arc < Inner < T > > ) ;
180
+ pub struct LockGuard < T > ( Lock < T > ) ;
177
181
178
182
unsafe impl < T : Send > Send for LockGuard < T > { }
179
183
unsafe impl < T : Sync > Sync for LockGuard < T > { }
180
184
185
+ impl < T > LockGuard < T > {
186
+ /// Returns a reference to the lock a guard came from.
187
+ ///
188
+ /// # Examples
189
+ ///
190
+ /// ```
191
+ /// # smol::block_on(async {
192
+ /// use async_lock::{Lock, LockGuard};
193
+ ///
194
+ /// let lock = Lock::new(10i32);
195
+ /// let guard = lock.lock().await;
196
+ /// dbg!(LockGuard::source(&guard));
197
+ /// # })
198
+ /// ```
199
+ pub fn source ( guard : & LockGuard < T > ) -> & Lock < T > {
200
+ & guard. 0
201
+ }
202
+ }
203
+
181
204
impl < T > Drop for LockGuard < T > {
182
205
fn drop ( & mut self ) {
183
- self . 0 . locked . store ( false , Ordering :: Release ) ;
184
- self . 0 . lock_ops . notify_one ( ) ;
206
+ ( self . 0 ) . 0 . locked . store ( false , Ordering :: Release ) ;
207
+ ( self . 0 ) . 0 . lock_ops . notify_one ( ) ;
185
208
}
186
209
}
187
210
@@ -201,12 +224,12 @@ impl<T> Deref for LockGuard<T> {
201
224
type Target = T ;
202
225
203
226
fn deref ( & self ) -> & T {
204
- unsafe { & * self . 0 . data . get ( ) }
227
+ unsafe { & * ( self . 0 ) . 0 . data . get ( ) }
205
228
}
206
229
}
207
230
208
231
impl < T > DerefMut for LockGuard < T > {
209
232
fn deref_mut ( & mut self ) -> & mut T {
210
- unsafe { & mut * self . 0 . data . get ( ) }
233
+ unsafe { & mut * ( self . 0 ) . 0 . data . get ( ) }
211
234
}
212
235
}
0 commit comments