Skip to main content

nuclei/sync/
mutex.rs

1//! A fair asynchronous mutex: a one-permit semaphore around a value.
2
3#![allow(unsafe_code)]
4
5use core::cell::UnsafeCell;
6use core::error::Error;
7use core::fmt;
8use core::future::Future;
9use core::marker::PhantomData;
10use core::mem::ManuallyDrop;
11use core::ops::{Deref, DerefMut};
12use core::pin::Pin;
13use core::ptr;
14use core::task::{Context, Poll};
15use std::sync::Arc;
16
17use super::internal;
18use super::raw_semaphore::{PermitWait, RawSemaphore};
19
20/// Error returned from [`Mutex::try_lock`], [`RwLock::try_read`] and
21/// [`RwLock::try_write`] and their `_owned` forms.
22///
23/// `Mutex::try_lock` fails when the mutex is locked, or is owed to a waiter
24/// that was passed over too often. `RwLock::try_read` fails when a writer
25/// holds the lock, an upgrade is under way, or a waiter is owed the lock.
26/// `RwLock::try_write` fails when any reader or writer holds it, or a waiter
27/// is owed it.
28///
29/// [`RwLock::try_read`]: super::RwLock::try_read
30/// [`RwLock::try_write`]: super::RwLock::try_write
31#[derive(Debug)]
32pub struct TryLockError(pub(crate) ());
33
34impl fmt::Display for TryLockError {
35    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
36        f.write_str("operation would block")
37    }
38}
39
40impl Error for TryLockError {}
41
42/// A mutual-exclusion lock whose wait is a future.
43///
44/// Uncontended, [`try_lock`](Self::try_lock) and a guard's drop are one
45/// atomic read-modify-write each and allocate nothing. A caller takes the
46/// lock whenever it is free, even while others wait; under contention
47/// [`lock`](Self::lock) spins briefly within the poll (see the
48/// [module docs](super#what-every-primitive-guarantees)), then queues and
49/// returns `Pending`.
50/// An unlock wakes the oldest waiter to try again; a waiter that loses
51/// [`MAX_BYPASS`](super::MAX_BYPASS) times is handed the lock directly,
52/// and `try_lock` fails until it has had it.
53///
54/// It does not poison: a panic in a holder unlocks it.
55///
56/// ```
57/// use nuclei::sync::Mutex;
58///
59/// let counter = Mutex::new(0u32);
60/// *counter.try_lock().expect("uncontended") += 1;
61/// assert_eq!(counter.into_inner(), 1);
62/// ```
63pub struct Mutex<T: ?Sized> {
64    sem: RawSemaphore,
65    value: UnsafeCell<T>,
66}
67
68// SAFETY: the value moves with the mutex.
69unsafe impl<T: ?Sized + Send> Send for Mutex<T> {}
70// SAFETY: the semaphore admits one guard at a time, and a guard hands out
71// the value only as `&mut T` or `&T` under that exclusion.
72unsafe impl<T: ?Sized + Send> Sync for Mutex<T> {}
73
74impl<T> Mutex<T> {
75    loom_const_fn! {
76        /// An unlocked mutex holding `value`.
77        pub fn new(value: T) -> Self {
78            Self { sem: RawSemaphore::new(1), value: UnsafeCell::new(value) }
79        }
80    }
81
82    loom_const_fn! {
83        /// An unlocked mutex holding `value`, usable in a `static`.
84        pub fn const_new(value: T) -> Self {
85            Self { sem: RawSemaphore::new(1), value: UnsafeCell::new(value) }
86        }
87    }
88
89    loom_const_fn! {
90        /// An unlocked mutex holding `value` whose contended acquires never
91        /// spin: they queue at once. For a mutex its holders keep across
92        /// long waits of their own (I/O, say), where a spin could only burn
93        /// the caller's time.
94        #[cfg(test)]
95        pub(crate) fn new_without_spin(value: T) -> Self {
96            Self { sem: RawSemaphore::without_spin(1), value: UnsafeCell::new(value) }
97        }
98    }
99
100    /// Consumes the mutex and returns its value.
101    pub fn into_inner(self) -> T {
102        self.value.into_inner()
103    }
104}
105
106#[cfg(all(test, not(loom)))]
107impl<T: ?Sized> Mutex<T> {
108    /// The rounds a contended acquire of this mutex would spin now.
109    pub(crate) fn spin_rounds(&self) -> u32 {
110        use super::queue::Policy;
111        self.sem.queue().spin.rounds()
112    }
113}
114
115impl<T: ?Sized> Mutex<T> {
116    /// Takes the permit if it is free and no handoff is owed.
117    #[inline]
118    fn try_acquire(&self) -> bool {
119        match self.sem.take_one() {
120            Ok(()) => true,
121            Err(seen) => self.sem.try_acquire_one_from(seen),
122        }
123    }
124
125    /// Locks the mutex if it is free and no handoff is owed.
126    ///
127    /// # Errors
128    ///
129    /// [`TryLockError`] when the mutex is locked or owed to a waiter.
130    #[inline]
131    pub fn try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError> {
132        if self.try_acquire() {
133            Ok(MutexGuard::new(self))
134        } else {
135            Err(TryLockError(()))
136        }
137    }
138
139    /// [`try_lock`](Self::try_lock) through an `Arc`, so the guard can
140    /// outlive the borrow.
141    ///
142    /// # Errors
143    ///
144    /// [`TryLockError`] when the mutex is locked or owed to a waiter.
145    pub fn try_lock_owned(self: Arc<Self>) -> Result<OwnedMutexGuard<T>, TryLockError> {
146        if self.try_acquire() {
147            Ok(OwnedMutexGuard {
148                mutex: self,
149                _value: PhantomData,
150            })
151        } else {
152            Err(TryLockError(()))
153        }
154    }
155
156    /// Waits for the lock. Uncontended, the first poll is one load and one
157    /// atomic read-modify-write. Contended, a poll may spin for up to the
158    /// lock's spin budget before it queues, and again after a retry it lost,
159    /// before it returns `Pending`; it is lock-free, not wait-free: see
160    /// [Progress](super#progress).
161    ///
162    /// Dropping the future withdraws the wait, and passes on a lock handed
163    /// to it meanwhile.
164    #[inline]
165    pub fn lock(&self) -> Lock<'_, T> {
166        Lock {
167            mutex: self,
168            wait: PermitWait::new(),
169        }
170    }
171
172    /// [`lock`](Self::lock) through an `Arc`, so the guard can outlive the
173    /// borrow.
174    pub fn lock_owned(self: Arc<Self>) -> LockOwned<T> {
175        LockOwned {
176            mutex: self,
177            wait: PermitWait::new(),
178        }
179    }
180
181    /// [`lock`](Self::lock) for a thread that may block: it parks the
182    /// calling thread until the lock is free. On a nuclei shard (inside one of its tasks) it does not park the thread: it runs a nested `block_on`, so the shard keeps running its other tasks meanwhile.
183    /// Inside another runtime's task it blocks that task's executor thread,
184    /// so do not: the task that would unlock may be the one that thread was
185    /// running.
186    ///
187    /// # Panics
188    ///
189    /// On `wasm32`, where no other thread can unlock, when the lock is held:
190    /// the call could never end.
191    pub fn blocking_lock(&self) -> MutexGuard<'_, T> {
192        internal::blocking(self.lock())
193    }
194
195    /// [`blocking_lock`](Self::blocking_lock) through an `Arc`, so the guard
196    /// can outlive the borrow.
197    ///
198    /// # Panics
199    ///
200    /// As for [`blocking_lock`](Self::blocking_lock).
201    pub fn blocking_lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
202        internal::blocking(self.lock_owned())
203    }
204
205    /// The value, borrowed mutably; `&mut self` proves no guard exists.
206    pub fn get_mut(&mut self) -> &mut T {
207        self.value.get_mut()
208    }
209}
210
211impl<T> From<T> for Mutex<T> {
212    fn from(value: T) -> Self {
213        Self::new(value)
214    }
215}
216
217impl<T: Default> Default for Mutex<T> {
218    fn default() -> Self {
219        Self::new(T::default())
220    }
221}
222
223impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
224    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
225        let mut d = f.debug_struct("Mutex");
226        match self.try_lock() {
227            Ok(inner) => d.field("data", &&*inner),
228            Err(_) => d.field("data", &format_args!("<locked>")),
229        };
230        d.finish()
231    }
232}
233
234/// Exclusive access to a [`Mutex`]'s value; unlocks on drop.
235///
236/// The release is one atomic read-modify-write when no waiter needs telling.
237/// Otherwise it is lock-free, not wait-free: it returns after one pass over
238/// the queue, plus at most one for each operation of another thread that
239/// lands on the queue meanwhile (see [Progress](super#progress)).
240#[must_use = "dropping the guard unlocks the mutex at once"]
241pub struct MutexGuard<'a, T: ?Sized> {
242    mutex: &'a Mutex<T>,
243    // `Sync` only when `T: Sync`, since `&MutexGuard` reaches `&T`.
244    _value: PhantomData<&'a mut T>,
245}
246
247impl<'a, T: ?Sized> MutexGuard<'a, T> {
248    fn new(mutex: &'a Mutex<T>) -> Self {
249        Self {
250            mutex,
251            _value: PhantomData,
252        }
253    }
254
255    /// The mutex, once the guard is spent: unlocking is left to whoever
256    /// takes it over.
257    fn into_mutex(self) -> &'a Mutex<T> {
258        ManuallyDrop::new(self).mutex
259    }
260
261    /// A guard for a component of the locked data. It cannot fail: this
262    /// guard already holds the lock.
263    ///
264    /// An associated function, `MutexGuard::map(guard, f)`: a method would
265    /// shadow methods of the locked data.
266    #[inline]
267    pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
268    where
269        U: ?Sized,
270        F: FnOnce(&mut T) -> &mut U,
271    {
272        let data = ptr::from_mut(f(&mut *this));
273        let mutex = this.into_mutex();
274        MappedMutexGuard {
275            sem: &mutex.sem,
276            data,
277            _value: PhantomData,
278        }
279    }
280
281    /// [`map`](Self::map) that gives the guard back when `f` finds no
282    /// component, with the lock still held.
283    #[inline]
284    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
285    where
286        U: ?Sized,
287        F: FnOnce(&mut T) -> Option<&mut U>,
288    {
289        let data = match f(&mut *this) {
290            Some(data) => ptr::from_mut(data),
291            None => return Err(this),
292        };
293        let mutex = this.into_mutex();
294        Ok(MappedMutexGuard {
295            sem: &mutex.sem,
296            data,
297            _value: PhantomData,
298        })
299    }
300
301    /// The mutex this guard locks, for a caller that wants to unlock and
302    /// lock again.
303    #[inline]
304    pub fn mutex(this: &Self) -> &'a Mutex<T> {
305        this.mutex
306    }
307}
308
309impl<T: ?Sized> Deref for MutexGuard<'_, T> {
310    type Target = T;
311
312    fn deref(&self) -> &T {
313        // SAFETY: this guard holds the mutex's only permit.
314        unsafe { &*self.mutex.value.get() }
315    }
316}
317
318impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
319    fn deref_mut(&mut self) -> &mut T {
320        // SAFETY: as in `deref`, and `&mut self` makes this borrow unique.
321        unsafe { &mut *self.mutex.value.get() }
322    }
323}
324
325impl<T: ?Sized> Drop for MutexGuard<'_, T> {
326    #[inline]
327    fn drop(&mut self) {
328        self.mutex.sem.release(1);
329    }
330}
331
332impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
333    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
334        fmt::Debug::fmt(&**self, f)
335    }
336}
337
338impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
339    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
340        fmt::Display::fmt(&**self, f)
341    }
342}
343
344/// Exclusive access to a [`Mutex`] held through an `Arc`; unlocks on drop.
345/// The release makes the progress [`MutexGuard`]'s does.
346#[must_use = "dropping the guard unlocks the mutex at once"]
347pub struct OwnedMutexGuard<T: ?Sized> {
348    mutex: Arc<Mutex<T>>,
349    // `Sync` only when `T: Sync`, since `&OwnedMutexGuard` reaches `&T`.
350    _value: PhantomData<UnsafeCell<T>>,
351}
352
353// SAFETY: sharing the guard shares `&T`, which needs `T: Sync`.
354unsafe impl<T: ?Sized + Send + Sync> Sync for OwnedMutexGuard<T> {}
355
356impl<T: ?Sized> OwnedMutexGuard<T> {
357    /// The `Arc` this guard keeps the mutex alive through, once the guard is
358    /// spent: unlocking is left to whoever takes it over.
359    fn into_arc(self) -> Arc<Mutex<T>> {
360        let spent = ManuallyDrop::new(self);
361        // SAFETY: `spent` is never dropped, so this is the only read of the
362        // `Arc` and it is moved out exactly once.
363        unsafe { ptr::read(&spent.mutex) }
364    }
365
366    /// A guard for a component of the locked data. It cannot fail: this
367    /// guard already holds the lock.
368    ///
369    /// An associated function, `OwnedMutexGuard::map(guard, f)`: a method
370    /// would shadow methods of the locked data.
371    #[inline]
372    pub fn map<U, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, U>
373    where
374        U: ?Sized,
375        F: FnOnce(&mut T) -> &mut U,
376    {
377        let data = ptr::from_mut(f(&mut *this));
378        OwnedMappedMutexGuard {
379            mutex: this.into_arc(),
380            data,
381        }
382    }
383
384    /// [`map`](Self::map) that gives the guard back when `f` finds no
385    /// component, with the lock still held.
386    #[inline]
387    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, U>, Self>
388    where
389        U: ?Sized,
390        F: FnOnce(&mut T) -> Option<&mut U>,
391    {
392        let data = match f(&mut *this) {
393            Some(data) => ptr::from_mut(data),
394            None => return Err(this),
395        };
396        Ok(OwnedMappedMutexGuard {
397            mutex: this.into_arc(),
398            data,
399        })
400    }
401
402    /// The `Arc` of the mutex this guard locks.
403    #[inline]
404    pub fn mutex(this: &Self) -> &Arc<Mutex<T>> {
405        &this.mutex
406    }
407}
408
409impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
410    type Target = T;
411
412    fn deref(&self) -> &T {
413        // SAFETY: this guard holds the mutex's only permit.
414        unsafe { &*self.mutex.value.get() }
415    }
416}
417
418impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
419    fn deref_mut(&mut self) -> &mut T {
420        // SAFETY: as in `deref`, and `&mut self` makes this borrow unique.
421        unsafe { &mut *self.mutex.value.get() }
422    }
423}
424
425impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
426    #[inline]
427    fn drop(&mut self) {
428        self.mutex.sem.release(1);
429    }
430}
431
432impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
433    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
434        fmt::Debug::fmt(&**self, f)
435    }
436}
437
438impl<T: ?Sized + fmt::Display> fmt::Display for OwnedMutexGuard<T> {
439    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
440        fmt::Display::fmt(&**self, f)
441    }
442}
443
444/// A guard for a component of a [`Mutex`]'s value, made by
445/// [`MutexGuard::map`]; unlocks on drop. The release makes the progress
446/// [`MutexGuard`]'s does.
447#[must_use = "dropping the guard unlocks the mutex at once"]
448pub struct MappedMutexGuard<'a, T: ?Sized> {
449    sem: &'a RawSemaphore,
450    data: *mut T,
451    // Tells the borrow checker this guard holds a `&mut T`.
452    _value: PhantomData<&'a mut T>,
453}
454
455// SAFETY: the guard hands out `&T` and `&mut T` to the component only, as a
456// `MutexGuard` does to the whole value, so it shares and moves like a `&T`
457// and a `&mut T`.
458unsafe impl<T: ?Sized + Sync> Sync for MappedMutexGuard<'_, T> {}
459// SAFETY: as above.
460unsafe impl<T: ?Sized + Send> Send for MappedMutexGuard<'_, T> {}
461
462impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
463    /// The semaphore, once the guard is spent: unlocking is left to whoever
464    /// takes it over.
465    fn into_sem(self) -> &'a RawSemaphore {
466        ManuallyDrop::new(self).sem
467    }
468
469    /// A guard for a component of the component. It cannot fail: this guard
470    /// already holds the lock.
471    ///
472    /// An associated function, `MappedMutexGuard::map(guard, f)`: a method
473    /// would shadow methods of the locked data.
474    #[inline]
475    pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
476    where
477        U: ?Sized,
478        F: FnOnce(&mut T) -> &mut U,
479    {
480        let data = ptr::from_mut(f(&mut *this));
481        MappedMutexGuard {
482            sem: this.into_sem(),
483            data,
484            _value: PhantomData,
485        }
486    }
487
488    /// [`map`](Self::map) that gives the guard back when `f` finds no
489    /// component, with the lock still held.
490    #[inline]
491    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
492    where
493        U: ?Sized,
494        F: FnOnce(&mut T) -> Option<&mut U>,
495    {
496        let data = match f(&mut *this) {
497            Some(data) => ptr::from_mut(data),
498            None => return Err(this),
499        };
500        Ok(MappedMutexGuard {
501            sem: this.into_sem(),
502            data,
503            _value: PhantomData,
504        })
505    }
506}
507
508impl<T: ?Sized> Deref for MappedMutexGuard<'_, T> {
509    type Target = T;
510
511    fn deref(&self) -> &T {
512        // SAFETY: `data` points into the value of the mutex whose permit
513        // this guard holds.
514        unsafe { &*self.data }
515    }
516}
517
518impl<T: ?Sized> DerefMut for MappedMutexGuard<'_, T> {
519    fn deref_mut(&mut self) -> &mut T {
520        // SAFETY: as in `deref`, and `&mut self` makes this borrow unique.
521        unsafe { &mut *self.data }
522    }
523}
524
525impl<T: ?Sized> Drop for MappedMutexGuard<'_, T> {
526    #[inline]
527    fn drop(&mut self) {
528        self.sem.release(1);
529    }
530}
531
532impl<T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'_, T> {
533    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
534        fmt::Debug::fmt(&**self, f)
535    }
536}
537
538impl<T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'_, T> {
539    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
540        fmt::Display::fmt(&**self, f)
541    }
542}
543
544/// A guard for a component `U` of the value of a [`Mutex<T>`] held through
545/// an `Arc`, made by [`OwnedMutexGuard::map`]; unlocks on drop. The release
546/// makes the progress [`MutexGuard`]'s does.
547#[must_use = "dropping the guard unlocks the mutex at once"]
548pub struct OwnedMappedMutexGuard<T: ?Sized, U: ?Sized = T> {
549    mutex: Arc<Mutex<T>>,
550    data: *mut U,
551}
552
553// SAFETY: the guard hands out `&U` and `&mut U` into a value of the mutex it
554// holds the lock of, and carries the `Arc` that keeps the mutex alive.
555unsafe impl<T: ?Sized + Send + Sync, U: ?Sized + Send + Sync> Sync for OwnedMappedMutexGuard<T, U> {}
556// SAFETY: as above.
557unsafe impl<T: ?Sized + Send, U: ?Sized + Send> Send for OwnedMappedMutexGuard<T, U> {}
558
559impl<T: ?Sized, U: ?Sized> OwnedMappedMutexGuard<T, U> {
560    /// The `Arc`, once the guard is spent: unlocking is left to whoever
561    /// takes it over.
562    fn into_arc(self) -> Arc<Mutex<T>> {
563        let spent = ManuallyDrop::new(self);
564        // SAFETY: `spent` is never dropped, so this is the only read of the
565        // `Arc` and it is moved out exactly once.
566        unsafe { ptr::read(&spent.mutex) }
567    }
568
569    /// A guard for a component of the component. It cannot fail: this guard
570    /// already holds the lock.
571    ///
572    /// An associated function, `OwnedMappedMutexGuard::map(guard, f)`: a
573    /// method would shadow methods of the locked data.
574    #[inline]
575    pub fn map<S, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, S>
576    where
577        S: ?Sized,
578        F: FnOnce(&mut U) -> &mut S,
579    {
580        let data = ptr::from_mut(f(&mut *this));
581        OwnedMappedMutexGuard {
582            mutex: this.into_arc(),
583            data,
584        }
585    }
586
587    /// [`map`](Self::map) that gives the guard back when `f` finds no
588    /// component, with the lock still held.
589    #[inline]
590    pub fn try_map<S, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, S>, Self>
591    where
592        S: ?Sized,
593        F: FnOnce(&mut U) -> Option<&mut S>,
594    {
595        let data = match f(&mut *this) {
596            Some(data) => ptr::from_mut(data),
597            None => return Err(this),
598        };
599        Ok(OwnedMappedMutexGuard {
600            mutex: this.into_arc(),
601            data,
602        })
603    }
604}
605
606impl<T: ?Sized, U: ?Sized> Deref for OwnedMappedMutexGuard<T, U> {
607    type Target = U;
608
609    fn deref(&self) -> &U {
610        // SAFETY: `data` points into the value of the mutex whose permit
611        // this guard holds.
612        unsafe { &*self.data }
613    }
614}
615
616impl<T: ?Sized, U: ?Sized> DerefMut for OwnedMappedMutexGuard<T, U> {
617    fn deref_mut(&mut self) -> &mut U {
618        // SAFETY: as in `deref`, and `&mut self` makes this borrow unique.
619        unsafe { &mut *self.data }
620    }
621}
622
623impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U> {
624    #[inline]
625    fn drop(&mut self) {
626        self.mutex.sem.release(1);
627    }
628}
629
630impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedMappedMutexGuard<T, U> {
631    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
632        fmt::Debug::fmt(&**self, f)
633    }
634}
635
636impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedMappedMutexGuard<T, U> {
637    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
638        fmt::Display::fmt(&**self, f)
639    }
640}
641
642/// The future [`Mutex::lock`] returns.
643#[must_use = "futures do nothing unless polled"]
644pub struct Lock<'a, T: ?Sized> {
645    mutex: &'a Mutex<T>,
646    wait: PermitWait,
647}
648
649impl<'a, T: ?Sized> Future for Lock<'a, T> {
650    type Output = MutexGuard<'a, T>;
651
652    #[inline]
653    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<MutexGuard<'a, T>> {
654        let this = self.get_mut();
655        this.wait
656            .poll_one(&this.mutex.sem, cx.waker())
657            .map(|()| MutexGuard::new(this.mutex))
658    }
659}
660
661impl<T: ?Sized> Drop for Lock<'_, T> {
662    #[inline]
663    fn drop(&mut self) {
664        self.wait.cancel(&self.mutex.sem, 1);
665    }
666}
667
668impl<T: ?Sized> fmt::Debug for Lock<'_, T> {
669    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
670        f.debug_struct("Lock").finish_non_exhaustive()
671    }
672}
673
674/// The future [`Mutex::lock_owned`] returns.
675#[must_use = "futures do nothing unless polled"]
676pub struct LockOwned<T: ?Sized> {
677    mutex: Arc<Mutex<T>>,
678    wait: PermitWait,
679}
680
681impl<T: ?Sized> Future for LockOwned<T> {
682    type Output = OwnedMutexGuard<T>;
683
684    #[inline]
685    fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<OwnedMutexGuard<T>> {
686        let this = self.get_mut();
687        this.wait
688            .poll_one(&this.mutex.sem, cx.waker())
689            .map(|()| OwnedMutexGuard {
690                mutex: Arc::clone(&this.mutex),
691                _value: PhantomData,
692            })
693    }
694}
695
696impl<T: ?Sized> Drop for LockOwned<T> {
697    #[inline]
698    fn drop(&mut self) {
699        self.wait.cancel(&self.mutex.sem, 1);
700    }
701}
702
703impl<T: ?Sized> fmt::Debug for LockOwned<T> {
704    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
705        f.debug_struct("LockOwned").finish_non_exhaustive()
706    }
707}
708
709#[cfg(all(test, not(loom)))]
710mod tests {
711    use super::*;
712    use crate::sync::test_support::{Polled, block_on};
713
714    const ITERATIONS: usize = if cfg!(miri) { 20 } else { 5_000 };
715
716    /// A mutex built without spin queues its contended callers at once:
717    /// its budget is zero from the start and stays zero through a contended
718    /// wait, its wake and its retry, where a spinning mutex's starts above
719    /// zero.
720    #[test]
721    fn a_mutex_built_without_spin_never_spins() {
722        assert!(Mutex::new(()).spin_rounds() > 0, "a plain mutex spins");
723        let mutex = Mutex::new_without_spin(0u8);
724        assert_eq!(mutex.spin_rounds(), 0);
725        let held = mutex.try_lock().expect("free");
726        let mut waiter = Polled::new(mutex.lock());
727        waiter.pending();
728        drop(held);
729        assert_eq!(waiter.wakes(), 1);
730        *waiter.ready() += 1;
731        assert_eq!(mutex.spin_rounds(), 0, "the mutex never spins");
732    }
733
734    #[test]
735    fn releases_wake_waiters_in_arrival_order() {
736        let mutex = Mutex::new(Vec::new());
737        let held = mutex.try_lock().expect("free");
738        let mut waiters: Vec<_> = (0..3).map(|_| Polled::new(mutex.lock())).collect();
739        for waiter in &mut waiters {
740            waiter.pending();
741        }
742        drop(held);
743        for (i, waiter) in waiters.iter_mut().enumerate() {
744            assert_eq!(
745                waiter.wakes(),
746                1,
747                "waiter {i} is woken by the release before it"
748            );
749            let mut guard = waiter.ready();
750            guard.push(i);
751            assert!(mutex.try_lock().is_err(), "the woken waiter holds it");
752        }
753        assert_eq!(*mutex.try_lock().expect("free"), vec![0, 1, 2]);
754    }
755
756    #[test]
757    fn a_waiter_that_never_saw_its_grant_passes_the_lock_on() {
758        let mutex = Mutex::new(());
759        let held = mutex.try_lock().expect("free");
760        let mut first = Polled::new(mutex.lock());
761        first.pending();
762        let mut second = Polled::new(mutex.lock());
763        second.pending();
764        drop(held);
765        drop(first);
766        drop(second.ready());
767        assert!(mutex.try_lock().is_ok());
768    }
769
770    #[test]
771    fn a_waker_changed_between_polls_is_the_one_woken() {
772        let mutex = Mutex::new(());
773        let held = mutex.try_lock().expect("free");
774        let mut lock = core::pin::pin!(mutex.lock());
775        let first = Polled::new(core::future::pending::<()>());
776        let second = Polled::new(core::future::pending::<()>());
777        let poll_with = |lock: &mut Pin<&mut Lock<'_, ()>>, waker: &core::task::Waker| {
778            lock.as_mut()
779                .poll(&mut Context::from_waker(waker))
780                .is_pending()
781        };
782        let (first_waker, second_waker) = (first.waker(), second.waker());
783        assert!(poll_with(&mut lock, &first_waker));
784        assert!(poll_with(&mut lock, &second_waker));
785        drop(held);
786        assert_eq!((first.wakes(), second.wakes()), (0, 1));
787        assert!(!poll_with(&mut lock, &second_waker));
788    }
789
790    #[test]
791    fn owned_guards_and_get_mut() {
792        let mut mutex = Mutex::new(1);
793        *mutex.get_mut() += 1;
794        let mutex = Arc::new(mutex);
795        let guard = block_on(Arc::clone(&mutex).lock_owned());
796        let mut next = Polled::new(Arc::clone(&mutex).lock_owned());
797        next.pending();
798        assert_eq!(*guard, 2);
799        drop(guard);
800        assert_eq!(*next.ready(), 2);
801    }
802
803    #[test]
804    fn a_failed_try_lock_reports_it_would_block() {
805        let mutex = Arc::new(Mutex::new(0));
806        let held = Arc::clone(&mutex).try_lock_owned().expect("free");
807        let err = mutex.try_lock().unwrap_err();
808        assert_eq!(err.to_string(), "operation would block");
809        assert_eq!(format!("{err:?}"), "TryLockError(())");
810        assert!(Arc::clone(&mutex).try_lock_owned().is_err());
811        drop(held);
812        assert!(mutex.try_lock().is_ok());
813    }
814
815    #[test]
816    fn a_mapped_guard_keeps_the_lock_until_it_drops() {
817        let mutex = Arc::new(Mutex::new((1, String::from("a"))));
818        let mut number = MutexGuard::map(block_on(mutex.lock()), |pair| &mut pair.0);
819        *number += 1;
820        assert!(mutex.try_lock().is_err(), "the mapped guard holds the lock");
821        let mut waiter = Polled::new(mutex.lock());
822        waiter.pending();
823        drop(number);
824        assert_eq!(waiter.wakes(), 1);
825        assert_eq!(waiter.ready().0, 2);
826
827        let owned = OwnedMutexGuard::map(block_on(Arc::clone(&mutex).lock_owned()), |pair| {
828            &mut pair.1
829        });
830        let mut tail = OwnedMappedMutexGuard::map(owned, |text| text.as_mut_str());
831        tail.make_ascii_uppercase();
832        assert_eq!(&*tail, "A");
833        assert!(mutex.try_lock().is_err());
834        drop(tail);
835        assert_eq!(mutex.try_lock().expect("unlocked").1, "A");
836    }
837
838    #[test]
839    fn try_map_gives_the_guard_back_when_nothing_is_found() {
840        let mutex = Mutex::new(Some(5));
841        let guard = mutex.try_lock().expect("free");
842        let guard = MutexGuard::try_map(guard, |value| value.as_mut().filter(|n| **n > 9))
843            .expect_err("nothing to map");
844        assert!(mutex.try_lock().is_err(), "the lock is still held");
845        let mut mapped =
846            MutexGuard::try_map(guard, |value| value.as_mut()).expect("a five is there");
847        *mapped += 1;
848        let mapped = MappedMutexGuard::try_map(mapped, |n| (*n > 100).then_some(n))
849            .expect_err("six is small");
850        let mut mapped = MappedMutexGuard::map(mapped, |n| n);
851        *mapped += 1;
852        drop(mapped);
853        assert_eq!(mutex.into_inner(), Some(7));
854    }
855
856    #[test]
857    fn a_guard_names_its_mutex() {
858        let mutex = Arc::new(Mutex::new(3));
859        let guard = block_on(mutex.lock());
860        let same = MutexGuard::mutex(&guard);
861        assert!(core::ptr::eq(same, &*mutex));
862        drop(guard);
863        let owned = block_on(Arc::clone(&mutex).lock_owned());
864        assert!(Arc::ptr_eq(OwnedMutexGuard::mutex(&owned), &mutex));
865        assert_eq!(format!("{owned} {owned:?}"), "3 3");
866    }
867
868    #[test]
869    fn blocking_locks_wait_for_the_holder_on_another_thread() {
870        let mutex = Arc::new(Mutex::new(0));
871        let held = mutex.blocking_lock();
872        let waiter = {
873            let mutex = Arc::clone(&mutex);
874            std::thread::spawn(move || {
875                *mutex.blocking_lock() += 1;
876                *Arc::clone(&mutex).blocking_lock_owned() += 1;
877            })
878        };
879        drop(held);
880        waiter.join().expect("waiter");
881        assert_eq!(*mutex.try_lock().expect("free"), 2);
882    }
883
884    #[test]
885    fn a_const_mutex_and_conversions() {
886        static COUNTER: Mutex<u32> = Mutex::const_new(5);
887        *COUNTER.try_lock().expect("free") += 1;
888        assert_eq!(*COUNTER.try_lock().expect("free"), 6);
889        let from: Mutex<u8> = 9.into();
890        assert_eq!(from.into_inner(), 9);
891        assert_eq!(Mutex::<u8>::default().into_inner(), 0);
892        let mutex = Mutex::new(vec![1]);
893        assert_eq!(format!("{mutex:?}"), "Mutex { data: [1] }");
894        let held = mutex.try_lock().expect("free");
895        assert_eq!(format!("{mutex:?}"), "Mutex { data: <locked> }");
896        drop(held);
897    }
898
899    #[test]
900    fn threads_never_overlap_inside_the_lock() {
901        let mutex = Arc::new(Mutex::new(0usize));
902        let threads: Vec<_> = (0..4)
903            .map(|_| {
904                let mutex = Arc::clone(&mutex);
905                std::thread::spawn(move || {
906                    for _ in 0..ITERATIONS {
907                        let mut guard = block_on(mutex.lock());
908                        let seen = *guard;
909                        std::hint::spin_loop();
910                        *guard = seen + 1;
911                    }
912                })
913            })
914            .collect();
915        for thread in threads {
916            thread.join().expect("worker");
917        }
918        assert_eq!(*mutex.try_lock().expect("free"), 4 * ITERATIONS);
919    }
920}