Coverage Report

Created: 2025-10-10 07:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/tokio-1.47.1/src/sync/mutex.rs
Line
Count
Source
1
#![cfg_attr(not(feature = "sync"), allow(unreachable_pub, dead_code))]
2
3
use crate::sync::batch_semaphore as semaphore;
4
#[cfg(all(tokio_unstable, feature = "tracing"))]
5
use crate::util::trace;
6
7
use std::cell::UnsafeCell;
8
use std::error::Error;
9
use std::marker::PhantomData;
10
use std::ops::{Deref, DerefMut};
11
use std::sync::Arc;
12
use std::{fmt, mem, ptr};
13
14
/// An asynchronous `Mutex`-like type.
15
///
16
/// This type acts similarly to [`std::sync::Mutex`], with two major
17
/// differences: [`lock`] is an async method so does not block, and the lock
18
/// guard is designed to be held across `.await` points.
19
///
20
/// Tokio's Mutex operates on a guaranteed FIFO basis.
21
/// This means that the order in which tasks call the [`lock`] method is
22
/// the exact order in which they will acquire the lock.
23
///
24
/// # Which kind of mutex should you use?
25
///
26
/// Contrary to popular belief, it is ok and often preferred to use the ordinary
27
/// [`Mutex`][std] from the standard library in asynchronous code.
28
///
29
/// The feature that the async mutex offers over the blocking mutex is the
30
/// ability to keep it locked across an `.await` point. This makes the async
31
/// mutex more expensive than the blocking mutex, so the blocking mutex should
32
/// be preferred in the cases where it can be used. The primary use case for the
33
/// async mutex is to provide shared mutable access to IO resources such as a
34
/// database connection. If the value behind the mutex is just data, it's
35
/// usually appropriate to use a blocking mutex such as the one in the standard
36
/// library or [`parking_lot`].
37
///
38
/// Note that, although the compiler will not prevent the std `Mutex` from holding
39
/// its guard across `.await` points in situations where the task is not movable
40
/// between threads, this virtually never leads to correct concurrent code in
41
/// practice as it can easily lead to deadlocks.
42
///
43
/// A common pattern is to wrap the `Arc<Mutex<...>>` in a struct that provides
44
/// non-async methods for performing operations on the data within, and only
45
/// lock the mutex inside these methods. The [mini-redis] example provides an
46
/// illustration of this pattern.
47
///
48
/// Additionally, when you _do_ want shared access to an IO resource, it is
49
/// often better to spawn a task to manage the IO resource, and to use message
50
/// passing to communicate with that task.
51
///
52
/// [std]: std::sync::Mutex
53
/// [`parking_lot`]: https://docs.rs/parking_lot
54
/// [mini-redis]: https://github.com/tokio-rs/mini-redis/blob/master/src/db.rs
55
///
56
/// # Examples:
57
///
58
/// ```rust,no_run
59
/// use tokio::sync::Mutex;
60
/// use std::sync::Arc;
61
///
62
/// #[tokio::main]
63
/// async fn main() {
64
///     let data1 = Arc::new(Mutex::new(0));
65
///     let data2 = Arc::clone(&data1);
66
///
67
///     tokio::spawn(async move {
68
///         let mut lock = data2.lock().await;
69
///         *lock += 1;
70
///     });
71
///
72
///     let mut lock = data1.lock().await;
73
///     *lock += 1;
74
/// }
75
/// ```
76
///
77
///
78
/// ```rust,no_run
79
/// use tokio::sync::Mutex;
80
/// use std::sync::Arc;
81
///
82
/// #[tokio::main]
83
/// async fn main() {
84
///     let count = Arc::new(Mutex::new(0));
85
///
86
///     for i in 0..5 {
87
///         let my_count = Arc::clone(&count);
88
///         tokio::spawn(async move {
89
///             for j in 0..10 {
90
///                 let mut lock = my_count.lock().await;
91
///                 *lock += 1;
92
///                 println!("{} {} {}", i, j, lock);
93
///             }
94
///         });
95
///     }
96
///
97
///     loop {
98
///         if *count.lock().await >= 50 {
99
///             break;
100
///         }
101
///     }
102
///     println!("Count hit 50.");
103
/// }
104
/// ```
105
/// There are a few things of note here to pay attention to in this example.
106
/// 1. The mutex is wrapped in an [`Arc`] to allow it to be shared across
107
///    threads.
108
/// 2. Each spawned task obtains a lock and releases it on every iteration.
109
/// 3. Mutation of the data protected by the Mutex is done by de-referencing
110
///    the obtained lock as seen on lines 13 and 20.
111
///
112
/// Tokio's Mutex works in a simple FIFO (first in, first out) style where all
113
/// calls to [`lock`] complete in the order they were performed. In that way the
114
/// Mutex is "fair" and predictable in how it distributes the locks to inner
115
/// data. Locks are released and reacquired after every iteration, so basically,
116
/// each thread goes to the back of the line after it increments the value once.
117
/// Note that there's some unpredictability to the timing between when the
118
/// threads are started, but once they are going they alternate predictably.
119
/// Finally, since there is only a single valid lock at any given time, there is
120
/// no possibility of a race condition when mutating the inner value.
121
///
122
/// Note that in contrast to [`std::sync::Mutex`], this implementation does not
123
/// poison the mutex when a thread holding the [`MutexGuard`] panics. In such a
124
/// case, the mutex will be unlocked. If the panic is caught, this might leave
125
/// the data protected by the mutex in an inconsistent state.
126
///
127
/// [`Mutex`]: struct@Mutex
128
/// [`MutexGuard`]: struct@MutexGuard
129
/// [`Arc`]: struct@std::sync::Arc
130
/// [`std::sync::Mutex`]: struct@std::sync::Mutex
131
/// [`Send`]: trait@std::marker::Send
132
/// [`lock`]: method@Mutex::lock
133
pub struct Mutex<T: ?Sized> {
134
    #[cfg(all(tokio_unstable, feature = "tracing"))]
135
    resource_span: tracing::Span,
136
    s: semaphore::Semaphore,
137
    c: UnsafeCell<T>,
138
}
139
140
/// A handle to a held `Mutex`. The guard can be held across any `.await` point
141
/// as it is [`Send`].
142
///
143
/// As long as you have this guard, you have exclusive access to the underlying
144
/// `T`. The guard internally borrows the `Mutex`, so the mutex will not be
145
/// dropped while a guard exists.
146
///
147
/// The lock is automatically released whenever the guard is dropped, at which
148
/// point `lock` will succeed yet again.
149
#[clippy::has_significant_drop]
150
#[must_use = "if unused the Mutex will immediately unlock"]
151
pub struct MutexGuard<'a, T: ?Sized> {
152
    // When changing the fields in this struct, make sure to update the
153
    // `skip_drop` method.
154
    #[cfg(all(tokio_unstable, feature = "tracing"))]
155
    resource_span: tracing::Span,
156
    lock: &'a Mutex<T>,
157
}
158
159
/// An owned handle to a held `Mutex`.
160
///
161
/// This guard is only available from a `Mutex` that is wrapped in an [`Arc`]. It
162
/// is identical to `MutexGuard`, except that rather than borrowing the `Mutex`,
163
/// it clones the `Arc`, incrementing the reference count. This means that
164
/// unlike `MutexGuard`, it will have the `'static` lifetime.
165
///
166
/// As long as you have this guard, you have exclusive access to the underlying
167
/// `T`. The guard internally keeps a reference-counted pointer to the original
168
/// `Mutex`, so even if the lock goes away, the guard remains valid.
169
///
170
/// The lock is automatically released whenever the guard is dropped, at which
171
/// point `lock` will succeed yet again.
172
///
173
/// [`Arc`]: std::sync::Arc
174
#[clippy::has_significant_drop]
175
pub struct OwnedMutexGuard<T: ?Sized> {
176
    // When changing the fields in this struct, make sure to update the
177
    // `skip_drop` method.
178
    #[cfg(all(tokio_unstable, feature = "tracing"))]
179
    resource_span: tracing::Span,
180
    lock: Arc<Mutex<T>>,
181
}
182
183
/// A handle to a held `Mutex` that has had a function applied to it via [`MutexGuard::map`].
184
///
185
/// This can be used to hold a subfield of the protected data.
186
///
187
/// [`MutexGuard::map`]: method@MutexGuard::map
188
#[clippy::has_significant_drop]
189
#[must_use = "if unused the Mutex will immediately unlock"]
190
pub struct MappedMutexGuard<'a, T: ?Sized> {
191
    // When changing the fields in this struct, make sure to update the
192
    // `skip_drop` method.
193
    #[cfg(all(tokio_unstable, feature = "tracing"))]
194
    resource_span: tracing::Span,
195
    s: &'a semaphore::Semaphore,
196
    data: *mut T,
197
    // Needed to tell the borrow checker that we are holding a `&mut T`
198
    marker: PhantomData<&'a mut T>,
199
}
200
201
/// A owned handle to a held `Mutex` that has had a function applied to it via
202
/// [`OwnedMutexGuard::map`].
203
///
204
/// This can be used to hold a subfield of the protected data.
205
///
206
/// [`OwnedMutexGuard::map`]: method@OwnedMutexGuard::map
207
#[clippy::has_significant_drop]
208
#[must_use = "if unused the Mutex will immediately unlock"]
209
pub struct OwnedMappedMutexGuard<T: ?Sized, U: ?Sized = T> {
210
    // When changing the fields in this struct, make sure to update the
211
    // `skip_drop` method.
212
    #[cfg(all(tokio_unstable, feature = "tracing"))]
213
    resource_span: tracing::Span,
214
    data: *mut U,
215
    lock: Arc<Mutex<T>>,
216
}
217
218
/// A helper type used when taking apart a `MutexGuard` without running its
219
/// Drop implementation.
220
#[allow(dead_code)] // Unused fields are still used in Drop.
221
struct MutexGuardInner<'a, T: ?Sized> {
222
    #[cfg(all(tokio_unstable, feature = "tracing"))]
223
    resource_span: tracing::Span,
224
    lock: &'a Mutex<T>,
225
}
226
227
/// A helper type used when taking apart a `OwnedMutexGuard` without running
228
/// its Drop implementation.
229
struct OwnedMutexGuardInner<T: ?Sized> {
230
    #[cfg(all(tokio_unstable, feature = "tracing"))]
231
    resource_span: tracing::Span,
232
    lock: Arc<Mutex<T>>,
233
}
234
235
/// A helper type used when taking apart a `MappedMutexGuard` without running
236
/// its Drop implementation.
237
#[allow(dead_code)] // Unused fields are still used in Drop.
238
struct MappedMutexGuardInner<'a, T: ?Sized> {
239
    #[cfg(all(tokio_unstable, feature = "tracing"))]
240
    resource_span: tracing::Span,
241
    s: &'a semaphore::Semaphore,
242
    data: *mut T,
243
}
244
245
/// A helper type used when taking apart a `OwnedMappedMutexGuard` without running
246
/// its Drop implementation.
247
#[allow(dead_code)] // Unused fields are still used in Drop.
248
struct OwnedMappedMutexGuardInner<T: ?Sized, U: ?Sized> {
249
    #[cfg(all(tokio_unstable, feature = "tracing"))]
250
    resource_span: tracing::Span,
251
    data: *mut U,
252
    lock: Arc<Mutex<T>>,
253
}
254
255
// As long as T: Send, it's fine to send and share Mutex<T> between threads.
256
// If T was not Send, sending and sharing a Mutex<T> would be bad, since you can
257
// access T through Mutex<T>.
258
unsafe impl<T> Send for Mutex<T> where T: ?Sized + Send {}
259
unsafe impl<T> Sync for Mutex<T> where T: ?Sized + Send {}
260
unsafe impl<T> Sync for MutexGuard<'_, T> where T: ?Sized + Send + Sync {}
261
unsafe impl<T> Sync for OwnedMutexGuard<T> where T: ?Sized + Send + Sync {}
262
unsafe impl<'a, T> Sync for MappedMutexGuard<'a, T> where T: ?Sized + Sync + 'a {}
263
unsafe impl<'a, T> Send for MappedMutexGuard<'a, T> where T: ?Sized + Send + 'a {}
264
265
unsafe impl<T, U> Sync for OwnedMappedMutexGuard<T, U>
266
where
267
    T: ?Sized + Send + Sync,
268
    U: ?Sized + Send + Sync,
269
{
270
}
271
unsafe impl<T, U> Send for OwnedMappedMutexGuard<T, U>
272
where
273
    T: ?Sized + Send,
274
    U: ?Sized + Send,
275
{
276
}
277
278
/// Error returned from the [`Mutex::try_lock`], [`RwLock::try_read`] and
279
/// [`RwLock::try_write`] functions.
280
///
281
/// `Mutex::try_lock` operation will only fail if the mutex is already locked.
282
///
283
/// `RwLock::try_read` operation will only fail if the lock is currently held
284
/// by an exclusive writer.
285
///
286
/// `RwLock::try_write` operation will only fail if the lock is currently held
287
/// by any reader or by an exclusive writer.
288
///
289
/// [`Mutex::try_lock`]: Mutex::try_lock
290
/// [`RwLock::try_read`]: fn@super::RwLock::try_read
291
/// [`RwLock::try_write`]: fn@super::RwLock::try_write
292
#[derive(Debug)]
293
pub struct TryLockError(pub(super) ());
294
295
impl fmt::Display for TryLockError {
296
0
    fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
297
0
        write!(fmt, "operation would block")
298
0
    }
299
}
300
301
impl Error for TryLockError {}
302
303
#[test]
304
#[cfg(not(loom))]
305
fn bounds() {
306
    fn check_send<T: Send>() {}
307
    fn check_unpin<T: Unpin>() {}
308
    // This has to take a value, since the async fn's return type is unnameable.
309
    fn check_send_sync_val<T: Send + Sync>(_t: T) {}
310
    fn check_send_sync<T: Send + Sync>() {}
311
    fn check_static<T: 'static>() {}
312
    fn check_static_val<T: 'static>(_t: T) {}
313
314
    check_send::<MutexGuard<'_, u32>>();
315
    check_send::<OwnedMutexGuard<u32>>();
316
    check_unpin::<Mutex<u32>>();
317
    check_send_sync::<Mutex<u32>>();
318
    check_static::<OwnedMutexGuard<u32>>();
319
320
    let mutex = Mutex::new(1);
321
    check_send_sync_val(mutex.lock());
322
    let arc_mutex = Arc::new(Mutex::new(1));
323
    check_send_sync_val(arc_mutex.clone().lock_owned());
324
    check_static_val(arc_mutex.lock_owned());
325
}
326
327
impl<T: ?Sized> Mutex<T> {
328
    /// Creates a new lock in an unlocked state ready for use.
329
    ///
330
    /// # Examples
331
    ///
332
    /// ```
333
    /// use tokio::sync::Mutex;
334
    ///
335
    /// let lock = Mutex::new(5);
336
    /// ```
337
    #[track_caller]
338
0
    pub fn new(t: T) -> Self
339
0
    where
340
0
        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
0
        let s = semaphore::Semaphore::new(1);
368
369
0
        Self {
370
0
            c: UnsafeCell::new(t),
371
0
            s,
372
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
373
0
            resource_span,
374
0
        }
375
0
    }
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
0
    pub const fn const_new(t: T) -> Self
396
0
    where
397
0
        T: Sized,
398
    {
399
0
        Self {
400
0
            c: UnsafeCell::new(t),
401
0
            s: semaphore::Semaphore::const_new(1),
402
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
403
0
            resource_span: tracing::Span::none(),
404
0
        }
405
0
    }
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
0
    pub async fn lock(&self) -> MutexGuard<'_, T> {
435
0
        let acquire_fut = async {
436
0
            self.acquire().await;
437
438
0
            MutexGuard {
439
0
                lock: self,
440
0
                #[cfg(all(tokio_unstable, feature = "tracing"))]
441
0
                resource_span: self.resource_span.clone(),
442
0
            }
443
0
        };
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
0
        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
0
        guard
466
0
    }
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
0
    pub fn blocking_lock(&self) -> MutexGuard<'_, T> {
519
0
        crate::future::block_on(self.lock())
520
0
    }
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
0
    pub fn blocking_lock_owned(self: Arc<Self>) -> OwnedMutexGuard<T> {
575
0
        crate::future::block_on(self.lock_owned())
576
0
    }
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
0
    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
0
        let acquire_fut = async {
619
0
            self.acquire().await;
620
621
0
            OwnedMutexGuard {
622
0
                #[cfg(all(tokio_unstable, feature = "tracing"))]
623
0
                resource_span: self.resource_span.clone(),
624
0
                lock: self,
625
0
            }
626
0
        };
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
0
        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
0
        guard
649
0
    }
650
651
0
    async fn acquire(&self) {
652
0
        crate::trace::async_trace_leaf().await;
653
654
0
        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
0
            unreachable!()
658
        });
659
0
    }
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
0
    pub fn try_lock(&self) -> Result<MutexGuard<'_, T>, TryLockError> {
679
0
        match self.s.try_acquire(1) {
680
            Ok(()) => {
681
0
                let guard = MutexGuard {
682
0
                    lock: self,
683
0
                    #[cfg(all(tokio_unstable, feature = "tracing"))]
684
0
                    resource_span: self.resource_span.clone(),
685
0
                };
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
0
                Ok(guard)
696
            }
697
0
            Err(_) => Err(TryLockError(())),
698
        }
699
0
    }
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
0
    pub fn get_mut(&mut self) -> &mut T {
719
0
        unsafe {
720
0
            // Safety: This is https://github.com/rust-lang/rust/pull/76936
721
0
            &mut *self.c.get()
722
0
        }
723
0
    }
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
0
    pub fn try_lock_owned(self: Arc<Self>) -> Result<OwnedMutexGuard<T>, TryLockError> {
750
0
        match self.s.try_acquire(1) {
751
            Ok(()) => {
752
0
                let guard = OwnedMutexGuard {
753
0
                    #[cfg(all(tokio_unstable, feature = "tracing"))]
754
0
                    resource_span: self.resource_span.clone(),
755
0
                    lock: self,
756
0
                };
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
0
                Ok(guard)
767
            }
768
0
            Err(_) => Err(TryLockError(())),
769
        }
770
0
    }
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
0
    pub fn into_inner(self) -> T
787
0
    where
788
0
        T: Sized,
789
    {
790
0
        self.c.into_inner()
791
0
    }
792
}
793
794
impl<T> From<T> for Mutex<T> {
795
0
    fn from(s: T) -> Self {
796
0
        Self::new(s)
797
0
    }
798
}
799
800
impl<T> Default for Mutex<T>
801
where
802
    T: Default,
803
{
804
0
    fn default() -> Self {
805
0
        Self::new(T::default())
806
0
    }
807
}
808
809
impl<T: ?Sized> std::fmt::Debug for Mutex<T>
810
where
811
    T: std::fmt::Debug,
812
{
813
0
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
814
0
        let mut d = f.debug_struct("Mutex");
815
0
        match self.try_lock() {
816
0
            Ok(inner) => d.field("data", &&*inner),
817
0
            Err(_) => d.field("data", &format_args!("<locked>")),
818
        };
819
0
        d.finish()
820
0
    }
821
}
822
823
// === impl MutexGuard ===
824
825
impl<'a, T: ?Sized> MutexGuard<'a, T> {
826
0
    fn skip_drop(self) -> MutexGuardInner<'a, T> {
827
0
        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
0
        MutexGuardInner {
831
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
832
0
            resource_span: unsafe { std::ptr::read(&me.resource_span) },
833
0
            lock: me.lock,
834
0
        }
835
0
    }
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
0
    pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
869
0
    where
870
0
        U: ?Sized,
871
0
        F: FnOnce(&mut T) -> &mut U,
872
    {
873
0
        let data = f(&mut *this) as *mut U;
874
0
        let inner = this.skip_drop();
875
0
        MappedMutexGuard {
876
0
            s: &inner.lock.s,
877
0
            data,
878
0
            marker: PhantomData,
879
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
880
0
            resource_span: inner.resource_span,
881
0
        }
882
0
    }
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
0
    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
918
0
    where
919
0
        U: ?Sized,
920
0
        F: FnOnce(&mut T) -> Option<&mut U>,
921
    {
922
0
        let data = match f(&mut *this) {
923
0
            Some(data) => data as *mut U,
924
0
            None => return Err(this),
925
        };
926
0
        let inner = this.skip_drop();
927
0
        Ok(MappedMutexGuard {
928
0
            s: &inner.lock.s,
929
0
            data,
930
0
            marker: PhantomData,
931
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
932
0
            resource_span: inner.resource_span,
933
0
        })
934
0
    }
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
0
    pub fn mutex(this: &Self) -> &'a Mutex<T> {
959
0
        this.lock
960
0
    }
961
}
962
963
impl<T: ?Sized> Drop for MutexGuard<'_, T> {
964
0
    fn drop(&mut self) {
965
0
        self.lock.s.release(1);
966
967
        #[cfg(all(tokio_unstable, feature = "tracing"))]
968
        self.resource_span.in_scope(|| {
969
            tracing::trace!(
970
                target: "runtime::resource::state_update",
971
                locked = false,
972
            );
973
        });
974
0
    }
975
}
976
977
impl<T: ?Sized> Deref for MutexGuard<'_, T> {
978
    type Target = T;
979
0
    fn deref(&self) -> &Self::Target {
980
0
        unsafe { &*self.lock.c.get() }
981
0
    }
982
}
983
984
impl<T: ?Sized> DerefMut for MutexGuard<'_, T> {
985
0
    fn deref_mut(&mut self) -> &mut Self::Target {
986
0
        unsafe { &mut *self.lock.c.get() }
987
0
    }
988
}
989
990
impl<T: ?Sized + fmt::Debug> fmt::Debug for MutexGuard<'_, T> {
991
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
992
0
        fmt::Debug::fmt(&**self, f)
993
0
    }
994
}
995
996
impl<T: ?Sized + fmt::Display> fmt::Display for MutexGuard<'_, T> {
997
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
998
0
        fmt::Display::fmt(&**self, f)
999
0
    }
1000
}
1001
1002
// === impl OwnedMutexGuard ===
1003
1004
impl<T: ?Sized> OwnedMutexGuard<T> {
1005
0
    fn skip_drop(self) -> OwnedMutexGuardInner<T> {
1006
0
        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
0
            OwnedMutexGuardInner {
1011
0
                lock: ptr::read(&me.lock),
1012
0
                #[cfg(all(tokio_unstable, feature = "tracing"))]
1013
0
                resource_span: ptr::read(&me.resource_span),
1014
0
            }
1015
        }
1016
0
    }
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
0
    pub fn map<U, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, U>
1051
0
    where
1052
0
        U: ?Sized,
1053
0
        F: FnOnce(&mut T) -> &mut U,
1054
    {
1055
0
        let data = f(&mut *this) as *mut U;
1056
0
        let inner = this.skip_drop();
1057
0
        OwnedMappedMutexGuard {
1058
0
            data,
1059
0
            lock: inner.lock,
1060
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
1061
0
            resource_span: inner.resource_span,
1062
0
        }
1063
0
    }
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
0
    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, U>, Self>
1100
0
    where
1101
0
        U: ?Sized,
1102
0
        F: FnOnce(&mut T) -> Option<&mut U>,
1103
    {
1104
0
        let data = match f(&mut *this) {
1105
0
            Some(data) => data as *mut U,
1106
0
            None => return Err(this),
1107
        };
1108
0
        let inner = this.skip_drop();
1109
0
        Ok(OwnedMappedMutexGuard {
1110
0
            data,
1111
0
            lock: inner.lock,
1112
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
1113
0
            resource_span: inner.resource_span,
1114
0
        })
1115
0
    }
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
0
    pub fn mutex(this: &Self) -> &Arc<Mutex<T>> {
1141
0
        &this.lock
1142
0
    }
1143
}
1144
1145
impl<T: ?Sized> Drop for OwnedMutexGuard<T> {
1146
0
    fn drop(&mut self) {
1147
0
        self.lock.s.release(1);
1148
1149
        #[cfg(all(tokio_unstable, feature = "tracing"))]
1150
        self.resource_span.in_scope(|| {
1151
            tracing::trace!(
1152
                target: "runtime::resource::state_update",
1153
                locked = false,
1154
            );
1155
        });
1156
0
    }
1157
}
1158
1159
impl<T: ?Sized> Deref for OwnedMutexGuard<T> {
1160
    type Target = T;
1161
0
    fn deref(&self) -> &Self::Target {
1162
0
        unsafe { &*self.lock.c.get() }
1163
0
    }
1164
}
1165
1166
impl<T: ?Sized> DerefMut for OwnedMutexGuard<T> {
1167
0
    fn deref_mut(&mut self) -> &mut Self::Target {
1168
0
        unsafe { &mut *self.lock.c.get() }
1169
0
    }
1170
}
1171
1172
impl<T: ?Sized + fmt::Debug> fmt::Debug for OwnedMutexGuard<T> {
1173
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1174
0
        fmt::Debug::fmt(&**self, f)
1175
0
    }
1176
}
1177
1178
impl<T: ?Sized + fmt::Display> fmt::Display for OwnedMutexGuard<T> {
1179
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1180
0
        fmt::Display::fmt(&**self, f)
1181
0
    }
1182
}
1183
1184
// === impl MappedMutexGuard ===
1185
1186
impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
1187
0
    fn skip_drop(self) -> MappedMutexGuardInner<'a, T> {
1188
0
        let me = mem::ManuallyDrop::new(self);
1189
0
        MappedMutexGuardInner {
1190
0
            s: me.s,
1191
0
            data: me.data,
1192
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
1193
0
            resource_span: unsafe { std::ptr::read(&me.resource_span) },
1194
0
        }
1195
0
    }
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
0
    pub fn map<U, F>(mut this: Self, f: F) -> MappedMutexGuard<'a, U>
1207
0
    where
1208
0
        F: FnOnce(&mut T) -> &mut U,
1209
    {
1210
0
        let data = f(&mut *this) as *mut U;
1211
0
        let inner = this.skip_drop();
1212
0
        MappedMutexGuard {
1213
0
            s: inner.s,
1214
0
            data,
1215
0
            marker: PhantomData,
1216
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
1217
0
            resource_span: inner.resource_span,
1218
0
        }
1219
0
    }
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
0
    pub fn try_map<U, F>(mut this: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
1232
0
    where
1233
0
        F: FnOnce(&mut T) -> Option<&mut U>,
1234
    {
1235
0
        let data = match f(&mut *this) {
1236
0
            Some(data) => data as *mut U,
1237
0
            None => return Err(this),
1238
        };
1239
0
        let inner = this.skip_drop();
1240
0
        Ok(MappedMutexGuard {
1241
0
            s: inner.s,
1242
0
            data,
1243
0
            marker: PhantomData,
1244
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
1245
0
            resource_span: inner.resource_span,
1246
0
        })
1247
0
    }
1248
}
1249
1250
impl<'a, T: ?Sized> Drop for MappedMutexGuard<'a, T> {
1251
0
    fn drop(&mut self) {
1252
0
        self.s.release(1);
1253
1254
        #[cfg(all(tokio_unstable, feature = "tracing"))]
1255
        self.resource_span.in_scope(|| {
1256
            tracing::trace!(
1257
                target: "runtime::resource::state_update",
1258
                locked = false,
1259
            );
1260
        });
1261
0
    }
1262
}
1263
1264
impl<'a, T: ?Sized> Deref for MappedMutexGuard<'a, T> {
1265
    type Target = T;
1266
0
    fn deref(&self) -> &Self::Target {
1267
0
        unsafe { &*self.data }
1268
0
    }
1269
}
1270
1271
impl<'a, T: ?Sized> DerefMut for MappedMutexGuard<'a, T> {
1272
0
    fn deref_mut(&mut self) -> &mut Self::Target {
1273
0
        unsafe { &mut *self.data }
1274
0
    }
1275
}
1276
1277
impl<'a, T: ?Sized + fmt::Debug> fmt::Debug for MappedMutexGuard<'a, T> {
1278
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1279
0
        fmt::Debug::fmt(&**self, f)
1280
0
    }
1281
}
1282
1283
impl<'a, T: ?Sized + fmt::Display> fmt::Display for MappedMutexGuard<'a, T> {
1284
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1285
0
        fmt::Display::fmt(&**self, f)
1286
0
    }
1287
}
1288
1289
// === impl OwnedMappedMutexGuard ===
1290
1291
impl<T: ?Sized, U: ?Sized> OwnedMappedMutexGuard<T, U> {
1292
0
    fn skip_drop(self) -> OwnedMappedMutexGuardInner<T, U> {
1293
0
        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
0
            OwnedMappedMutexGuardInner {
1298
0
                data: me.data,
1299
0
                lock: ptr::read(&me.lock),
1300
0
                #[cfg(all(tokio_unstable, feature = "tracing"))]
1301
0
                resource_span: ptr::read(&me.resource_span),
1302
0
            }
1303
        }
1304
0
    }
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
0
    pub fn map<S, F>(mut this: Self, f: F) -> OwnedMappedMutexGuard<T, S>
1316
0
    where
1317
0
        F: FnOnce(&mut U) -> &mut S,
1318
    {
1319
0
        let data = f(&mut *this) as *mut S;
1320
0
        let inner = this.skip_drop();
1321
0
        OwnedMappedMutexGuard {
1322
0
            data,
1323
0
            lock: inner.lock,
1324
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
1325
0
            resource_span: inner.resource_span,
1326
0
        }
1327
0
    }
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
0
    pub fn try_map<S, F>(mut this: Self, f: F) -> Result<OwnedMappedMutexGuard<T, S>, Self>
1341
0
    where
1342
0
        F: FnOnce(&mut U) -> Option<&mut S>,
1343
    {
1344
0
        let data = match f(&mut *this) {
1345
0
            Some(data) => data as *mut S,
1346
0
            None => return Err(this),
1347
        };
1348
0
        let inner = this.skip_drop();
1349
0
        Ok(OwnedMappedMutexGuard {
1350
0
            data,
1351
0
            lock: inner.lock,
1352
0
            #[cfg(all(tokio_unstable, feature = "tracing"))]
1353
0
            resource_span: inner.resource_span,
1354
0
        })
1355
0
    }
1356
}
1357
1358
impl<T: ?Sized, U: ?Sized> Drop for OwnedMappedMutexGuard<T, U> {
1359
0
    fn drop(&mut self) {
1360
0
        self.lock.s.release(1);
1361
1362
        #[cfg(all(tokio_unstable, feature = "tracing"))]
1363
        self.resource_span.in_scope(|| {
1364
            tracing::trace!(
1365
                target: "runtime::resource::state_update",
1366
                locked = false,
1367
            );
1368
        });
1369
0
    }
1370
}
1371
1372
impl<T: ?Sized, U: ?Sized> Deref for OwnedMappedMutexGuard<T, U> {
1373
    type Target = U;
1374
0
    fn deref(&self) -> &Self::Target {
1375
0
        unsafe { &*self.data }
1376
0
    }
1377
}
1378
1379
impl<T: ?Sized, U: ?Sized> DerefMut for OwnedMappedMutexGuard<T, U> {
1380
0
    fn deref_mut(&mut self) -> &mut Self::Target {
1381
0
        unsafe { &mut *self.data }
1382
0
    }
1383
}
1384
1385
impl<T: ?Sized, U: ?Sized + fmt::Debug> fmt::Debug for OwnedMappedMutexGuard<T, U> {
1386
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1387
0
        fmt::Debug::fmt(&**self, f)
1388
0
    }
1389
}
1390
1391
impl<T: ?Sized, U: ?Sized + fmt::Display> fmt::Display for OwnedMappedMutexGuard<T, U> {
1392
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1393
0
        fmt::Display::fmt(&**self, f)
1394
0
    }
1395
}