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