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