1 #![cfg_attr(not(feature = "sync"), allow(unreachable_pub, dead_code))]
2 
3 use crate::sync::batch_semaphore as semaphore;
4 #[cfg(all(tokio_unstable, feature = "tracing"))]
5 use crate::util::trace;
6 
7 use std::cell::UnsafeCell;
8 use std::error::Error;
9 use std::marker::PhantomData;
10 use std::ops::{Deref, DerefMut};
11 use std::sync::Arc;
12 use 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
133 pub 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"]
151 pub 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]
175 pub 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"]
190 pub 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"]
209 pub 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.
221 struct 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.
229 struct 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.
238 struct 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.
248 struct 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>.
258 unsafe impl<T> Send for Mutex<T> where T: ?Sized + Send {}
259 unsafe impl<T> Sync for Mutex<T> where T: ?Sized + Send {}
260 unsafe impl<T> Sync for MutexGuard<'_, T> where T: ?Sized + Send + Sync {}
261 unsafe impl<T> Sync for OwnedMutexGuard<T> where T: ?Sized + Send + Sync {}
262 unsafe impl<'a, T> Sync for MappedMutexGuard<'a, T> where T: ?Sized + Sync + 'a {}
263 unsafe impl<'a, T> Send for MappedMutexGuard<'a, T> where T: ?Sized + Send + 'a {}
264 
265 unsafe impl<T, U> Sync for OwnedMappedMutexGuard<T, U>
266 where
267     T: ?Sized + Send + Sync,
268     U: ?Sized + Send + Sync,
269 {
270 }
271 unsafe impl<T, U> Send for OwnedMappedMutexGuard<T, U>
272 where
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)]
293 pub struct TryLockError(pub(super) ());
294 
295 impl fmt::Display for TryLockError {
fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result296     fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
297         write!(fmt, "operation would block")
298     }
299 }
300 
301 impl Error for TryLockError {}
302 
303 #[test]
304 #[cfg(not(loom))]
bounds()305 fn 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 
327 impl<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]
new(t: T) -> Self where T: Sized,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)))]
const_new(t: T) -> Self where T: Sized,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     /// ```
lock(&self) -> MutexGuard<'_, T>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"))]
blocking_lock(&self) -> MutexGuard<'_, T>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")]
blocking_lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T>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
lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T>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 
acquire(&self)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     /// ```
try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError>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     /// ```
get_mut(&mut self) -> &mut T718     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     /// # }
try_lock_owned(self: Arc<Self>) -> Result<OwnedMutexGuard<T>, TryLockError>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     /// ```
into_inner(self) -> T where T: Sized,786     pub fn into_inner(self) -> T
787     where
788         T: Sized,
789     {
790         self.c.into_inner()
791     }
792 }
793 
794 impl<T> From<T> for Mutex<T> {
from(s: T) -> Self795     fn from(s: T) -> Self {
796         Self::new(s)
797     }
798 }
799 
800 impl<T> Default for Mutex<T>
801 where
802     T: Default,
803 {
default() -> Self804     fn default() -> Self {
805         Self::new(T::default())
806     }
807 }
808 
809 impl<T: ?Sized> std::fmt::Debug for Mutex<T>
810 where
811     T: std::fmt::Debug,
812 {
fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result813     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 
825 impl<'a, T: ?Sized> MutexGuard<'a, T> {
skip_drop(self) -> MutexGuardInner<'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]
map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U> where U: ?Sized, F: FnOnce(&mut T) -> &mut U,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]
try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self> where U: ?Sized, F: FnOnce(&mut T) -> Option<&mut U>,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]
mutex(this: &Self) -> &'a Mutex<T>958     pub fn mutex(this: &Self) -> &'a Mutex<T> {
959         this.lock
960     }
961 }
962 
963 impl<T: ?Sized> Drop for MutexGuard<'_, T> {
drop(&mut self)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 
977 impl<T: ?Sized> Deref for MutexGuard<'_, T> {
978     type Target = T;
deref(&self) -> &Self::Target979     fn deref(&self) -> &Self::Target {
980         unsafe { &*self.lock.c.get() }
981     }
982 }
983 
984 impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
deref_mut(&mut self) -> &mut Self::Target985     fn deref_mut(&mut self) -> &mut Self::Target {
986         unsafe { &mut *self.lock.c.get() }
987     }
988 }
989 
990 impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result991     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
992         fmt::Debug::fmt(&**self, f)
993     }
994 }
995 
996 impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result997     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
998         fmt::Display::fmt(&**self, f)
999     }
1000 }
1001 
1002 // === impl OwnedMutexGuard ===
1003 
1004 impl<T: ?Sized> OwnedMutexGuard<T> {
skip_drop(self) -> OwnedMutexGuardInner<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]
map<U, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, U> where U: ?Sized, F: FnOnce(&mut T) -> &mut U,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]
try_map<U, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, U>, Self> where U: ?Sized, F: FnOnce(&mut T) -> Option<&mut U>,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]
mutex(this: &Self) -> &Arc<Mutex<T>>1140     pub fn mutex(this: &Self) -> &Arc<Mutex<T>> {
1141         &this.lock
1142     }
1143 }
1144 
1145 impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
drop(&mut self)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 
1159 impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
1160     type Target = T;
deref(&self) -> &Self::Target1161     fn deref(&self) -> &Self::Target {
1162         unsafe { &*self.lock.c.get() }
1163     }
1164 }
1165 
1166 impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
deref_mut(&mut self) -> &mut Self::Target1167     fn deref_mut(&mut self) -> &mut Self::Target {
1168         unsafe { &mut *self.lock.c.get() }
1169     }
1170 }
1171 
1172 impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1173     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1174         fmt::Debug::fmt(&**self, f)
1175     }
1176 }
1177 
1178 impl<T: ?Sized + fmt::Display> fmt::Display for OwnedMutexGuard<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1179     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1180         fmt::Display::fmt(&**self, f)
1181     }
1182 }
1183 
1184 // === impl MappedMutexGuard ===
1185 
1186 impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
skip_drop(self) -> MappedMutexGuardInner<'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]
map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U> where F: FnOnce(&mut T) -> &mut U,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]
try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self> where F: FnOnce(&mut T) -> Option<&mut U>,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 
1250 impl<'a, T: ?Sized> Drop for MappedMutexGuard<'a, T> {
drop(&mut self)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 
1264 impl<'a, T: ?Sized> Deref for MappedMutexGuard<'a, T> {
1265     type Target = T;
deref(&self) -> &Self::Target1266     fn deref(&self) -> &Self::Target {
1267         unsafe { &*self.data }
1268     }
1269 }
1270 
1271 impl<'a, T: ?Sized> DerefMut for MappedMutexGuard<'a, T> {
deref_mut(&mut self) -> &mut Self::Target1272     fn deref_mut(&mut self) -> &mut Self::Target {
1273         unsafe { &mut *self.data }
1274     }
1275 }
1276 
1277 impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'a, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1278     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1279         fmt::Debug::fmt(&**self, f)
1280     }
1281 }
1282 
1283 impl<'a, T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'a, T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1284     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1285         fmt::Display::fmt(&**self, f)
1286     }
1287 }
1288 
1289 // === impl OwnedMappedMutexGuard ===
1290 
1291 impl<T: ?Sized, U: ?Sized> OwnedMappedMutexGuard<T, U> {
skip_drop(self) -> OwnedMappedMutexGuardInner<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]
map<S, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, S> where F: FnOnce(&mut U) -> &mut S,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]
try_map<S, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, S>, Self> where F: FnOnce(&mut U) -> Option<&mut S>,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 
1358 impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U> {
drop(&mut self)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 
1372 impl<T: ?Sized, U: ?Sized> Deref for OwnedMappedMutexGuard<T, U> {
1373     type Target = U;
deref(&self) -> &Self::Target1374     fn deref(&self) -> &Self::Target {
1375         unsafe { &*self.data }
1376     }
1377 }
1378 
1379 impl<T: ?Sized, U: ?Sized> DerefMut for OwnedMappedMutexGuard<T, U> {
deref_mut(&mut self) -> &mut Self::Target1380     fn deref_mut(&mut self) -> &mut Self::Target {
1381         unsafe { &mut *self.data }
1382     }
1383 }
1384 
1385 impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedMappedMutexGuard<T, U> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1386     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1387         fmt::Debug::fmt(&**self, f)
1388     }
1389 }
1390 
1391 impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedMappedMutexGuard<T, U> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result1392     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1393         fmt::Display::fmt(&**self, f)
1394     }
1395 }
1396