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(flavor = "current_thread")]
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(flavor = "current_thread")]
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(flavor = "current_thread")]
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    /// # #[cfg(not(target_family = "wasm"))]
488    /// # {
489    /// use std::sync::Arc;
490    /// use tokio::sync::Mutex;
491    ///
492    /// #[tokio::main]
493    /// async fn main() {
494    ///     let mutex =  Arc::new(Mutex::new(1));
495    ///     let lock = mutex.lock().await;
496    ///
497    ///     let mutex1 = Arc::clone(&mutex);
498    ///     let blocking_task = tokio::task::spawn_blocking(move || {
499    ///         // This shall block until the `lock` is released.
500    ///         let mut n = mutex1.blocking_lock();
501    ///         *n = 2;
502    ///     });
503    ///
504    ///     assert_eq!(*lock, 1);
505    ///     // Release the lock.
506    ///     drop(lock);
507    ///
508    ///     // Await the completion of the blocking task.
509    ///     blocking_task.await.unwrap();
510    ///
511    ///     // Assert uncontended.
512    ///     let n = mutex.try_lock().unwrap();
513    ///     assert_eq!(*n, 2);
514    /// }
515    /// # }
516    /// ```
517    #[track_caller]
518    #[cfg(feature = "sync")]
519    #[cfg_attr(docsrs, doc(alias = "lock_blocking"))]
520    pub fn blocking_lock(&self) -> MutexGuard<'_, T> {
521        crate::future::block_on(self.lock())
522    }
523
524    /// Blockingly locks this `Mutex`. When the lock has been acquired, function returns an
525    /// [`OwnedMutexGuard`].
526    ///
527    /// This method is identical to [`Mutex::blocking_lock`], except that the returned
528    /// guard references the `Mutex` with an [`Arc`] rather than by borrowing
529    /// it. Therefore, the `Mutex` must be wrapped in an `Arc` to call this
530    /// method, and the guard will live for the `'static` lifetime, as it keeps
531    /// the `Mutex` alive by holding an `Arc`.
532    ///
533    /// # Panics
534    ///
535    /// This function panics if called within an asynchronous execution context.
536    ///
537    ///   - If you find yourself in an asynchronous execution context and needing
538    ///     to call some (synchronous) function which performs one of these
539    ///     `blocking_` operations, then consider wrapping that call inside
540    ///     [`spawn_blocking()`][crate::runtime::Handle::spawn_blocking]
541    ///     (or [`block_in_place()`][crate::task::block_in_place]).
542    ///
543    /// # Examples
544    ///
545    /// ```
546    /// # #[cfg(not(target_family = "wasm"))]
547    /// # {
548    /// use std::sync::Arc;
549    /// use tokio::sync::Mutex;
550    ///
551    /// #[tokio::main]
552    /// async fn main() {
553    ///     let mutex =  Arc::new(Mutex::new(1));
554    ///     let lock = mutex.lock().await;
555    ///
556    ///     let mutex1 = Arc::clone(&mutex);
557    ///     let blocking_task = tokio::task::spawn_blocking(move || {
558    ///         // This shall block until the `lock` is released.
559    ///         let mut n = mutex1.blocking_lock_owned();
560    ///         *n = 2;
561    ///     });
562    ///
563    ///     assert_eq!(*lock, 1);
564    ///     // Release the lock.
565    ///     drop(lock);
566    ///
567    ///     // Await the completion of the blocking task.
568    ///     blocking_task.await.unwrap();
569    ///
570    ///     // Assert uncontended.
571    ///     let n = mutex.try_lock().unwrap();
572    ///     assert_eq!(*n, 2);
573    /// }
574    /// # }
575    /// ```
576    #[track_caller]
577    #[cfg(feature = "sync")]
578    pub fn blocking_lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
579        crate::future::block_on(self.lock_owned())
580    }
581
582    /// Locks this mutex, causing the current task to yield until the lock has
583    /// been acquired. When the lock has been acquired, this returns an
584    /// [`OwnedMutexGuard`].
585    ///
586    /// If the mutex is available to be acquired immediately, then this call
587    /// will typically not yield to the runtime. However, this is not guaranteed
588    /// under all circumstances.
589    ///
590    /// This method is identical to [`Mutex::lock`], except that the returned
591    /// guard references the `Mutex` with an [`Arc`] rather than by borrowing
592    /// it. Therefore, the `Mutex` must be wrapped in an `Arc` to call this
593    /// method, and the guard will live for the `'static` lifetime, as it keeps
594    /// the `Mutex` alive by holding an `Arc`.
595    ///
596    /// # Cancel safety
597    ///
598    /// This method uses a queue to fairly distribute locks in the order they
599    /// were requested. Cancelling a call to `lock_owned` makes you lose your
600    /// place in the queue.
601    ///
602    /// # Examples
603    ///
604    /// ```
605    /// use tokio::sync::Mutex;
606    /// use std::sync::Arc;
607    ///
608    /// # #[tokio::main(flavor = "current_thread")]
609    /// # async fn main() {
610    /// let mutex = Arc::new(Mutex::new(1));
611    ///
612    /// let mut n = mutex.clone().lock_owned().await;
613    /// *n = 2;
614    /// # }
615    /// ```
616    ///
617    /// [`Arc`]: std::sync::Arc
618    pub async fn lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
619        #[cfg(all(tokio_unstable, feature = "tracing"))]
620        let resource_span = self.resource_span.clone();
621
622        let acquire_fut = async {
623            self.acquire().await;
624
625            OwnedMutexGuard {
626                #[cfg(all(tokio_unstable, feature = "tracing"))]
627                resource_span: self.resource_span.clone(),
628                lock: self,
629            }
630        };
631
632        #[cfg(all(tokio_unstable, feature = "tracing"))]
633        let acquire_fut = trace::async_op(
634            move || acquire_fut,
635            resource_span,
636            "Mutex::lock_owned",
637            "poll",
638            false,
639        );
640
641        #[allow(clippy::let_and_return)] // this lint triggers when disabling tracing
642        let guard = acquire_fut.await;
643
644        #[cfg(all(tokio_unstable, feature = "tracing"))]
645        guard.resource_span.in_scope(|| {
646            tracing::trace!(
647                target: "runtime::resource::state_update",
648                locked = true,
649            );
650        });
651
652        guard
653    }
654
655    async fn acquire(&self) {
656        crate::trace::async_trace_leaf().await;
657
658        self.s.acquire(1).await.unwrap_or_else(|_| {
659            // The semaphore was closed. but, we never explicitly close it, and
660            // we own it exclusively, which means that this can never happen.
661            unreachable!()
662        });
663    }
664
665    /// Attempts to acquire the lock, and returns [`TryLockError`] if the
666    /// lock is currently held somewhere else.
667    ///
668    /// [`TryLockError`]: TryLockError
669    /// # Examples
670    ///
671    /// ```
672    /// use tokio::sync::Mutex;
673    /// # async fn dox() -> Result<(), tokio::sync::TryLockError> {
674    ///
675    /// let mutex = Mutex::new(1);
676    ///
677    /// let n = mutex.try_lock()?;
678    /// assert_eq!(*n, 1);
679    /// # Ok(())
680    /// # }
681    /// ```
682    pub fn try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError> {
683        match self.s.try_acquire(1) {
684            Ok(()) => {
685                let guard = MutexGuard {
686                    lock: self,
687                    #[cfg(all(tokio_unstable, feature = "tracing"))]
688                    resource_span: self.resource_span.clone(),
689                };
690
691                #[cfg(all(tokio_unstable, feature = "tracing"))]
692                self.resource_span.in_scope(|| {
693                    tracing::trace!(
694                        target: "runtime::resource::state_update",
695                        locked = true,
696                    );
697                });
698
699                Ok(guard)
700            }
701            Err(_) => Err(TryLockError(())),
702        }
703    }
704
705    /// Returns a mutable reference to the underlying data.
706    ///
707    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
708    /// take place -- the mutable borrow statically guarantees no locks exist.
709    ///
710    /// # Examples
711    ///
712    /// ```
713    /// use tokio::sync::Mutex;
714    ///
715    /// fn main() {
716    ///     let mut mutex = Mutex::new(1);
717    ///
718    ///     let n = mutex.get_mut();
719    ///     *n = 2;
720    /// }
721    /// ```
722    pub fn get_mut(&mut self) -> &mut T {
723        self.c.get_mut()
724    }
725
726    /// Attempts to acquire the lock, and returns [`TryLockError`] if the lock
727    /// is currently held somewhere else.
728    ///
729    /// This method is identical to [`Mutex::try_lock`], except that the
730    /// returned  guard references the `Mutex` with an [`Arc`] rather than by
731    /// borrowing it. Therefore, the `Mutex` must be wrapped in an `Arc` to call
732    /// this method, and the guard will live for the `'static` lifetime, as it
733    /// keeps the `Mutex` alive by holding an `Arc`.
734    ///
735    /// [`TryLockError`]: TryLockError
736    /// [`Arc`]: std::sync::Arc
737    /// # Examples
738    ///
739    /// ```
740    /// use tokio::sync::Mutex;
741    /// use std::sync::Arc;
742    /// # async fn dox() -> Result<(), tokio::sync::TryLockError> {
743    ///
744    /// let mutex = Arc::new(Mutex::new(1));
745    ///
746    /// let n = mutex.clone().try_lock_owned()?;
747    /// assert_eq!(*n, 1);
748    /// # Ok(())
749    /// # }
750    pub fn try_lock_owned(self: Arc<Self>) -> Result<OwnedMutexGuard<T>, TryLockError> {
751        match self.s.try_acquire(1) {
752            Ok(()) => {
753                let guard = OwnedMutexGuard {
754                    #[cfg(all(tokio_unstable, feature = "tracing"))]
755                    resource_span: self.resource_span.clone(),
756                    lock: self,
757                };
758
759                #[cfg(all(tokio_unstable, feature = "tracing"))]
760                guard.resource_span.in_scope(|| {
761                    tracing::trace!(
762                        target: "runtime::resource::state_update",
763                        locked = true,
764                    );
765                });
766
767                Ok(guard)
768            }
769            Err(_) => Err(TryLockError(())),
770        }
771    }
772
773    /// Consumes the mutex, returning the underlying data.
774    /// # Examples
775    ///
776    /// ```
777    /// use tokio::sync::Mutex;
778    ///
779    /// # #[tokio::main(flavor = "current_thread")]
780    /// # async fn main() {
781    /// let mutex = Mutex::new(1);
782    ///
783    /// let n = mutex.into_inner();
784    /// assert_eq!(n, 1);
785    /// # }
786    /// ```
787    pub fn into_inner(self) -> T
788    where
789        T: Sized,
790    {
791        self.c.into_inner()
792    }
793}
794
795impl<T> From<T> for Mutex<T> {
796    fn from(s: T) -> Self {
797        Self::new(s)
798    }
799}
800
801impl<T> Default for Mutex<T>
802where
803    T: Default,
804{
805    fn default() -> Self {
806        Self::new(T::default())
807    }
808}
809
810impl<T: ?Sized> std::fmt::Debug for Mutex<T>
811where
812    T: std::fmt::Debug,
813{
814    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
815        let mut d = f.debug_struct("Mutex");
816        match self.try_lock() {
817            Ok(inner) => d.field("data", &&*inner),
818            Err(_) => d.field("data", &format_args!("<locked>")),
819        };
820        d.finish()
821    }
822}
823
824// === impl MutexGuard ===
825
826impl<'a, T: ?Sized> MutexGuard<'a, T> {
827    fn skip_drop(self) -> MutexGuardInner<'a, T> {
828        let me = mem::ManuallyDrop::new(self);
829        // SAFETY: This duplicates the `resource_span` and then forgets the
830        // original. In the end, we have not duplicated or forgotten any values.
831        MutexGuardInner {
832            #[cfg(all(tokio_unstable, feature = "tracing"))]
833            resource_span: unsafe { std::ptr::read(&me.resource_span) },
834            lock: me.lock,
835        }
836    }
837
838    /// Makes a new [`MappedMutexGuard`] for a component of the locked data.
839    ///
840    /// This operation cannot fail as the [`MutexGuard`] passed in already locked the mutex.
841    ///
842    /// This is an associated function that needs to be used as `MutexGuard::map(...)`. A method
843    /// would interfere with methods of the same name on the contents of the locked data.
844    ///
845    /// # Examples
846    ///
847    /// ```
848    /// use tokio::sync::{Mutex, MutexGuard};
849    ///
850    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
851    /// struct Foo(u32);
852    ///
853    /// # #[tokio::main(flavor = "current_thread")]
854    /// # async fn main() {
855    /// let foo = Mutex::new(Foo(1));
856    ///
857    /// {
858    ///     let mut mapped = MutexGuard::map(foo.lock().await, |f| &mut f.0);
859    ///     *mapped = 2;
860    /// }
861    ///
862    /// assert_eq!(Foo(2), *foo.lock().await);
863    /// # }
864    /// ```
865    ///
866    /// [`MutexGuard`]: struct@MutexGuard
867    /// [`MappedMutexGuard`]: struct@MappedMutexGuard
868    #[inline]
869    pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
870    where
871        U: ?Sized,
872        F: FnOnce(&mut T) -> &mut U,
873    {
874        let data = f(&mut *this) as *mut U;
875        let inner = this.skip_drop();
876        MappedMutexGuard {
877            s: &inner.lock.s,
878            data,
879            marker: PhantomData,
880            #[cfg(all(tokio_unstable, feature = "tracing"))]
881            resource_span: inner.resource_span,
882        }
883    }
884
885    /// Attempts to make a new [`MappedMutexGuard`] for a component of the locked data. The
886    /// original guard is returned if the closure returns `None`.
887    ///
888    /// This operation cannot fail as the [`MutexGuard`] passed in already locked the mutex.
889    ///
890    /// This is an associated function that needs to be used as `MutexGuard::try_map(...)`. A
891    /// method would interfere with methods of the same name on the contents of the locked data.
892    ///
893    /// # Examples
894    ///
895    /// ```
896    /// use tokio::sync::{Mutex, MutexGuard};
897    ///
898    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
899    /// struct Foo(u32);
900    ///
901    /// # #[tokio::main(flavor = "current_thread")]
902    /// # async fn main() {
903    /// let foo = Mutex::new(Foo(1));
904    ///
905    /// {
906    ///     let mut mapped = MutexGuard::try_map(foo.lock().await, |f| Some(&mut f.0))
907    ///         .expect("should not fail");
908    ///     *mapped = 2;
909    /// }
910    ///
911    /// assert_eq!(Foo(2), *foo.lock().await);
912    /// # }
913    /// ```
914    ///
915    /// [`MutexGuard`]: struct@MutexGuard
916    /// [`MappedMutexGuard`]: struct@MappedMutexGuard
917    #[inline]
918    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
919    where
920        U: ?Sized,
921        F: FnOnce(&mut T) -> Option<&mut U>,
922    {
923        let data = match f(&mut *this) {
924            Some(data) => data as *mut U,
925            None => return Err(this),
926        };
927        let inner = this.skip_drop();
928        Ok(MappedMutexGuard {
929            s: &inner.lock.s,
930            data,
931            marker: PhantomData,
932            #[cfg(all(tokio_unstable, feature = "tracing"))]
933            resource_span: inner.resource_span,
934        })
935    }
936
937    /// Returns a reference to the original `Mutex`.
938    ///
939    /// ```
940    /// use tokio::sync::{Mutex, MutexGuard};
941    ///
942    /// async fn unlock_and_relock<'l>(guard: MutexGuard<'l, u32>) -> MutexGuard<'l, u32> {
943    ///     println!("1. contains: {:?}", *guard);
944    ///     let mutex = MutexGuard::mutex(&guard);
945    ///     drop(guard);
946    ///     let guard = mutex.lock().await;
947    ///     println!("2. contains: {:?}", *guard);
948    ///     guard
949    /// }
950    /// #
951    /// # #[tokio::main(flavor = "current_thread")]
952    /// # async fn main() {
953    /// #     let mutex = Mutex::new(0u32);
954    /// #     let guard = mutex.lock().await;
955    /// #     let _guard = unlock_and_relock(guard).await;
956    /// # }
957    /// ```
958    #[inline]
959    pub fn mutex(this: &Self) -> &'a Mutex<T> {
960        this.lock
961    }
962}
963
964impl<T: ?Sized> Drop for MutexGuard<'_, T> {
965    fn drop(&mut self) {
966        self.lock.s.release(1);
967
968        #[cfg(all(tokio_unstable, feature = "tracing"))]
969        self.resource_span.in_scope(|| {
970            tracing::trace!(
971                target: "runtime::resource::state_update",
972                locked = false,
973            );
974        });
975    }
976}
977
978impl<T: ?Sized> Deref for MutexGuard<'_, T> {
979    type Target = T;
980    fn deref(&self) -> &Self::Target {
981        unsafe { &*self.lock.c.get() }
982    }
983}
984
985impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
986    fn deref_mut(&mut self) -> &mut Self::Target {
987        unsafe { &mut *self.lock.c.get() }
988    }
989}
990
991impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
992    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
993        fmt::Debug::fmt(&**self, f)
994    }
995}
996
997impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
998    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
999        fmt::Display::fmt(&**self, f)
1000    }
1001}
1002
1003// === impl OwnedMutexGuard ===
1004
1005impl<T: ?Sized> OwnedMutexGuard<T> {
1006    fn skip_drop(self) -> OwnedMutexGuardInner<T> {
1007        let me = mem::ManuallyDrop::new(self);
1008        // SAFETY: This duplicates the values in every field of the guard, then
1009        // forgets the originals, so in the end no value is duplicated.
1010        unsafe {
1011            OwnedMutexGuardInner {
1012                lock: ptr::read(&me.lock),
1013                #[cfg(all(tokio_unstable, feature = "tracing"))]
1014                resource_span: ptr::read(&me.resource_span),
1015            }
1016        }
1017    }
1018
1019    /// Makes a new [`OwnedMappedMutexGuard`] for a component of the locked data.
1020    ///
1021    /// This operation cannot fail as the [`OwnedMutexGuard`] passed in already locked the mutex.
1022    ///
1023    /// This is an associated function that needs to be used as `OwnedMutexGuard::map(...)`. A method
1024    /// would interfere with methods of the same name on the contents of the locked data.
1025    ///
1026    /// # Examples
1027    ///
1028    /// ```
1029    /// use tokio::sync::{Mutex, OwnedMutexGuard};
1030    /// use std::sync::Arc;
1031    ///
1032    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
1033    /// struct Foo(u32);
1034    ///
1035    /// # #[tokio::main(flavor = "current_thread")]
1036    /// # async fn main() {
1037    /// let foo = Arc::new(Mutex::new(Foo(1)));
1038    ///
1039    /// {
1040    ///     let mut mapped = OwnedMutexGuard::map(foo.clone().lock_owned().await, |f| &mut f.0);
1041    ///     *mapped = 2;
1042    /// }
1043    ///
1044    /// assert_eq!(Foo(2), *foo.lock().await);
1045    /// # }
1046    /// ```
1047    ///
1048    /// [`OwnedMutexGuard`]: struct@OwnedMutexGuard
1049    /// [`OwnedMappedMutexGuard`]: struct@OwnedMappedMutexGuard
1050    #[inline]
1051    pub fn map<U, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, U>
1052    where
1053        U: ?Sized,
1054        F: FnOnce(&mut T) -> &mut U,
1055    {
1056        let data = f(&mut *this) as *mut U;
1057        let inner = this.skip_drop();
1058        OwnedMappedMutexGuard {
1059            data,
1060            lock: inner.lock,
1061            #[cfg(all(tokio_unstable, feature = "tracing"))]
1062            resource_span: inner.resource_span,
1063        }
1064    }
1065
1066    /// Attempts to make a new [`OwnedMappedMutexGuard`] for a component of the locked data. The
1067    /// original guard is returned if the closure returns `None`.
1068    ///
1069    /// This operation cannot fail as the [`OwnedMutexGuard`] passed in already locked the mutex.
1070    ///
1071    /// This is an associated function that needs to be used as `OwnedMutexGuard::try_map(...)`. A
1072    /// method would interfere with methods of the same name on the contents of the locked data.
1073    ///
1074    /// # Examples
1075    ///
1076    /// ```
1077    /// use tokio::sync::{Mutex, OwnedMutexGuard};
1078    /// use std::sync::Arc;
1079    ///
1080    /// #[derive(Debug, Clone, Copy, PartialEq, Eq)]
1081    /// struct Foo(u32);
1082    ///
1083    /// # #[tokio::main(flavor = "current_thread")]
1084    /// # async fn main() {
1085    /// let foo = Arc::new(Mutex::new(Foo(1)));
1086    ///
1087    /// {
1088    ///     let mut mapped = OwnedMutexGuard::try_map(foo.clone().lock_owned().await, |f| Some(&mut f.0))
1089    ///         .expect("should not fail");
1090    ///     *mapped = 2;
1091    /// }
1092    ///
1093    /// assert_eq!(Foo(2), *foo.lock().await);
1094    /// # }
1095    /// ```
1096    ///
1097    /// [`OwnedMutexGuard`]: struct@OwnedMutexGuard
1098    /// [`OwnedMappedMutexGuard`]: struct@OwnedMappedMutexGuard
1099    #[inline]
1100    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, U>, Self>
1101    where
1102        U: ?Sized,
1103        F: FnOnce(&mut T) -> Option<&mut U>,
1104    {
1105        let data = match f(&mut *this) {
1106            Some(data) => data as *mut U,
1107            None => return Err(this),
1108        };
1109        let inner = this.skip_drop();
1110        Ok(OwnedMappedMutexGuard {
1111            data,
1112            lock: inner.lock,
1113            #[cfg(all(tokio_unstable, feature = "tracing"))]
1114            resource_span: inner.resource_span,
1115        })
1116    }
1117
1118    /// Returns a reference to the original `Arc<Mutex>`.
1119    ///
1120    /// ```
1121    /// use std::sync::Arc;
1122    /// use tokio::sync::{Mutex, OwnedMutexGuard};
1123    ///
1124    /// async fn unlock_and_relock(guard: OwnedMutexGuard<u32>) -> OwnedMutexGuard<u32> {
1125    ///     println!("1. contains: {:?}", *guard);
1126    ///     let mutex: Arc<Mutex<u32>> = OwnedMutexGuard::mutex(&guard).clone();
1127    ///     drop(guard);
1128    ///     let guard = mutex.lock_owned().await;
1129    ///     println!("2. contains: {:?}", *guard);
1130    ///     guard
1131    /// }
1132    /// #
1133    /// # #[tokio::main(flavor = "current_thread")]
1134    /// # async fn main() {
1135    /// #     let mutex = Arc::new(Mutex::new(0u32));
1136    /// #     let guard = mutex.lock_owned().await;
1137    /// #     unlock_and_relock(guard).await;
1138    /// # }
1139    /// ```
1140    #[inline]
1141    pub fn mutex(this: &Self) -> &Arc<Mutex<T>> {
1142        &this.lock
1143    }
1144}
1145
1146impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
1147    fn drop(&mut self) {
1148        self.lock.s.release(1);
1149
1150        #[cfg(all(tokio_unstable, feature = "tracing"))]
1151        self.resource_span.in_scope(|| {
1152            tracing::trace!(
1153                target: "runtime::resource::state_update",
1154                locked = false,
1155            );
1156        });
1157    }
1158}
1159
1160impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
1161    type Target = T;
1162    fn deref(&self) -> &Self::Target {
1163        unsafe { &*self.lock.c.get() }
1164    }
1165}
1166
1167impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
1168    fn deref_mut(&mut self) -> &mut Self::Target {
1169        unsafe { &mut *self.lock.c.get() }
1170    }
1171}
1172
1173impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
1174    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1175        fmt::Debug::fmt(&**self, f)
1176    }
1177}
1178
1179impl<T: ?Sized + fmt::Display> fmt::Display for OwnedMutexGuard<T> {
1180    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1181        fmt::Display::fmt(&**self, f)
1182    }
1183}
1184
1185// === impl MappedMutexGuard ===
1186
1187impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
1188    fn skip_drop(self) -> MappedMutexGuardInner<'a, T> {
1189        let me = mem::ManuallyDrop::new(self);
1190        MappedMutexGuardInner {
1191            s: me.s,
1192            data: me.data,
1193            #[cfg(all(tokio_unstable, feature = "tracing"))]
1194            resource_span: unsafe { std::ptr::read(&me.resource_span) },
1195        }
1196    }
1197
1198    /// Makes a new [`MappedMutexGuard`] for a component of the locked data.
1199    ///
1200    /// This operation cannot fail as the [`MappedMutexGuard`] passed in already locked the mutex.
1201    ///
1202    /// This is an associated function that needs to be used as `MappedMutexGuard::map(...)`. A
1203    /// method would interfere with methods of the same name on the contents of the locked data.
1204    ///
1205    /// [`MappedMutexGuard`]: struct@MappedMutexGuard
1206    #[inline]
1207    pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
1208    where
1209        F: FnOnce(&mut T) -> &mut U,
1210    {
1211        let data = f(&mut *this) as *mut U;
1212        let inner = this.skip_drop();
1213        MappedMutexGuard {
1214            s: inner.s,
1215            data,
1216            marker: PhantomData,
1217            #[cfg(all(tokio_unstable, feature = "tracing"))]
1218            resource_span: inner.resource_span,
1219        }
1220    }
1221
1222    /// Attempts to make a new [`MappedMutexGuard`] for a component of the locked data. The
1223    /// original guard is returned if the closure returns `None`.
1224    ///
1225    /// This operation cannot fail as the [`MappedMutexGuard`] passed in already locked the mutex.
1226    ///
1227    /// This is an associated function that needs to be used as `MappedMutexGuard::try_map(...)`. A
1228    /// method would interfere with methods of the same name on the contents of the locked data.
1229    ///
1230    /// [`MappedMutexGuard`]: struct@MappedMutexGuard
1231    #[inline]
1232    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
1233    where
1234        F: FnOnce(&mut T) -> Option<&mut U>,
1235    {
1236        let data = match f(&mut *this) {
1237            Some(data) => data as *mut U,
1238            None => return Err(this),
1239        };
1240        let inner = this.skip_drop();
1241        Ok(MappedMutexGuard {
1242            s: inner.s,
1243            data,
1244            marker: PhantomData,
1245            #[cfg(all(tokio_unstable, feature = "tracing"))]
1246            resource_span: inner.resource_span,
1247        })
1248    }
1249}
1250
1251impl<'a, T: ?Sized> Drop for MappedMutexGuard<'a, T> {
1252    fn drop(&mut self) {
1253        self.s.release(1);
1254
1255        #[cfg(all(tokio_unstable, feature = "tracing"))]
1256        self.resource_span.in_scope(|| {
1257            tracing::trace!(
1258                target: "runtime::resource::state_update",
1259                locked = false,
1260            );
1261        });
1262    }
1263}
1264
1265impl<'a, T: ?Sized> Deref for MappedMutexGuard<'a, T> {
1266    type Target = T;
1267    fn deref(&self) -> &Self::Target {
1268        unsafe { &*self.data }
1269    }
1270}
1271
1272impl<'a, T: ?Sized> DerefMut for MappedMutexGuard<'a, T> {
1273    fn deref_mut(&mut self) -> &mut Self::Target {
1274        unsafe { &mut *self.data }
1275    }
1276}
1277
1278impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'a, T> {
1279    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1280        fmt::Debug::fmt(&**self, f)
1281    }
1282}
1283
1284impl<'a, T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'a, T> {
1285    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1286        fmt::Display::fmt(&**self, f)
1287    }
1288}
1289
1290// === impl OwnedMappedMutexGuard ===
1291
1292impl<T: ?Sized, U: ?Sized> OwnedMappedMutexGuard<T, U> {
1293    fn skip_drop(self) -> OwnedMappedMutexGuardInner<T, U> {
1294        let me = mem::ManuallyDrop::new(self);
1295        // SAFETY: This duplicates the values in every field of the guard, then
1296        // forgets the originals, so in the end no value is duplicated.
1297        unsafe {
1298            OwnedMappedMutexGuardInner {
1299                data: me.data,
1300                lock: ptr::read(&me.lock),
1301                #[cfg(all(tokio_unstable, feature = "tracing"))]
1302                resource_span: ptr::read(&me.resource_span),
1303            }
1304        }
1305    }
1306
1307    /// Makes a new [`OwnedMappedMutexGuard`] for a component of the locked data.
1308    ///
1309    /// This operation cannot fail as the [`OwnedMappedMutexGuard`] passed in already locked the mutex.
1310    ///
1311    /// This is an associated function that needs to be used as `OwnedMappedMutexGuard::map(...)`. A method
1312    /// would interfere with methods of the same name on the contents of the locked data.
1313    ///
1314    /// [`OwnedMappedMutexGuard`]: struct@OwnedMappedMutexGuard
1315    #[inline]
1316    pub fn map<S, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, S>
1317    where
1318        F: FnOnce(&mut U) -> &mut S,
1319    {
1320        let data = f(&mut *this) as *mut S;
1321        let inner = this.skip_drop();
1322        OwnedMappedMutexGuard {
1323            data,
1324            lock: inner.lock,
1325            #[cfg(all(tokio_unstable, feature = "tracing"))]
1326            resource_span: inner.resource_span,
1327        }
1328    }
1329
1330    /// Attempts to make a new [`OwnedMappedMutexGuard`] for a component of the locked data. The
1331    /// original guard is returned if the closure returns `None`.
1332    ///
1333    /// This operation cannot fail as the [`OwnedMutexGuard`] passed in already locked the mutex.
1334    ///
1335    /// This is an associated function that needs to be used as `OwnedMutexGuard::try_map(...)`. A
1336    /// method would interfere with methods of the same name on the contents of the locked data.
1337    ///
1338    /// [`OwnedMutexGuard`]: struct@OwnedMutexGuard
1339    /// [`OwnedMappedMutexGuard`]: struct@OwnedMappedMutexGuard
1340    #[inline]
1341    pub fn try_map<S, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, S>, Self>
1342    where
1343        F: FnOnce(&mut U) -> Option<&mut S>,
1344    {
1345        let data = match f(&mut *this) {
1346            Some(data) => data as *mut S,
1347            None => return Err(this),
1348        };
1349        let inner = this.skip_drop();
1350        Ok(OwnedMappedMutexGuard {
1351            data,
1352            lock: inner.lock,
1353            #[cfg(all(tokio_unstable, feature = "tracing"))]
1354            resource_span: inner.resource_span,
1355        })
1356    }
1357}
1358
1359impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U> {
1360    fn drop(&mut self) {
1361        self.lock.s.release(1);
1362
1363        #[cfg(all(tokio_unstable, feature = "tracing"))]
1364        self.resource_span.in_scope(|| {
1365            tracing::trace!(
1366                target: "runtime::resource::state_update",
1367                locked = false,
1368            );
1369        });
1370    }
1371}
1372
1373impl<T: ?Sized, U: ?Sized> Deref for OwnedMappedMutexGuard<T, U> {
1374    type Target = U;
1375    fn deref(&self) -> &Self::Target {
1376        unsafe { &*self.data }
1377    }
1378}
1379
1380impl<T: ?Sized, U: ?Sized> DerefMut for OwnedMappedMutexGuard<T, U> {
1381    fn deref_mut(&mut self) -> &mut Self::Target {
1382        unsafe { &mut *self.data }
1383    }
1384}
1385
1386impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedMappedMutexGuard<T, U> {
1387    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1388        fmt::Debug::fmt(&**self, f)
1389    }
1390}
1391
1392impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedMappedMutexGuard<T, U> {
1393    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1394        fmt::Display::fmt(&**self, f)
1395    }
1396}