Coverage Report

Created: 2025-05-08 06:13

/rust/registry/src/index.crates.io-6f17d22bba15001f/lock_api-0.4.12/src/mutex.rs
Line
Count
Source
1
// Copyright 2018 Amanieu d'Antras
2
//
3
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5
// http://opensource.org/licenses/MIT>, at your option. This file may not be
6
// copied, modified, or distributed except according to those terms.
7
8
use core::cell::UnsafeCell;
9
use core::fmt;
10
use core::marker::PhantomData;
11
use core::mem;
12
use core::ops::{Deref, DerefMut};
13
14
#[cfg(feature = "arc_lock")]
15
use alloc::sync::Arc;
16
#[cfg(feature = "arc_lock")]
17
use core::mem::ManuallyDrop;
18
#[cfg(feature = "arc_lock")]
19
use core::ptr;
20
21
#[cfg(feature = "owning_ref")]
22
use owning_ref::StableAddress;
23
24
#[cfg(feature = "serde")]
25
use serde::{Deserialize, Deserializer, Serialize, Serializer};
26
27
/// Basic operations for a mutex.
28
///
29
/// Types implementing this trait can be used by `Mutex` to form a safe and
30
/// fully-functioning mutex type.
31
///
32
/// # Safety
33
///
34
/// Implementations of this trait must ensure that the mutex is actually
35
/// exclusive: a lock can't be acquired while the mutex is already locked.
36
pub unsafe trait RawMutex {
37
    /// Initial value for an unlocked mutex.
38
    // A “non-constant” const item is a legacy way to supply an initialized value to downstream
39
    // static items. Can hopefully be replaced with `const fn new() -> Self` at some point.
40
    #[allow(clippy::declare_interior_mutable_const)]
41
    const INIT: Self;
42
43
    /// Marker type which determines whether a lock guard should be `Send`. Use
44
    /// one of the `GuardSend` or `GuardNoSend` helper types here.
45
    type GuardMarker;
46
47
    /// Acquires this mutex, blocking the current thread until it is able to do so.
48
    fn lock(&self);
49
50
    /// Attempts to acquire this mutex without blocking. Returns `true`
51
    /// if the lock was successfully acquired and `false` otherwise.
52
    fn try_lock(&self) -> bool;
53
54
    /// Unlocks this mutex.
55
    ///
56
    /// # Safety
57
    ///
58
    /// This method may only be called if the mutex is held in the current context, i.e. it must
59
    /// be paired with a successful call to [`lock`], [`try_lock`], [`try_lock_for`] or [`try_lock_until`].
60
    ///
61
    /// [`lock`]: RawMutex::lock
62
    /// [`try_lock`]: RawMutex::try_lock
63
    /// [`try_lock_for`]: RawMutexTimed::try_lock_for
64
    /// [`try_lock_until`]: RawMutexTimed::try_lock_until
65
    unsafe fn unlock(&self);
66
67
    /// Checks whether the mutex is currently locked.
68
    #[inline]
69
    fn is_locked(&self) -> bool {
70
        let acquired_lock = self.try_lock();
71
        if acquired_lock {
72
            // Safety: The lock has been successfully acquired above.
73
            unsafe {
74
                self.unlock();
75
            }
76
        }
77
        !acquired_lock
78
    }
79
}
80
81
/// Additional methods for mutexes which support fair unlocking.
82
///
83
/// Fair unlocking means that a lock is handed directly over to the next waiting
84
/// thread if there is one, without giving other threads the opportunity to
85
/// "steal" the lock in the meantime. This is typically slower than unfair
86
/// unlocking, but may be necessary in certain circumstances.
87
pub unsafe trait RawMutexFair: RawMutex {
88
    /// Unlocks this mutex using a fair unlock protocol.
89
    ///
90
    /// # Safety
91
    ///
92
    /// This method may only be called if the mutex is held in the current context, see
93
    /// the documentation of [`unlock`](RawMutex::unlock).
94
    unsafe fn unlock_fair(&self);
95
96
    /// Temporarily yields the mutex to a waiting thread if there is one.
97
    ///
98
    /// This method is functionally equivalent to calling `unlock_fair` followed
99
    /// by `lock`, however it can be much more efficient in the case where there
100
    /// are no waiting threads.
101
    ///
102
    /// # Safety
103
    ///
104
    /// This method may only be called if the mutex is held in the current context, see
105
    /// the documentation of [`unlock`](RawMutex::unlock).
106
    unsafe fn bump(&self) {
107
        self.unlock_fair();
108
        self.lock();
109
    }
110
}
111
112
/// Additional methods for mutexes which support locking with timeouts.
113
///
114
/// The `Duration` and `Instant` types are specified as associated types so that
115
/// this trait is usable even in `no_std` environments.
116
pub unsafe trait RawMutexTimed: RawMutex {
117
    /// Duration type used for `try_lock_for`.
118
    type Duration;
119
120
    /// Instant type used for `try_lock_until`.
121
    type Instant;
122
123
    /// Attempts to acquire this lock until a timeout is reached.
124
    fn try_lock_for(&self, timeout: Self::Duration) -> bool;
125
126
    /// Attempts to acquire this lock until a timeout is reached.
127
    fn try_lock_until(&self, timeout: Self::Instant) -> bool;
128
}
129
130
/// A mutual exclusion primitive useful for protecting shared data
131
///
132
/// This mutex will block threads waiting for the lock to become available. The
133
/// mutex can also be statically initialized or created via a `new`
134
/// constructor. Each mutex has a type parameter which represents the data that
135
/// it is protecting. The data can only be accessed through the RAII guards
136
/// returned from `lock` and `try_lock`, which guarantees that the data is only
137
/// ever accessed when the mutex is locked.
138
pub struct Mutex<R, T: ?Sized> {
139
    raw: R,
140
    data: UnsafeCell<T>,
141
}
142
143
unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {}
144
unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {}
145
146
impl<R: RawMutex, T> Mutex<R, T> {
147
    /// Creates a new mutex in an unlocked state ready for use.
148
    #[cfg(has_const_fn_trait_bound)]
149
    #[inline]
150
4.09k
    pub const fn new(val: T) -> Mutex<R, T> {
151
4.09k
        Mutex {
152
4.09k
            raw: R::INIT,
153
4.09k
            data: UnsafeCell::new(val),
154
4.09k
        }
155
4.09k
    }
156
157
    /// Creates a new mutex in an unlocked state ready for use.
158
    #[cfg(not(has_const_fn_trait_bound))]
159
    #[inline]
160
    pub fn new(val: T) -> Mutex<R, T> {
161
        Mutex {
162
            raw: R::INIT,
163
            data: UnsafeCell::new(val),
164
        }
165
    }
166
167
    /// Consumes this mutex, returning the underlying data.
168
    #[inline]
169
    pub fn into_inner(self) -> T {
170
        self.data.into_inner()
171
    }
172
}
173
174
impl<R, T> Mutex<R, T> {
175
    /// Creates a new mutex based on a pre-existing raw mutex.
176
    #[inline]
177
    pub const fn from_raw(raw_mutex: R, val: T) -> Mutex<R, T> {
178
        Mutex {
179
            raw: raw_mutex,
180
            data: UnsafeCell::new(val),
181
        }
182
    }
183
184
    /// Creates a new mutex based on a pre-existing raw mutex.
185
    ///
186
    /// This allows creating a mutex in a constant context on stable Rust.
187
    ///
188
    /// This method is a legacy alias for [`from_raw`](Self::from_raw).
189
    #[inline]
190
    pub const fn const_new(raw_mutex: R, val: T) -> Mutex<R, T> {
191
        Self::from_raw(raw_mutex, val)
192
    }
193
}
194
195
impl<R: RawMutex, T: ?Sized> Mutex<R, T> {
196
    /// Creates a new `MutexGuard` without checking if the mutex is locked.
197
    ///
198
    /// # Safety
199
    ///
200
    /// This method must only be called if the thread logically holds the lock.
201
    ///
202
    /// Calling this function when a guard has already been produced is undefined behaviour unless
203
    /// the guard was forgotten with `mem::forget`.
204
    #[inline]
205
978k
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
206
978k
        MutexGuard {
207
978k
            mutex: self,
208
978k
            marker: PhantomData,
209
978k
        }
210
978k
    }
211
212
    /// Acquires a mutex, blocking the current thread until it is able to do so.
213
    ///
214
    /// This function will block the local thread until it is available to acquire
215
    /// the mutex. Upon returning, the thread is the only thread with the mutex
216
    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
217
    /// the guard goes out of scope, the mutex will be unlocked.
218
    ///
219
    /// Attempts to lock a mutex in the thread which already holds the lock will
220
    /// result in a deadlock.
221
    #[inline]
222
978k
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
223
978k
        self.raw.lock();
224
978k
        // SAFETY: The lock is held, as required.
225
978k
        unsafe { self.make_guard_unchecked() }
226
978k
    }
227
228
    /// Attempts to acquire this lock.
229
    ///
230
    /// If the lock could not be acquired at this time, then `None` is returned.
231
    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
232
    /// guard is dropped.
233
    ///
234
    /// This function does not block.
235
    #[inline]
236
    pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> {
237
        if self.raw.try_lock() {
238
            // SAFETY: The lock is held, as required.
239
            Some(unsafe { self.make_guard_unchecked() })
240
        } else {
241
            None
242
        }
243
    }
244
245
    /// Returns a mutable reference to the underlying data.
246
    ///
247
    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
248
    /// take place---the mutable borrow statically guarantees no locks exist.
249
    #[inline]
250
    pub fn get_mut(&mut self) -> &mut T {
251
        unsafe { &mut *self.data.get() }
252
    }
253
254
    /// Checks whether the mutex is currently locked.
255
    #[inline]
256
    pub fn is_locked(&self) -> bool {
257
        self.raw.is_locked()
258
    }
259
260
    /// Forcibly unlocks the mutex.
261
    ///
262
    /// This is useful when combined with `mem::forget` to hold a lock without
263
    /// the need to maintain a `MutexGuard` object alive, for example when
264
    /// dealing with FFI.
265
    ///
266
    /// # Safety
267
    ///
268
    /// This method must only be called if the current thread logically owns a
269
    /// `MutexGuard` but that guard has been discarded using `mem::forget`.
270
    /// Behavior is undefined if a mutex is unlocked when not locked.
271
    #[inline]
272
    pub unsafe fn force_unlock(&self) {
273
        self.raw.unlock();
274
    }
275
276
    /// Returns the underlying raw mutex object.
277
    ///
278
    /// Note that you will most likely need to import the `RawMutex` trait from
279
    /// `lock_api` to be able to call functions on the raw mutex.
280
    ///
281
    /// # Safety
282
    ///
283
    /// This method is unsafe because it allows unlocking a mutex while
284
    /// still holding a reference to a `MutexGuard`.
285
    #[inline]
286
    pub unsafe fn raw(&self) -> &R {
287
        &self.raw
288
    }
289
290
    /// Returns a raw pointer to the underlying data.
291
    ///
292
    /// This is useful when combined with `mem::forget` to hold a lock without
293
    /// the need to maintain a `MutexGuard` object alive, for example when
294
    /// dealing with FFI.
295
    ///
296
    /// # Safety
297
    ///
298
    /// You must ensure that there are no data races when dereferencing the
299
    /// returned pointer, for example if the current thread logically owns
300
    /// a `MutexGuard` but that guard has been discarded using `mem::forget`.
301
    #[inline]
302
    pub fn data_ptr(&self) -> *mut T {
303
        self.data.get()
304
    }
305
306
    /// Creates a new `ArcMutexGuard` without checking if the mutex is locked.
307
    ///
308
    /// # Safety
309
    ///
310
    /// This method must only be called if the thread logically holds the lock.
311
    ///
312
    /// Calling this function when a guard has already been produced is undefined behaviour unless
313
    /// the guard was forgotten with `mem::forget`.
314
    #[cfg(feature = "arc_lock")]
315
    #[inline]
316
    unsafe fn make_arc_guard_unchecked(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
317
        ArcMutexGuard {
318
            mutex: self.clone(),
319
            marker: PhantomData,
320
        }
321
    }
322
323
    /// Acquires a lock through an `Arc`.
324
    ///
325
    /// This method is similar to the `lock` method; however, it requires the `Mutex` to be inside of an `Arc`
326
    /// and the resulting mutex guard has no lifetime requirements.
327
    #[cfg(feature = "arc_lock")]
328
    #[inline]
329
    pub fn lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
330
        self.raw.lock();
331
        // SAFETY: the locking guarantee is upheld
332
        unsafe { self.make_arc_guard_unchecked() }
333
    }
334
335
    /// Attempts to acquire a lock through an `Arc`.
336
    ///
337
    /// This method is similar to the `try_lock` method; however, it requires the `Mutex` to be inside of an
338
    /// `Arc` and the resulting mutex guard has no lifetime requirements.
339
    #[cfg(feature = "arc_lock")]
340
    #[inline]
341
    pub fn try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>> {
342
        if self.raw.try_lock() {
343
            // SAFETY: locking guarantee is upheld
344
            Some(unsafe { self.make_arc_guard_unchecked() })
345
        } else {
346
            None
347
        }
348
    }
349
}
350
351
impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> {
352
    /// Forcibly unlocks the mutex using a fair unlock protocol.
353
    ///
354
    /// This is useful when combined with `mem::forget` to hold a lock without
355
    /// the need to maintain a `MutexGuard` object alive, for example when
356
    /// dealing with FFI.
357
    ///
358
    /// # Safety
359
    ///
360
    /// This method must only be called if the current thread logically owns a
361
    /// `MutexGuard` but that guard has been discarded using `mem::forget`.
362
    /// Behavior is undefined if a mutex is unlocked when not locked.
363
    #[inline]
364
    pub unsafe fn force_unlock_fair(&self) {
365
        self.raw.unlock_fair();
366
    }
367
}
368
369
impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> {
370
    /// Attempts to acquire this lock until a timeout is reached.
371
    ///
372
    /// If the lock could not be acquired before the timeout expired, then
373
    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
374
    /// be unlocked when the guard is dropped.
375
    #[inline]
376
    pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> {
377
        if self.raw.try_lock_for(timeout) {
378
            // SAFETY: The lock is held, as required.
379
            Some(unsafe { self.make_guard_unchecked() })
380
        } else {
381
            None
382
        }
383
    }
384
385
    /// Attempts to acquire this lock until a timeout is reached.
386
    ///
387
    /// If the lock could not be acquired before the timeout expired, then
388
    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
389
    /// be unlocked when the guard is dropped.
390
    #[inline]
391
    pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> {
392
        if self.raw.try_lock_until(timeout) {
393
            // SAFETY: The lock is held, as required.
394
            Some(unsafe { self.make_guard_unchecked() })
395
        } else {
396
            None
397
        }
398
    }
399
400
    /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
401
    ///
402
    /// This method is similar to the `try_lock_for` method; however, it requires the `Mutex` to be inside of an
403
    /// `Arc` and the resulting mutex guard has no lifetime requirements.
404
    #[cfg(feature = "arc_lock")]
405
    #[inline]
406
    pub fn try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>> {
407
        if self.raw.try_lock_for(timeout) {
408
            // SAFETY: locking guarantee is upheld
409
            Some(unsafe { self.make_arc_guard_unchecked() })
410
        } else {
411
            None
412
        }
413
    }
414
415
    /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
416
    ///
417
    /// This method is similar to the `try_lock_until` method; however, it requires the `Mutex` to be inside of
418
    /// an `Arc` and the resulting mutex guard has no lifetime requirements.
419
    #[cfg(feature = "arc_lock")]
420
    #[inline]
421
    pub fn try_lock_arc_until(
422
        self: &Arc<Self>,
423
        timeout: R::Instant,
424
    ) -> Option<ArcMutexGuard<R, T>> {
425
        if self.raw.try_lock_until(timeout) {
426
            // SAFETY: locking guarantee is upheld
427
            Some(unsafe { self.make_arc_guard_unchecked() })
428
        } else {
429
            None
430
        }
431
    }
432
}
433
434
impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> {
435
    #[inline]
436
    fn default() -> Mutex<R, T> {
437
        Mutex::new(Default::default())
438
    }
439
}
440
441
impl<R: RawMutex, T> From<T> for Mutex<R, T> {
442
    #[inline]
443
    fn from(t: T) -> Mutex<R, T> {
444
        Mutex::new(t)
445
    }
446
}
447
448
impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> {
449
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450
        match self.try_lock() {
451
            Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
452
            None => {
453
                struct LockedPlaceholder;
454
                impl fmt::Debug for LockedPlaceholder {
455
                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456
                        f.write_str("<locked>")
457
                    }
458
                }
459
460
                f.debug_struct("Mutex")
461
                    .field("data", &LockedPlaceholder)
462
                    .finish()
463
            }
464
        }
465
    }
466
}
467
468
// Copied and modified from serde
469
#[cfg(feature = "serde")]
470
impl<R, T> Serialize for Mutex<R, T>
471
where
472
    R: RawMutex,
473
    T: Serialize + ?Sized,
474
{
475
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
476
    where
477
        S: Serializer,
478
    {
479
        self.lock().serialize(serializer)
480
    }
481
}
482
483
#[cfg(feature = "serde")]
484
impl<'de, R, T> Deserialize<'de> for Mutex<R, T>
485
where
486
    R: RawMutex,
487
    T: Deserialize<'de> + ?Sized,
488
{
489
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
490
    where
491
        D: Deserializer<'de>,
492
    {
493
        Deserialize::deserialize(deserializer).map(Mutex::new)
494
    }
495
}
496
497
/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
498
/// dropped (falls out of scope), the lock will be unlocked.
499
///
500
/// The data protected by the mutex can be accessed through this guard via its
501
/// `Deref` and `DerefMut` implementations.
502
#[clippy::has_significant_drop]
503
#[must_use = "if unused the Mutex will immediately unlock"]
504
pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> {
505
    mutex: &'a Mutex<R, T>,
506
    marker: PhantomData<(&'a mut T, R::GuardMarker)>,
507
}
508
509
unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {}
510
511
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
512
    /// Returns a reference to the original `Mutex` object.
513
    pub fn mutex(s: &Self) -> &'a Mutex<R, T> {
514
        s.mutex
515
    }
516
517
    /// Makes a new `MappedMutexGuard` for a component of the locked data.
518
    ///
519
    /// This operation cannot fail as the `MutexGuard` passed
520
    /// in already locked the mutex.
521
    ///
522
    /// This is an associated function that needs to be
523
    /// used as `MutexGuard::map(...)`. A method would interfere with methods of
524
    /// the same name on the contents of the locked data.
525
    #[inline]
526
    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
527
    where
528
        F: FnOnce(&mut T) -> &mut U,
529
    {
530
        let raw = &s.mutex.raw;
531
        let data = f(unsafe { &mut *s.mutex.data.get() });
532
        mem::forget(s);
533
        MappedMutexGuard {
534
            raw,
535
            data,
536
            marker: PhantomData,
537
        }
538
    }
539
540
    /// Attempts to make a new `MappedMutexGuard` for a component of the
541
    /// locked data. The original guard is returned if the closure returns `None`.
542
    ///
543
    /// This operation cannot fail as the `MutexGuard` passed
544
    /// in already locked the mutex.
545
    ///
546
    /// This is an associated function that needs to be
547
    /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of
548
    /// the same name on the contents of the locked data.
549
    #[inline]
550
    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
551
    where
552
        F: FnOnce(&mut T) -> Option<&mut U>,
553
    {
554
        let raw = &s.mutex.raw;
555
        let data = match f(unsafe { &mut *s.mutex.data.get() }) {
556
            Some(data) => data,
557
            None => return Err(s),
558
        };
559
        mem::forget(s);
560
        Ok(MappedMutexGuard {
561
            raw,
562
            data,
563
            marker: PhantomData,
564
        })
565
    }
566
567
    /// Temporarily unlocks the mutex to execute the given function.
568
    ///
569
    /// This is safe because `&mut` guarantees that there exist no other
570
    /// references to the data protected by the mutex.
571
    #[inline]
572
    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
573
    where
574
        F: FnOnce() -> U,
575
    {
576
        // Safety: A MutexGuard always holds the lock.
577
        unsafe {
578
            s.mutex.raw.unlock();
579
        }
580
        defer!(s.mutex.raw.lock());
581
        f()
582
    }
583
584
    /// Leaks the mutex guard and returns a mutable reference to the data
585
    /// protected by the mutex.
586
    ///
587
    /// This will leave the `Mutex` in a locked state.
588
    #[inline]
589
    pub fn leak(s: Self) -> &'a mut T {
590
        let r = unsafe { &mut *s.mutex.data.get() };
591
        mem::forget(s);
592
        r
593
    }
594
}
595
596
impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
597
    /// Unlocks the mutex using a fair unlock protocol.
598
    ///
599
    /// By default, mutexes are unfair and allow the current thread to re-lock
600
    /// the mutex before another has the chance to acquire the lock, even if
601
    /// that thread has been blocked on the mutex for a long time. This is the
602
    /// default because it allows much higher throughput as it avoids forcing a
603
    /// context switch on every mutex unlock. This can result in one thread
604
    /// acquiring a mutex many more times than other threads.
605
    ///
606
    /// However in some cases it can be beneficial to ensure fairness by forcing
607
    /// the lock to pass on to a waiting thread if there is one. This is done by
608
    /// using this method instead of dropping the `MutexGuard` normally.
609
    #[inline]
610
    pub fn unlock_fair(s: Self) {
611
        // Safety: A MutexGuard always holds the lock.
612
        unsafe {
613
            s.mutex.raw.unlock_fair();
614
        }
615
        mem::forget(s);
616
    }
617
618
    /// Temporarily unlocks the mutex to execute the given function.
619
    ///
620
    /// The mutex is unlocked using a fair unlock protocol.
621
    ///
622
    /// This is safe because `&mut` guarantees that there exist no other
623
    /// references to the data protected by the mutex.
624
    #[inline]
625
    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
626
    where
627
        F: FnOnce() -> U,
628
    {
629
        // Safety: A MutexGuard always holds the lock.
630
        unsafe {
631
            s.mutex.raw.unlock_fair();
632
        }
633
        defer!(s.mutex.raw.lock());
634
        f()
635
    }
636
637
    /// Temporarily yields the mutex to a waiting thread if there is one.
638
    ///
639
    /// This method is functionally equivalent to calling `unlock_fair` followed
640
    /// by `lock`, however it can be much more efficient in the case where there
641
    /// are no waiting threads.
642
    #[inline]
643
    pub fn bump(s: &mut Self) {
644
        // Safety: A MutexGuard always holds the lock.
645
        unsafe {
646
            s.mutex.raw.bump();
647
        }
648
    }
649
}
650
651
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> {
652
    type Target = T;
653
    #[inline]
654
    fn deref(&self) -> &T {
655
        unsafe { &*self.mutex.data.get() }
656
    }
657
}
658
659
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> {
660
    #[inline]
661
1.23M
    fn deref_mut(&mut self) -> &mut T {
662
1.23M
        unsafe { &mut *self.mutex.data.get() }
663
1.23M
    }
664
}
665
666
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> {
667
    #[inline]
668
978k
    fn drop(&mut self) {
669
978k
        // Safety: A MutexGuard always holds the lock.
670
978k
        unsafe {
671
978k
            self.mutex.raw.unlock();
672
978k
        }
673
978k
    }
674
}
675
676
impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> {
677
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
678
        fmt::Debug::fmt(&**self, f)
679
    }
680
}
681
682
impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> {
683
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
684
        (**self).fmt(f)
685
    }
686
}
687
688
#[cfg(feature = "owning_ref")]
689
unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {}
690
691
/// An RAII mutex guard returned by the `Arc` locking operations on `Mutex`.
692
///
693
/// This is similar to the `MutexGuard` struct, except instead of using a reference to unlock the `Mutex` it
694
/// uses an `Arc<Mutex>`. This has several advantages, most notably that it has an `'static` lifetime.
695
#[cfg(feature = "arc_lock")]
696
#[clippy::has_significant_drop]
697
#[must_use = "if unused the Mutex will immediately unlock"]
698
pub struct ArcMutexGuard<R: RawMutex, T: ?Sized> {
699
    mutex: Arc<Mutex<R, T>>,
700
    marker: PhantomData<*const ()>,
701
}
702
703
#[cfg(feature = "arc_lock")]
704
unsafe impl<R: RawMutex + Send + Sync, T: Send + ?Sized> Send for ArcMutexGuard<R, T> where
705
    R::GuardMarker: Send
706
{
707
}
708
#[cfg(feature = "arc_lock")]
709
unsafe impl<R: RawMutex + Sync, T: Sync + ?Sized> Sync for ArcMutexGuard<R, T> where
710
    R::GuardMarker: Sync
711
{
712
}
713
714
#[cfg(feature = "arc_lock")]
715
impl<R: RawMutex, T: ?Sized> ArcMutexGuard<R, T> {
716
    /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`.
717
    #[inline]
718
    pub fn mutex(s: &Self) -> &Arc<Mutex<R, T>> {
719
        &s.mutex
720
    }
721
722
    /// Unlocks the mutex and returns the `Arc` that was held by the [`ArcMutexGuard`].
723
    #[inline]
724
    pub fn into_arc(s: Self) -> Arc<Mutex<R, T>> {
725
        // Safety: Skip our Drop impl and manually unlock the mutex.
726
        let arc = unsafe { ptr::read(&s.mutex) };
727
        mem::forget(s);
728
        unsafe {
729
            arc.raw.unlock();
730
        }
731
        arc
732
    }
733
734
    /// Temporarily unlocks the mutex to execute the given function.
735
    ///
736
    /// This is safe because `&mut` guarantees that there exist no other
737
    /// references to the data protected by the mutex.
738
    #[inline]
739
    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
740
    where
741
        F: FnOnce() -> U,
742
    {
743
        // Safety: A MutexGuard always holds the lock.
744
        unsafe {
745
            s.mutex.raw.unlock();
746
        }
747
        defer!(s.mutex.raw.lock());
748
        f()
749
    }
750
}
751
752
#[cfg(feature = "arc_lock")]
753
impl<R: RawMutexFair, T: ?Sized> ArcMutexGuard<R, T> {
754
    /// Unlocks the mutex using a fair unlock protocol.
755
    ///
756
    /// This is functionally identical to the `unlock_fair` method on [`MutexGuard`].
757
    #[inline]
758
    pub fn unlock_fair(s: Self) {
759
        // Safety: A MutexGuard always holds the lock.
760
        unsafe {
761
            s.mutex.raw.unlock_fair();
762
        }
763
764
        // SAFETY: make sure the Arc gets it reference decremented
765
        let mut s = ManuallyDrop::new(s);
766
        unsafe { ptr::drop_in_place(&mut s.mutex) };
767
    }
768
769
    /// Temporarily unlocks the mutex to execute the given function.
770
    ///
771
    /// This is functionally identical to the `unlocked_fair` method on [`MutexGuard`].
772
    #[inline]
773
    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
774
    where
775
        F: FnOnce() -> U,
776
    {
777
        // Safety: A MutexGuard always holds the lock.
778
        unsafe {
779
            s.mutex.raw.unlock_fair();
780
        }
781
        defer!(s.mutex.raw.lock());
782
        f()
783
    }
784
785
    /// Temporarily yields the mutex to a waiting thread if there is one.
786
    ///
787
    /// This is functionally identical to the `bump` method on [`MutexGuard`].
788
    #[inline]
789
    pub fn bump(s: &mut Self) {
790
        // Safety: A MutexGuard always holds the lock.
791
        unsafe {
792
            s.mutex.raw.bump();
793
        }
794
    }
795
}
796
797
#[cfg(feature = "arc_lock")]
798
impl<R: RawMutex, T: ?Sized> Deref for ArcMutexGuard<R, T> {
799
    type Target = T;
800
    #[inline]
801
    fn deref(&self) -> &T {
802
        unsafe { &*self.mutex.data.get() }
803
    }
804
}
805
806
#[cfg(feature = "arc_lock")]
807
impl<R: RawMutex, T: ?Sized> DerefMut for ArcMutexGuard<R, T> {
808
    #[inline]
809
    fn deref_mut(&mut self) -> &mut T {
810
        unsafe { &mut *self.mutex.data.get() }
811
    }
812
}
813
814
#[cfg(feature = "arc_lock")]
815
impl<R: RawMutex, T: ?Sized> Drop for ArcMutexGuard<R, T> {
816
    #[inline]
817
    fn drop(&mut self) {
818
        // Safety: A MutexGuard always holds the lock.
819
        unsafe {
820
            self.mutex.raw.unlock();
821
        }
822
    }
823
}
824
825
/// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
826
/// subfield of the protected data.
827
///
828
/// The main difference between `MappedMutexGuard` and `MutexGuard` is that the
829
/// former doesn't support temporarily unlocking and re-locking, since that
830
/// could introduce soundness issues if the locked object is modified by another
831
/// thread.
832
#[clippy::has_significant_drop]
833
#[must_use = "if unused the Mutex will immediately unlock"]
834
pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> {
835
    raw: &'a R,
836
    data: *mut T,
837
    marker: PhantomData<&'a mut T>,
838
}
839
840
unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync
841
    for MappedMutexGuard<'a, R, T>
842
{
843
}
844
unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where
845
    R::GuardMarker: Send
846
{
847
}
848
849
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
850
    /// Makes a new `MappedMutexGuard` for a component of the locked data.
851
    ///
852
    /// This operation cannot fail as the `MappedMutexGuard` passed
853
    /// in already locked the mutex.
854
    ///
855
    /// This is an associated function that needs to be
856
    /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of
857
    /// the same name on the contents of the locked data.
858
    #[inline]
859
    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
860
    where
861
        F: FnOnce(&mut T) -> &mut U,
862
    {
863
        let raw = s.raw;
864
        let data = f(unsafe { &mut *s.data });
865
        mem::forget(s);
866
        MappedMutexGuard {
867
            raw,
868
            data,
869
            marker: PhantomData,
870
        }
871
    }
872
873
    /// Attempts to make a new `MappedMutexGuard` for a component of the
874
    /// locked data. The original guard is returned if the closure returns `None`.
875
    ///
876
    /// This operation cannot fail as the `MappedMutexGuard` passed
877
    /// in already locked the mutex.
878
    ///
879
    /// This is an associated function that needs to be
880
    /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of
881
    /// the same name on the contents of the locked data.
882
    #[inline]
883
    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
884
    where
885
        F: FnOnce(&mut T) -> Option<&mut U>,
886
    {
887
        let raw = s.raw;
888
        let data = match f(unsafe { &mut *s.data }) {
889
            Some(data) => data,
890
            None => return Err(s),
891
        };
892
        mem::forget(s);
893
        Ok(MappedMutexGuard {
894
            raw,
895
            data,
896
            marker: PhantomData,
897
        })
898
    }
899
}
900
901
impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
902
    /// Unlocks the mutex using a fair unlock protocol.
903
    ///
904
    /// By default, mutexes are unfair and allow the current thread to re-lock
905
    /// the mutex before another has the chance to acquire the lock, even if
906
    /// that thread has been blocked on the mutex for a long time. This is the
907
    /// default because it allows much higher throughput as it avoids forcing a
908
    /// context switch on every mutex unlock. This can result in one thread
909
    /// acquiring a mutex many more times than other threads.
910
    ///
911
    /// However in some cases it can be beneficial to ensure fairness by forcing
912
    /// the lock to pass on to a waiting thread if there is one. This is done by
913
    /// using this method instead of dropping the `MutexGuard` normally.
914
    #[inline]
915
    pub fn unlock_fair(s: Self) {
916
        // Safety: A MutexGuard always holds the lock.
917
        unsafe {
918
            s.raw.unlock_fair();
919
        }
920
        mem::forget(s);
921
    }
922
}
923
924
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> {
925
    type Target = T;
926
    #[inline]
927
    fn deref(&self) -> &T {
928
        unsafe { &*self.data }
929
    }
930
}
931
932
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> {
933
    #[inline]
934
    fn deref_mut(&mut self) -> &mut T {
935
        unsafe { &mut *self.data }
936
    }
937
}
938
939
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> {
940
    #[inline]
941
    fn drop(&mut self) {
942
        // Safety: A MappedMutexGuard always holds the lock.
943
        unsafe {
944
            self.raw.unlock();
945
        }
946
    }
947
}
948
949
impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> {
950
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
951
        fmt::Debug::fmt(&**self, f)
952
    }
953
}
954
955
impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
956
    for MappedMutexGuard<'a, R, T>
957
{
958
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
959
        (**self).fmt(f)
960
    }
961
}
962
963
#[cfg(feature = "owning_ref")]
964
unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {}