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