Coverage Report

Created: 2025-11-28 06:44

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