tokio/sync/
mutex.rs

1#![cfg_attr(not(feature = "sync"), allow(unreachable_pub, dead_code))]
2
3use crate::sync::batch_semaphore as semaphore;
4#[cfg(all(tokio_unstable, feature = "tracing"))]
5use crate::util::trace;
6
7use std::cell::UnsafeCell;
8use std::error::Error;
9use std::marker::PhantomData;
10use std::ops::{Deref, DerefMut};
11use std::sync::Arc;
12use std::{fmt, mem, ptr};
13
14/// An asynchronous `Mutex`-like type.
15///
16/// This type acts similarly to [`std::sync::Mutex`], with two major
17/// differences: [`lock`] is an async method so does not block, and the lock
18/// guard is designed to be held across `.await` points.
19///
20/// Tokio's Mutex operates on a guaranteed FIFO basis.
21/// This means that the order in which tasks call the [`lock`] method is
22/// the exact order in which they will acquire the lock.
23///
24/// # Which kind of mutex should you use?
25///
26/// Contrary to popular belief, it is ok and often preferred to use the ordinary
27/// [`Mutex`][std] from the standard library in asynchronous code.
28///
29/// The feature that the async mutex offers over the blocking mutex is the
30/// ability to keep it locked across an `.await` point. This makes the async
31/// mutex more expensive than the blocking mutex, so the blocking mutex should
32/// be preferred in the cases where it can be used. The primary use case for the
33/// async mutex is to provide shared mutable access to IO resources such as a
34/// database connection. If the value behind the mutex is just data, it's
35/// usually appropriate to use a blocking mutex such as the one in the standard
36/// library or [`parking_lot`].
37///
38/// Note that, although the compiler will not prevent the std `Mutex` from holding
39/// its guard across `.await` points in situations where the task is not movable
40/// between threads, this virtually never leads to correct concurrent code in
41/// practice as it can easily lead to deadlocks.
42///
43/// A common pattern is to wrap the `Arc<Mutex<...>>` in a struct that provides
44/// non-async methods for performing operations on the data within, and only
45/// lock the mutex inside these methods. The [mini-redis] example provides an
46/// illustration of this pattern.
47///
48/// Additionally, when you _do_ want shared access to an IO resource, it is
49/// often better to spawn a task to manage the IO resource, and to use message
50/// passing to communicate with that task.
51///
52/// [std]: std::sync::Mutex
53/// [`parking_lot`]: https://docs.rs/parking_lot
54/// [mini-redis]: https://github.com/tokio-rs/mini-redis/blob/master/src/db.rs
55///
56/// # Examples:
57///
58/// ```rust,no_run
59/// use tokio::sync::Mutex;
60/// use std::sync::Arc;
61///
62/// #[tokio::main]
63/// async fn main() {
64///     let data1 = Arc::new(Mutex::new(0));
65///     let data2 = Arc::clone(&data1);
66///
67///     tokio::spawn(async move {
68///         let mut lock = data2.lock().await;
69///         *lock += 1;
70///     });
71///
72///     let mut lock = data1.lock().await;
73///     *lock += 1;
74/// }
75/// ```
76///
77///
78/// ```rust,no_run
79/// use tokio::sync::Mutex;
80/// use std::sync::Arc;
81///
82/// #[tokio::main]
83/// async fn main() {
84///     let count = Arc::new(Mutex::new(0));
85///
86///     for i in 0..5 {
87///         let my_count = Arc::clone(&count);
88///         tokio::spawn(async move {
89///             for j in 0..10 {
90///                 let mut lock = my_count.lock().await;
91///                 *lock += 1;
92///                 println!("{} {} {}", i, j, lock);
93///             }
94///         });
95///     }
96///
97///     loop {
98///         if *count.lock().await >= 50 {
99///             break;
100///         }
101///     }
102///     println!("Count hit 50.");
103/// }
104/// ```
105/// There are a few things of note here to pay attention to in this example.
106/// 1. The mutex is wrapped in an [`Arc`] to allow it to be shared across
107///    threads.
108/// 2. Each spawned task obtains a lock and releases it on every iteration.
109/// 3. Mutation of the data protected by the Mutex is done by de-referencing
110///    the obtained lock as seen on lines 13 and 20.
111///
112/// Tokio's Mutex works in a simple FIFO (first in, first out) style where all
113/// calls to [`lock`] complete in the order they were performed. In that way the
114/// Mutex is "fair" and predictable in how it distributes the locks to inner
115/// data. Locks are released and reacquired after every iteration, so basically,
116/// each thread goes to the back of the line after it increments the value once.
117/// Note that there's some unpredictability to the timing between when the
118/// threads are started, but once they are going they alternate predictably.
119/// Finally, since there is only a single valid lock at any given time, there is
120/// no possibility of a race condition when mutating the inner value.
121///
122/// Note that in contrast to [`std::sync::Mutex`], this implementation does not
123/// poison the mutex when a thread holding the [`MutexGuard`] panics. In such a
124/// case, the mutex will be unlocked. If the panic is caught, this might leave
125/// the data protected by the mutex in an inconsistent state.
126///
127/// [`Mutex`]: struct@Mutex
128/// [`MutexGuard`]: struct@MutexGuard
129/// [`Arc`]: struct@std::sync::Arc
130/// [`std::sync::Mutex`]: struct@std::sync::Mutex
131/// [`Send`]: trait@std::marker::Send
132/// [`lock`]: method@Mutex::lock
133pub struct Mutex<T: ?Sized> {
134    #[cfg(all(tokio_unstable, feature = "tracing"))]
135    resource_span: tracing::Span,
136    s: semaphore::Semaphore,
137    c: UnsafeCell<T>,
138}
139
140/// A handle to a held `Mutex`. The guard can be held across any `.await` point
141/// as it is [`Send`].
142///
143/// As long as you have this guard, you have exclusive access to the underlying
144/// `T`. The guard internally borrows the `Mutex`, so the mutex will not be
145/// dropped while a guard exists.
146///
147/// The lock is automatically released whenever the guard is dropped, at which
148/// point `lock` will succeed yet again.
149#[clippy::has_significant_drop]
150#[must_use = "if unused the Mutex will immediately unlock"]
151pub struct MutexGuard<'a, T: ?Sized> {
152    // When changing the fields in this struct, make sure to update the
153    // `skip_drop` method.
154    #[cfg(all(tokio_unstable, feature = "tracing"))]
155    resource_span: tracing::Span,
156    lock: &'a Mutex<T>,
157}
158
159/// An owned handle to a held `Mutex`.
160///
161/// This guard is only available from a `Mutex` that is wrapped in an [`Arc`]. It
162/// is identical to `MutexGuard`, except that rather than borrowing the `Mutex`,
163/// it clones the `Arc`, incrementing the reference count. This means that
164/// unlike `MutexGuard`, it will have the `'static` lifetime.
165///
166/// As long as you have this guard, you have exclusive access to the underlying
167/// `T`. The guard internally keeps a reference-counted pointer to the original
168/// `Mutex`, so even if the lock goes away, the guard remains valid.
169///
170/// The lock is automatically released whenever the guard is dropped, at which
171/// point `lock` will succeed yet again.
172///
173/// [`Arc`]: std::sync::Arc
174#[clippy::has_significant_drop]
175pub struct OwnedMutexGuard<T: ?Sized> {
176    // When changing the fields in this struct, make sure to update the
177    // `skip_drop` method.
178    #[cfg(all(tokio_unstable, feature = "tracing"))]
179    resource_span: tracing::Span,
180    lock: Arc<Mutex<T>>,
181}
182
183/// A handle to a held `Mutex` that has had a function applied to it via [`MutexGuard::map`].
184///
185/// This can be used to hold a subfield of the protected data.
186///
187/// [`MutexGuard::map`]: method@MutexGuard::map
188#[clippy::has_significant_drop]
189#[must_use = "if unused the Mutex will immediately unlock"]
190pub struct MappedMutexGuard<'a, T: ?Sized> {
191    // When changing the fields in this struct, make sure to update the
192    // `skip_drop` method.
193    #[cfg(all(tokio_unstable, feature = "tracing"))]
194    resource_span: tracing::Span,
195    s: &'a semaphore::Semaphore,
196    data: *mut T,
197    // Needed to tell the borrow checker that we are holding a `&mut T`
198    marker: PhantomData<&'a mut T>,
199}
200
201/// A owned handle to a held `Mutex` that has had a function applied to it via
202/// [`OwnedMutexGuard::map`].
203///
204/// This can be used to hold a subfield of the protected data.
205///
206/// [`OwnedMutexGuard::map`]: method@OwnedMutexGuard::map
207#[clippy::has_significant_drop]
208#[must_use = "if unused the Mutex will immediately unlock"]
209pub struct OwnedMappedMutexGuard<T: ?Sized, U: ?Sized = T> {
210    // When changing the fields in this struct, make sure to update the
211    // `skip_drop` method.
212    #[cfg(all(tokio_unstable, feature = "tracing"))]
213    resource_span: tracing::Span,
214    data: *mut U,
215    lock: Arc<Mutex<T>>,
216}
217
218/// A helper type used when taking apart a `MutexGuard` without running its
219/// Drop implementation.
220#[allow(dead_code)] // Unused fields are still used in Drop.
221struct MutexGuardInner<'a, T: ?Sized> {
222    #[cfg(all(tokio_unstable, feature = "tracing"))]
223    resource_span: tracing::Span,
224    lock: &'a Mutex<T>,
225}
226
227/// A helper type used when taking apart a `OwnedMutexGuard` without running
228/// its Drop implementation.
229struct OwnedMutexGuardInner<T: ?Sized> {
230    #[cfg(all(tokio_unstable, feature = "tracing"))]
231    resource_span: tracing::Span,
232    lock: Arc<Mutex<T>>,
233}
234
235/// A helper type used when taking apart a `MappedMutexGuard` without running
236/// its Drop implementation.
237#[allow(dead_code)] // Unused fields are still used in Drop.
238struct MappedMutexGuardInner<'a, T: ?Sized> {
239    #[cfg(all(tokio_unstable, feature = "tracing"))]
240    resource_span: tracing::Span,
241    s: &'a semaphore::Semaphore,
242    data: *mut T,
243}
244
245/// A helper type used when taking apart a `OwnedMappedMutexGuard` without running
246/// its Drop implementation.
247#[allow(dead_code)] // Unused fields are still used in Drop.
248struct OwnedMappedMutexGuardInner<T: ?Sized, U: ?Sized> {
249    #[cfg(all(tokio_unstable, feature = "tracing"))]
250    resource_span: tracing::Span,
251    data: *mut U,
252    lock: Arc<Mutex<T>>,
253}
254
255// As long as T: Send, it's fine to send and share Mutex<T> between threads.
256// If T was not Send, sending and sharing a Mutex<T> would be bad, since you can
257// access T through Mutex<T>.
258unsafe impl<T> Send for Mutex<T> where T: ?Sized + Send {}
259unsafe impl<T> Sync for Mutex<T> where T: ?Sized + Send {}
260unsafe impl<T> Sync for MutexGuard<'_, T> where T: ?Sized + Send + Sync {}
261unsafe impl<T> Sync for OwnedMutexGuard<T> where T: ?Sized + Send + Sync {}
262unsafe impl<'a, T> Sync for MappedMutexGuard<'a, T> where T: ?Sized + Sync + 'a {}
263unsafe impl<'a, T> Send for MappedMutexGuard<'a, T> where T: ?Sized + Send + 'a {}
264
265unsafe impl<T, U> Sync for OwnedMappedMutexGuard<T, U>
266where
267    T: ?Sized + Send + Sync,
268    U: ?Sized + Send + Sync,
269{
270}
271unsafe impl<T, U> Send for OwnedMappedMutexGuard<T, U>
272where
273    T: ?Sized + Send,
274    U: ?Sized + Send,
275{
276}
277
278/// Error returned from the [`Mutex::try_lock`], [`RwLock::try_read`] and
279/// [`RwLock::try_write`] functions.
280///
281/// `Mutex::try_lock` operation will only fail if the mutex is already locked.
282///
283/// `RwLock::try_read` operation will only fail if the lock is currently held
284/// by an exclusive writer.
285///
286/// `RwLock::try_write` operation will only fail if the lock is currently held
287/// by any reader or by an exclusive writer.
288///
289/// [`Mutex::try_lock`]: Mutex::try_lock
290/// [`RwLock::try_read`]: fn@super::RwLock::try_read
291/// [`RwLock::try_write`]: fn@super::RwLock::try_write
292#[derive(Debug)]
293pub struct TryLockError(pub(super) ());
294
295impl fmt::Display for TryLockError {
296    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
297        write!(fmt, "operation would block")
298    }
299}
300
301impl Error for TryLockError {}
302
303#[test]
304#[cfg(not(loom))]
305fn bounds() {
306    fn check_send<T: Send>() {}
307    fn check_unpin<T: Unpin>() {}
308    // This has to take a value, since the async fn's return type is unnameable.
309    fn check_send_sync_val<T: Send + Sync>(_t: T) {}
310    fn check_send_sync<T: Send + Sync>() {}
311    fn check_static<T: 'static>() {}
312    fn check_static_val<T: 'static>(_t: T) {}
313
314    check_send::<MutexGuard<'_, u32>>();
315    check_send::<OwnedMutexGuard<u32>>();
316    check_unpin::<Mutex<u32>>();
317    check_send_sync::<Mutex<u32>>();
318    check_static::<OwnedMutexGuard<u32>>();
319
320    let mutex = Mutex::new(1);
321    check_send_sync_val(mutex.lock());
322    let arc_mutex = Arc::new(Mutex::new(1));
323    check_send_sync_val(arc_mutex.clone().lock_owned());
324    check_static_val(arc_mutex.lock_owned());
325}
326
327impl<T: ?Sized> Mutex<T> {
328    /// Creates a new lock in an unlocked state ready for use.
329    ///
330    /// # Examples
331    ///
332    /// ```
333    /// use tokio::sync::Mutex;
334    ///
335    /// let lock = Mutex::new(5);
336    /// ```
337    #[track_caller]
338    pub fn new(t: T) -> Self
339    where
340        T: Sized,
341    {
342        #[cfg(all(tokio_unstable, feature = "tracing"))]
343        let resource_span = {
344            let location = std::panic::Location::caller();
345
346            tracing::trace_span!(
347                parent: None,
348                "runtime.resource",
349                concrete_type = "Mutex",
350                kind = "Sync",
351                loc.file = location.file(),
352                loc.line = location.line(),
353                loc.col = location.column(),
354            )
355        };
356
357        #[cfg(all(tokio_unstable, feature = "tracing"))]
358        let s = resource_span.in_scope(|| {
359            tracing::trace!(
360                target: "runtime::resource::state_update",
361                locked = false,
362            );
363            semaphore::Semaphore::new(1)
364        });
365
366        #[cfg(any(not(tokio_unstable), not(feature = "tracing")))]
367        let s = semaphore::Semaphore::new(1);
368
369        Self {
370            c: UnsafeCell::new(t),
371            s,
372            #[cfg(all(tokio_unstable, feature = "tracing"))]
373            resource_span,
374        }
375    }
376
377    /// Creates a new lock in an unlocked state ready for use.
378    ///
379    /// When using the `tracing` [unstable feature], a `Mutex` created with
380    /// `const_new` will not be instrumented. As such, it will not be visible
381    /// in [`tokio-console`]. Instead, [`Mutex::new`] should be used to create
382    /// an instrumented object if that is needed.
383    ///
384    /// # Examples
385    ///
386    /// ```
387    /// use tokio::sync::Mutex;
388    ///
389    /// static LOCK: Mutex<i32> = Mutex::const_new(5);
390    /// ```
391    ///
392    /// [`tokio-console`]: https://github.com/tokio-rs/console
393    /// [unstable feature]: crate#unstable-features
394    #[cfg(not(all(loom, test)))]
395    pub const fn const_new(t: T) -> Self
396    where
397        T: Sized,
398    {
399        Self {
400            c: UnsafeCell::new(t),
401            s: semaphore::Semaphore::const_new(1),
402            #[cfg(all(tokio_unstable, feature = "tracing"))]
403            resource_span: tracing::Span::none(),
404        }
405    }
406
407    /// Locks this mutex, causing the current task to yield until the lock has
408    /// been acquired.  When the lock has been acquired, function returns a
409    /// [`MutexGuard`].
410    ///
411    /// If the mutex is available to be acquired immediately, then this call
412    /// will typically not yield to the runtime. However, this is not guaranteed
413    /// under all circumstances.
414    ///
415    /// # Cancel safety
416    ///
417    /// This method uses a queue to fairly distribute locks in the order they
418    /// were requested. Cancelling a call to `lock` makes you lose your place in
419    /// the queue.
420    ///
421    /// # Examples
422    ///
423    /// ```
424    /// use tokio::sync::Mutex;
425    ///
426    /// #[tokio::main]
427    /// async fn main() {
428    ///     let mutex = Mutex::new(1);
429    ///
430    ///     let mut n = mutex.lock().await;
431    ///     *n = 2;
432    /// }
433    /// ```
434    pub async fn lock(&self) -> MutexGuard<'_, T> {
435        let acquire_fut = async {
436            self.acquire().await;
437
438            MutexGuard {
439                lock: self,
440                #[cfg(all(tokio_unstable, feature = "tracing"))]
441                resource_span: self.resource_span.clone(),
442            }
443        };
444
445        #[cfg(all(tokio_unstable, feature = "tracing"))]
446        let acquire_fut = trace::async_op(
447            move || acquire_fut,
448            self.resource_span.clone(),
449            "Mutex::lock",
450            "poll",
451            false,
452        );
453
454        #[allow(clippy::let_and_return)] // this lint triggers when disabling tracing
455        let guard = acquire_fut.await;
456
457        #[cfg(all(tokio_unstable, feature = "tracing"))]
458        self.resource_span.in_scope(|| {
459            tracing::trace!(
460                target: "runtime::resource::state_update",
461                locked = true,
462            );
463        });
464
465        guard
466    }
467
468    /// Blockingly locks this `Mutex`. When the lock has been acquired, function returns a
469    /// [`MutexGuard`].
470    ///
471    /// This method is intended for use cases where you
472    /// need to use this mutex in asynchronous code as well as in synchronous code.
473    ///
474    /// # Panics
475    ///
476    /// This function panics if called within an asynchronous execution context.
477    ///
478    ///   - If you find yourself in an asynchronous execution context and needing
479    ///     to call some (synchronous) function which performs one of these
480    ///     `blocking_` operations, then consider wrapping that call inside
481    ///     [`spawn_blocking()`][crate::runtime::Handle::spawn_blocking]
482    ///     (or [`block_in_place()`][crate::task::block_in_place]).
483    ///
484    /// # Examples
485    ///
486    /// ```
487    /// use std::sync::Arc;
488    /// use tokio::sync::Mutex;
489    ///
490    /// #[tokio::main]
491    /// async fn main() {
492    ///     let mutex =  Arc::new(Mutex::new(1));
493    ///     let lock = mutex.lock().await;
494    ///
495    ///     let mutex1 = Arc::clone(&mutex);
496    ///     let blocking_task = tokio::task::spawn_blocking(move || {
497    ///         // This shall block until the `lock` is released.
498    ///         let mut n = mutex1.blocking_lock();
499    ///         *n = 2;
500    ///     });
501    ///
502    ///     assert_eq!(*lock, 1);
503    ///     // Release the lock.
504    ///     drop(lock);
505    ///
506    ///     // Await the completion of the blocking task.
507    ///     blocking_task.await.unwrap();
508    ///
509    ///     // Assert uncontended.
510    ///     let n = mutex.try_lock().unwrap();
511    ///     assert_eq!(*n, 2);
512    /// }
513    ///
514    /// ```
515    #[track_caller]
516    #[cfg(feature = "sync")]
517    #[cfg_attr(docsrs, doc(alias = "lock_blocking"))]
518    pub fn blocking_lock(&self) -> MutexGuard<'_, T> {
519        crate::future::block_on(self.lock())
520    }
521
522    /// Blockingly locks this `Mutex`. When the lock has been acquired, function returns an
523    /// [`OwnedMutexGuard`].
524    ///
525    /// This method is identical to [`Mutex::blocking_lock`], except that the returned
526    /// guard references the `Mutex` with an [`Arc`] rather than by borrowing
527    /// it. Therefore, the `Mutex` must be wrapped in an `Arc` to call this
528    /// method, and the guard will live for the `'static` lifetime, as it keeps
529    /// the `Mutex` alive by holding an `Arc`.
530    ///
531    /// # Panics
532    ///
533    /// This function panics if called within an asynchronous execution context.
534    ///
535    ///   - If you find yourself in an asynchronous execution context and needing
536    ///     to call some (synchronous) function which performs one of these
537    ///     `blocking_` operations, then consider wrapping that call inside
538    ///     [`spawn_blocking()`][crate::runtime::Handle::spawn_blocking]
539    ///     (or [`block_in_place()`][crate::task::block_in_place]).
540    ///
541    /// # Examples
542    ///
543    /// ```
544    /// use std::sync::Arc;
545    /// use tokio::sync::Mutex;
546    ///
547    /// #[tokio::main]
548    /// async fn main() {
549    ///     let mutex =  Arc::new(Mutex::new(1));
550    ///     let lock = mutex.lock().await;
551    ///
552    ///     let mutex1 = Arc::clone(&mutex);
553    ///     let blocking_task = tokio::task::spawn_blocking(move || {
554    ///         // This shall block until the `lock` is released.
555    ///         let mut n = mutex1.blocking_lock_owned();
556    ///         *n = 2;
557    ///     });
558    ///
559    ///     assert_eq!(*lock, 1);
560    ///     // Release the lock.
561    ///     drop(lock);
562    ///
563    ///     // Await the completion of the blocking task.
564    ///     blocking_task.await.unwrap();
565    ///
566    ///     // Assert uncontended.
567    ///     let n = mutex.try_lock().unwrap();
568    ///     assert_eq!(*n, 2);
569    /// }
570    ///
571    /// ```
572    #[track_caller]
573    #[cfg(feature = "sync")]
574    pub fn blocking_lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
575        crate::future::block_on(self.lock_owned())
576    }
577
578    /// Locks this mutex, causing the current task to yield until the lock has
579    /// been acquired. When the lock has been acquired, this returns an
580    /// [`OwnedMutexGuard`].
581    ///
582    /// If the mutex is available to be acquired immediately, then this call
583    /// will typically not yield to the runtime. However, this is not guaranteed
584    /// under all circumstances.
585    ///
586    /// This method is identical to [`Mutex::lock`], except that the returned
587    /// guard references the `Mutex` with an [`Arc`] rather than by borrowing
588    /// it. Therefore, the `Mutex` must be wrapped in an `Arc` to call this
589    /// method, and the guard will live for the `'static` lifetime, as it keeps
590    /// the `Mutex` alive by holding an `Arc`.
591    ///
592    /// # Cancel safety
593    ///
594    /// This method uses a queue to fairly distribute locks in the order they
595    /// were requested. Cancelling a call to `lock_owned` makes you lose your
596    /// place in the queue.
597    ///
598    /// # Examples
599    ///
600    /// ```
601    /// use tokio::sync::Mutex;
602    /// use std::sync::Arc;
603    ///
604    /// #[tokio::main]
605    /// async fn main() {
606    ///     let mutex = Arc::new(Mutex::new(1));
607    ///
608    ///     let mut n = mutex.clone().lock_owned().await;
609    ///     *n = 2;
610    /// }
611    /// ```
612    ///
613    /// [`Arc`]: std::sync::Arc
614    pub async fn lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
615        #[cfg(all(tokio_unstable, feature = "tracing"))]
616        let resource_span = self.resource_span.clone();
617
618        let acquire_fut = async {
619            self.acquire().await;
620
621            OwnedMutexGuard {
622                #[cfg(all(tokio_unstable, feature = "tracing"))]
623                resource_span: self.resource_span.clone(),
624                lock: self,
625            }
626        };
627
628        #[cfg(all(tokio_unstable, feature = "tracing"))]
629        let acquire_fut = trace::async_op(
630            move || acquire_fut,
631            resource_span,
632            "Mutex::lock_owned",
633            "poll",
634            false,
635        );
636
637        #[allow(clippy::let_and_return)] // this lint triggers when disabling tracing
638        let guard = acquire_fut.await;
639
640        #[cfg(all(tokio_unstable, feature = "tracing"))]
641        guard.resource_span.in_scope(|| {
642            tracing::trace!(
643                target: "runtime::resource::state_update",
644                locked = true,
645            );
646        });
647
648        guard
649    }
650
651    async fn acquire(&self) {
652        crate::trace::async_trace_leaf().await;
653
654        self.s.acquire(1).await.unwrap_or_else(|_| {
655            // The semaphore was closed. but, we never explicitly close it, and
656            // we own it exclusively, which means that this can never happen.
657            unreachable!()
658        });
659    }
660
661    /// Attempts to acquire the lock, and returns [`TryLockError`] if the
662    /// lock is currently held somewhere else.
663    ///
664    /// [`TryLockError`]: TryLockError
665    /// # Examples
666    ///
667    /// ```
668    /// use tokio::sync::Mutex;
669    /// # async fn dox() -> Result<(), tokio::sync::TryLockError> {
670    ///
671    /// let mutex = Mutex::new(1);
672    ///
673    /// let n = mutex.try_lock()?;
674    /// assert_eq!(*n, 1);
675    /// # Ok(())
676    /// # }
677    /// ```
678    pub fn try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError> {
679        match self.s.try_acquire(1) {
680            Ok(()) => {
681                let guard = MutexGuard {
682                    lock: self,
683                    #[cfg(all(tokio_unstable, feature = "tracing"))]
684                    resource_span: self.resource_span.clone(),
685                };
686
687                #[cfg(all(tokio_unstable, feature = "tracing"))]
688                self.resource_span.in_scope(|| {
689                    tracing::trace!(
690                        target: "runtime::resource::state_update",
691                        locked = true,
692                    );
693                });
694
695                Ok(guard)
696            }
697            Err(_) => Err(TryLockError(())),
698        }
699    }
700
701    /// Returns a mutable reference to the underlying data.
702    ///
703    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
704    /// take place -- the mutable borrow statically guarantees no locks exist.
705    ///
706    /// # Examples
707    ///
708    /// ```
709    /// use tokio::sync::Mutex;
710    ///
711    /// fn main() {
712    ///     let mut mutex = Mutex::new(1);
713    ///
714    ///     let n = mutex.get_mut();
715    ///     *n = 2;
716    /// }
717    /// ```
718    pub fn get_mut(&mut self) -> &mut T {
719        unsafe {
720            // Safety: This is https://github.com/rust-lang/rust/pull/76936
721            &mut *self.c.get()
722        }
723    }
724
725    /// Attempts to acquire the lock, and returns [`TryLockError`] if the lock
726    /// is currently held somewhere else.
727    ///
728    /// This method is identical to [`Mutex::try_lock`], except that the
729    /// returned  guard references the `Mutex` with an [`Arc`] rather than by
730    /// borrowing it. Therefore, the `Mutex` must be wrapped in an `Arc` to call
731    /// this method, and the guard will live for the `'static` lifetime, as it
732    /// keeps the `Mutex` alive by holding an `Arc`.
733    ///
734    /// [`TryLockError`]: TryLockError
735    /// [`Arc`]: std::sync::Arc
736    /// # Examples
737    ///
738    /// ```
739    /// use tokio::sync::Mutex;
740    /// use std::sync::Arc;
741    /// # async fn dox() -> Result<(), tokio::sync::TryLockError> {
742    ///
743    /// let mutex = Arc::new(Mutex::new(1));
744    ///
745    /// let n = mutex.clone().try_lock_owned()?;
746    /// assert_eq!(*n, 1);
747    /// # Ok(())
748    /// # }
749    pub fn try_lock_owned(self: Arc<Self>) -> Result<OwnedMutexGuard<T>, TryLockError> {
750        match self.s.try_acquire(1) {
751            Ok(()) => {
752                let guard = OwnedMutexGuard {
753                    #[cfg(all(tokio_unstable, feature = "tracing"))]
754                    resource_span: self.resource_span.clone(),
755                    lock: self,
756                };
757
758                #[cfg(all(tokio_unstable, feature = "tracing"))]
759                guard.resource_span.in_scope(|| {
760                    tracing::trace!(
761                        target: "runtime::resource::state_update",
762                        locked = true,
763                    );
764                });
765
766                Ok(guard)
767            }
768            Err(_) => Err(TryLockError(())),
769        }
770    }
771
772    /// Consumes the mutex, returning the underlying data.
773    /// # Examples
774    ///
775    /// ```
776    /// use tokio::sync::Mutex;
777    ///
778    /// #[tokio::main]
779    /// async fn main() {
780    ///     let mutex = Mutex::new(1);
781    ///
782    ///     let n = mutex.into_inner();
783    ///     assert_eq!(n, 1);
784    /// }
785    /// ```
786    pub fn into_inner(self) -> T
787    where
788        T: Sized,
789    {
790        self.c.into_inner()
791    }
792}
793
794impl<T> From<T> for Mutex<T> {
795    fn from(s: T) -> Self {
796        Self::new(s)
797    }
798}
799
800impl<T> Default for Mutex<T>
801where
802    T: Default,
803{
804    fn default() -> Self {
805        Self::new(T::default())
806    }
807}
808
809impl<T: ?Sized> std::fmt::Debug for Mutex<T>
810where
811    T: std::fmt::Debug,
812{
813    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
814        let mut d = f.debug_struct("Mutex");
815        match self.try_lock() {
816            Ok(inner) => d.field("data", &&*inner),
817            Err(_) => d.field("data", &format_args!("<locked>")),
818        };
819        d.finish()
820    }
821}
822
823// === impl MutexGuard ===
824
825impl<'a, T: ?Sized> MutexGuard<'a, T> {
826    fn skip_drop(self) -> MutexGuardInner<'a, T> {
827        let me = mem::ManuallyDrop::new(self);
828        // SAFETY: This duplicates the `resource_span` and then forgets the
829        // original. In the end, we have not duplicated or forgotten any values.
830        MutexGuardInner {
831            #[cfg(all(tokio_unstable, feature = "tracing"))]
832            resource_span: unsafe { std::ptr::read(&me.resource_span) },
833            lock: me.lock,
834        }
835    }
836
837    /// Makes a new [`MappedMutexGuard`] for a component of the locked data.
838    ///
839    /// This operation cannot fail as the [`MutexGuard`] passed in already locked the mutex.
840    ///
841    /// This is an associated function that needs to be used as `MutexGuard::map(...)`. A method
842    /// would interfere with methods of the same name on the contents of the locked data.
843    ///
844    /// # Examples
845    ///
846    /// ```
847    /// use tokio::sync::{Mutex, MutexGuard};
848    ///
849    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
850    /// struct Foo(u32);
851    ///
852    /// # #[tokio::main]
853    /// # async fn main() {
854    /// let foo = Mutex::new(Foo(1));
855    ///
856    /// {
857    ///     let mut mapped = MutexGuard::map(foo.lock().await, |f| &mut f.0);
858    ///     *mapped = 2;
859    /// }
860    ///
861    /// assert_eq!(Foo(2), *foo.lock().await);
862    /// # }
863    /// ```
864    ///
865    /// [`MutexGuard`]: struct@MutexGuard
866    /// [`MappedMutexGuard`]: struct@MappedMutexGuard
867    #[inline]
868    pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
869    where
870        U: ?Sized,
871        F: FnOnce(&mut T) -> &mut U,
872    {
873        let data = f(&mut *this) as *mut U;
874        let inner = this.skip_drop();
875        MappedMutexGuard {
876            s: &inner.lock.s,
877            data,
878            marker: PhantomData,
879            #[cfg(all(tokio_unstable, feature = "tracing"))]
880            resource_span: inner.resource_span,
881        }
882    }
883
884    /// Attempts to make a new [`MappedMutexGuard`] for a component of the locked data. The
885    /// original guard is returned if the closure returns `None`.
886    ///
887    /// This operation cannot fail as the [`MutexGuard`] passed in already locked the mutex.
888    ///
889    /// This is an associated function that needs to be used as `MutexGuard::try_map(...)`. A
890    /// method would interfere with methods of the same name on the contents of the locked data.
891    ///
892    /// # Examples
893    ///
894    /// ```
895    /// use tokio::sync::{Mutex, MutexGuard};
896    ///
897    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
898    /// struct Foo(u32);
899    ///
900    /// # #[tokio::main]
901    /// # async fn main() {
902    /// let foo = Mutex::new(Foo(1));
903    ///
904    /// {
905    ///     let mut mapped = MutexGuard::try_map(foo.lock().await, |f| Some(&mut f.0))
906    ///         .expect("should not fail");
907    ///     *mapped = 2;
908    /// }
909    ///
910    /// assert_eq!(Foo(2), *foo.lock().await);
911    /// # }
912    /// ```
913    ///
914    /// [`MutexGuard`]: struct@MutexGuard
915    /// [`MappedMutexGuard`]: struct@MappedMutexGuard
916    #[inline]
917    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
918    where
919        U: ?Sized,
920        F: FnOnce(&mut T) -> Option<&mut U>,
921    {
922        let data = match f(&mut *this) {
923            Some(data) => data as *mut U,
924            None => return Err(this),
925        };
926        let inner = this.skip_drop();
927        Ok(MappedMutexGuard {
928            s: &inner.lock.s,
929            data,
930            marker: PhantomData,
931            #[cfg(all(tokio_unstable, feature = "tracing"))]
932            resource_span: inner.resource_span,
933        })
934    }
935
936    /// Returns a reference to the original `Mutex`.
937    ///
938    /// ```
939    /// use tokio::sync::{Mutex, MutexGuard};
940    ///
941    /// async fn unlock_and_relock<'l>(guard: MutexGuard<'l, u32>) -> MutexGuard<'l, u32> {
942    ///     println!("1. contains: {:?}", *guard);
943    ///     let mutex = MutexGuard::mutex(&guard);
944    ///     drop(guard);
945    ///     let guard = mutex.lock().await;
946    ///     println!("2. contains: {:?}", *guard);
947    ///     guard
948    /// }
949    /// #
950    /// # #[tokio::main]
951    /// # async fn main() {
952    /// #     let mutex = Mutex::new(0u32);
953    /// #     let guard = mutex.lock().await;
954    /// #     let _guard = unlock_and_relock(guard).await;
955    /// # }
956    /// ```
957    #[inline]
958    pub fn mutex(this: &Self) -> &'a Mutex<T> {
959        this.lock
960    }
961}
962
963impl<T: ?Sized> Drop for MutexGuard<'_, T> {
964    fn drop(&mut self) {
965        self.lock.s.release(1);
966
967        #[cfg(all(tokio_unstable, feature = "tracing"))]
968        self.resource_span.in_scope(|| {
969            tracing::trace!(
970                target: "runtime::resource::state_update",
971                locked = false,
972            );
973        });
974    }
975}
976
977impl<T: ?Sized> Deref for MutexGuard<'_, T> {
978    type Target = T;
979    fn deref(&self) -> &Self::Target {
980        unsafe { &*self.lock.c.get() }
981    }
982}
983
984impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
985    fn deref_mut(&mut self) -> &mut Self::Target {
986        unsafe { &mut *self.lock.c.get() }
987    }
988}
989
990impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
991    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
992        fmt::Debug::fmt(&**self, f)
993    }
994}
995
996impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
997    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
998        fmt::Display::fmt(&**self, f)
999    }
1000}
1001
1002// === impl OwnedMutexGuard ===
1003
1004impl<T: ?Sized> OwnedMutexGuard<T> {
1005    fn skip_drop(self) -> OwnedMutexGuardInner<T> {
1006        let me = mem::ManuallyDrop::new(self);
1007        // SAFETY: This duplicates the values in every field of the guard, then
1008        // forgets the originals, so in the end no value is duplicated.
1009        unsafe {
1010            OwnedMutexGuardInner {
1011                lock: ptr::read(&me.lock),
1012                #[cfg(all(tokio_unstable, feature = "tracing"))]
1013                resource_span: ptr::read(&me.resource_span),
1014            }
1015        }
1016    }
1017
1018    /// Makes a new [`OwnedMappedMutexGuard`] for a component of the locked data.
1019    ///
1020    /// This operation cannot fail as the [`OwnedMutexGuard`] passed in already locked the mutex.
1021    ///
1022    /// This is an associated function that needs to be used as `OwnedMutexGuard::map(...)`. A method
1023    /// would interfere with methods of the same name on the contents of the locked data.
1024    ///
1025    /// # Examples
1026    ///
1027    /// ```
1028    /// use tokio::sync::{Mutex, OwnedMutexGuard};
1029    /// use std::sync::Arc;
1030    ///
1031    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
1032    /// struct Foo(u32);
1033    ///
1034    /// # #[tokio::main]
1035    /// # async fn main() {
1036    /// let foo = Arc::new(Mutex::new(Foo(1)));
1037    ///
1038    /// {
1039    ///     let mut mapped = OwnedMutexGuard::map(foo.clone().lock_owned().await, |f| &mut f.0);
1040    ///     *mapped = 2;
1041    /// }
1042    ///
1043    /// assert_eq!(Foo(2), *foo.lock().await);
1044    /// # }
1045    /// ```
1046    ///
1047    /// [`OwnedMutexGuard`]: struct@OwnedMutexGuard
1048    /// [`OwnedMappedMutexGuard`]: struct@OwnedMappedMutexGuard
1049    #[inline]
1050    pub fn map<U, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, U>
1051    where
1052        U: ?Sized,
1053        F: FnOnce(&mut T) -> &mut U,
1054    {
1055        let data = f(&mut *this) as *mut U;
1056        let inner = this.skip_drop();
1057        OwnedMappedMutexGuard {
1058            data,
1059            lock: inner.lock,
1060            #[cfg(all(tokio_unstable, feature = "tracing"))]
1061            resource_span: inner.resource_span,
1062        }
1063    }
1064
1065    /// Attempts to make a new [`OwnedMappedMutexGuard`] for a component of the locked data. The
1066    /// original guard is returned if the closure returns `None`.
1067    ///
1068    /// This operation cannot fail as the [`OwnedMutexGuard`] passed in already locked the mutex.
1069    ///
1070    /// This is an associated function that needs to be used as `OwnedMutexGuard::try_map(...)`. A
1071    /// method would interfere with methods of the same name on the contents of the locked data.
1072    ///
1073    /// # Examples
1074    ///
1075    /// ```
1076    /// use tokio::sync::{Mutex, OwnedMutexGuard};
1077    /// use std::sync::Arc;
1078    ///
1079    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
1080    /// struct Foo(u32);
1081    ///
1082    /// # #[tokio::main]
1083    /// # async fn main() {
1084    /// let foo = Arc::new(Mutex::new(Foo(1)));
1085    ///
1086    /// {
1087    ///     let mut mapped = OwnedMutexGuard::try_map(foo.clone().lock_owned().await, |f| Some(&mut f.0))
1088    ///         .expect("should not fail");
1089    ///     *mapped = 2;
1090    /// }
1091    ///
1092    /// assert_eq!(Foo(2), *foo.lock().await);
1093    /// # }
1094    /// ```
1095    ///
1096    /// [`OwnedMutexGuard`]: struct@OwnedMutexGuard
1097    /// [`OwnedMappedMutexGuard`]: struct@OwnedMappedMutexGuard
1098    #[inline]
1099    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, U>, Self>
1100    where
1101        U: ?Sized,
1102        F: FnOnce(&mut T) -> Option<&mut U>,
1103    {
1104        let data = match f(&mut *this) {
1105            Some(data) => data as *mut U,
1106            None => return Err(this),
1107        };
1108        let inner = this.skip_drop();
1109        Ok(OwnedMappedMutexGuard {
1110            data,
1111            lock: inner.lock,
1112            #[cfg(all(tokio_unstable, feature = "tracing"))]
1113            resource_span: inner.resource_span,
1114        })
1115    }
1116
1117    /// Returns a reference to the original `Arc<Mutex>`.
1118    ///
1119    /// ```
1120    /// use std::sync::Arc;
1121    /// use tokio::sync::{Mutex, OwnedMutexGuard};
1122    ///
1123    /// async fn unlock_and_relock(guard: OwnedMutexGuard<u32>) -> OwnedMutexGuard<u32> {
1124    ///     println!("1. contains: {:?}", *guard);
1125    ///     let mutex: Arc<Mutex<u32>> = OwnedMutexGuard::mutex(&guard).clone();
1126    ///     drop(guard);
1127    ///     let guard = mutex.lock_owned().await;
1128    ///     println!("2. contains: {:?}", *guard);
1129    ///     guard
1130    /// }
1131    /// #
1132    /// # #[tokio::main]
1133    /// # async fn main() {
1134    /// #     let mutex = Arc::new(Mutex::new(0u32));
1135    /// #     let guard = mutex.lock_owned().await;
1136    /// #     unlock_and_relock(guard).await;
1137    /// # }
1138    /// ```
1139    #[inline]
1140    pub fn mutex(this: &Self) -> &Arc<Mutex<T>> {
1141        &this.lock
1142    }
1143}
1144
1145impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
1146    fn drop(&mut self) {
1147        self.lock.s.release(1);
1148
1149        #[cfg(all(tokio_unstable, feature = "tracing"))]
1150        self.resource_span.in_scope(|| {
1151            tracing::trace!(
1152                target: "runtime::resource::state_update",
1153                locked = false,
1154            );
1155        });
1156    }
1157}
1158
1159impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
1160    type Target = T;
1161    fn deref(&self) -> &Self::Target {
1162        unsafe { &*self.lock.c.get() }
1163    }
1164}
1165
1166impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
1167    fn deref_mut(&mut self) -> &mut Self::Target {
1168        unsafe { &mut *self.lock.c.get() }
1169    }
1170}
1171
1172impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
1173    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1174        fmt::Debug::fmt(&**self, f)
1175    }
1176}
1177
1178impl<T: ?Sized + fmt::Display> fmt::Display for OwnedMutexGuard<T> {
1179    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1180        fmt::Display::fmt(&**self, f)
1181    }
1182}
1183
1184// === impl MappedMutexGuard ===
1185
1186impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
1187    fn skip_drop(self) -> MappedMutexGuardInner<'a, T> {
1188        let me = mem::ManuallyDrop::new(self);
1189        MappedMutexGuardInner {
1190            s: me.s,
1191            data: me.data,
1192            #[cfg(all(tokio_unstable, feature = "tracing"))]
1193            resource_span: unsafe { std::ptr::read(&me.resource_span) },
1194        }
1195    }
1196
1197    /// Makes a new [`MappedMutexGuard`] for a component of the locked data.
1198    ///
1199    /// This operation cannot fail as the [`MappedMutexGuard`] passed in already locked the mutex.
1200    ///
1201    /// This is an associated function that needs to be used as `MappedMutexGuard::map(...)`. A
1202    /// method would interfere with methods of the same name on the contents of the locked data.
1203    ///
1204    /// [`MappedMutexGuard`]: struct@MappedMutexGuard
1205    #[inline]
1206    pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
1207    where
1208        F: FnOnce(&mut T) -> &mut U,
1209    {
1210        let data = f(&mut *this) as *mut U;
1211        let inner = this.skip_drop();
1212        MappedMutexGuard {
1213            s: inner.s,
1214            data,
1215            marker: PhantomData,
1216            #[cfg(all(tokio_unstable, feature = "tracing"))]
1217            resource_span: inner.resource_span,
1218        }
1219    }
1220
1221    /// Attempts to make a new [`MappedMutexGuard`] for a component of the locked data. The
1222    /// original guard is returned if the closure returns `None`.
1223    ///
1224    /// This operation cannot fail as the [`MappedMutexGuard`] passed in already locked the mutex.
1225    ///
1226    /// This is an associated function that needs to be used as `MappedMutexGuard::try_map(...)`. A
1227    /// method would interfere with methods of the same name on the contents of the locked data.
1228    ///
1229    /// [`MappedMutexGuard`]: struct@MappedMutexGuard
1230    #[inline]
1231    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
1232    where
1233        F: FnOnce(&mut T) -> Option<&mut U>,
1234    {
1235        let data = match f(&mut *this) {
1236            Some(data) => data as *mut U,
1237            None => return Err(this),
1238        };
1239        let inner = this.skip_drop();
1240        Ok(MappedMutexGuard {
1241            s: inner.s,
1242            data,
1243            marker: PhantomData,
1244            #[cfg(all(tokio_unstable, feature = "tracing"))]
1245            resource_span: inner.resource_span,
1246        })
1247    }
1248}
1249
1250impl<'a, T: ?Sized> Drop for MappedMutexGuard<'a, T> {
1251    fn drop(&mut self) {
1252        self.s.release(1);
1253
1254        #[cfg(all(tokio_unstable, feature = "tracing"))]
1255        self.resource_span.in_scope(|| {
1256            tracing::trace!(
1257                target: "runtime::resource::state_update",
1258                locked = false,
1259            );
1260        });
1261    }
1262}
1263
1264impl<'a, T: ?Sized> Deref for MappedMutexGuard<'a, T> {
1265    type Target = T;
1266    fn deref(&self) -> &Self::Target {
1267        unsafe { &*self.data }
1268    }
1269}
1270
1271impl<'a, T: ?Sized> DerefMut for MappedMutexGuard<'a, T> {
1272    fn deref_mut(&mut self) -> &mut Self::Target {
1273        unsafe { &mut *self.data }
1274    }
1275}
1276
1277impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'a, T> {
1278    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1279        fmt::Debug::fmt(&**self, f)
1280    }
1281}
1282
1283impl<'a, T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'a, T> {
1284    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1285        fmt::Display::fmt(&**self, f)
1286    }
1287}
1288
1289// === impl OwnedMappedMutexGuard ===
1290
1291impl<T: ?Sized, U: ?Sized> OwnedMappedMutexGuard<T, U> {
1292    fn skip_drop(self) -> OwnedMappedMutexGuardInner<T, U> {
1293        let me = mem::ManuallyDrop::new(self);
1294        // SAFETY: This duplicates the values in every field of the guard, then
1295        // forgets the originals, so in the end no value is duplicated.
1296        unsafe {
1297            OwnedMappedMutexGuardInner {
1298                data: me.data,
1299                lock: ptr::read(&me.lock),
1300                #[cfg(all(tokio_unstable, feature = "tracing"))]
1301                resource_span: ptr::read(&me.resource_span),
1302            }
1303        }
1304    }
1305
1306    /// Makes a new [`OwnedMappedMutexGuard`] for a component of the locked data.
1307    ///
1308    /// This operation cannot fail as the [`OwnedMappedMutexGuard`] passed in already locked the mutex.
1309    ///
1310    /// This is an associated function that needs to be used as `OwnedMappedMutexGuard::map(...)`. A method
1311    /// would interfere with methods of the same name on the contents of the locked data.
1312    ///
1313    /// [`OwnedMappedMutexGuard`]: struct@OwnedMappedMutexGuard
1314    #[inline]
1315    pub fn map<S, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, S>
1316    where
1317        F: FnOnce(&mut U) -> &mut S,
1318    {
1319        let data = f(&mut *this) as *mut S;
1320        let inner = this.skip_drop();
1321        OwnedMappedMutexGuard {
1322            data,
1323            lock: inner.lock,
1324            #[cfg(all(tokio_unstable, feature = "tracing"))]
1325            resource_span: inner.resource_span,
1326        }
1327    }
1328
1329    /// Attempts to make a new [`OwnedMappedMutexGuard`] for a component of the locked data. The
1330    /// original guard is returned if the closure returns `None`.
1331    ///
1332    /// This operation cannot fail as the [`OwnedMutexGuard`] passed in already locked the mutex.
1333    ///
1334    /// This is an associated function that needs to be used as `OwnedMutexGuard::try_map(...)`. A
1335    /// method would interfere with methods of the same name on the contents of the locked data.
1336    ///
1337    /// [`OwnedMutexGuard`]: struct@OwnedMutexGuard
1338    /// [`OwnedMappedMutexGuard`]: struct@OwnedMappedMutexGuard
1339    #[inline]
1340    pub fn try_map<S, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, S>, Self>
1341    where
1342        F: FnOnce(&mut U) -> Option<&mut S>,
1343    {
1344        let data = match f(&mut *this) {
1345            Some(data) => data as *mut S,
1346            None => return Err(this),
1347        };
1348        let inner = this.skip_drop();
1349        Ok(OwnedMappedMutexGuard {
1350            data,
1351            lock: inner.lock,
1352            #[cfg(all(tokio_unstable, feature = "tracing"))]
1353            resource_span: inner.resource_span,
1354        })
1355    }
1356}
1357
1358impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U> {
1359    fn drop(&mut self) {
1360        self.lock.s.release(1);
1361
1362        #[cfg(all(tokio_unstable, feature = "tracing"))]
1363        self.resource_span.in_scope(|| {
1364            tracing::trace!(
1365                target: "runtime::resource::state_update",
1366                locked = false,
1367            );
1368        });
1369    }
1370}
1371
1372impl<T: ?Sized, U: ?Sized> Deref for OwnedMappedMutexGuard<T, U> {
1373    type Target = U;
1374    fn deref(&self) -> &Self::Target {
1375        unsafe { &*self.data }
1376    }
1377}
1378
1379impl<T: ?Sized, U: ?Sized> DerefMut for OwnedMappedMutexGuard<T, U> {
1380    fn deref_mut(&mut self) -> &mut Self::Target {
1381        unsafe { &mut *self.data }
1382    }
1383}
1384
1385impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedMappedMutexGuard<T, U> {
1386    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1387        fmt::Debug::fmt(&**self, f)
1388    }
1389}
1390
1391impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedMappedMutexGuard<T, U> {
1392    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1393        fmt::Display::fmt(&**self, f)
1394    }
1395}