Coverage Report

Created: 2025-11-16 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/lock_api-0.4.14/src/mutex.rs
Line
Count
Source
1
// Copyright 2018 Amanieu d'Antras
2
//
3
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
4
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
5
// http://opensource.org/licenses/MIT>, at your option. This file may not be
6
// copied, modified, or distributed except according to those terms.
7
8
use core::cell::UnsafeCell;
9
use core::fmt;
10
use core::marker::PhantomData;
11
use core::mem;
12
use core::ops::{Deref, DerefMut};
13
14
#[cfg(feature = "arc_lock")]
15
use alloc::sync::Arc;
16
#[cfg(feature = "arc_lock")]
17
use core::mem::ManuallyDrop;
18
#[cfg(feature = "arc_lock")]
19
use core::ptr;
20
21
#[cfg(feature = "owning_ref")]
22
use owning_ref::StableAddress;
23
24
#[cfg(feature = "serde")]
25
use serde::{Deserialize, Deserializer, Serialize, Serializer};
26
27
/// Basic operations for a mutex.
28
///
29
/// Types implementing this trait can be used by `Mutex` to form a safe and
30
/// fully-functioning mutex type.
31
///
32
/// # Safety
33
///
34
/// Implementations of this trait must ensure that the mutex is actually
35
/// exclusive: a lock can't be acquired while the mutex is already locked.
36
pub unsafe trait RawMutex {
37
    /// Initial value for an unlocked mutex.
38
    // A “non-constant” const item is a legacy way to supply an initialized value to downstream
39
    // static items. Can hopefully be replaced with `const fn new() -> Self` at some point.
40
    #[allow(clippy::declare_interior_mutable_const)]
41
    const INIT: Self;
42
43
    /// Marker type which determines whether a lock guard should be `Send`. Use
44
    /// one of the `GuardSend` or `GuardNoSend` helper types here.
45
    type GuardMarker;
46
47
    /// Acquires this mutex, blocking the current thread until it is able to do so.
48
    fn lock(&self);
49
50
    /// Attempts to acquire this mutex without blocking. Returns `true`
51
    /// if the lock was successfully acquired and `false` otherwise.
52
    fn try_lock(&self) -> bool;
53
54
    /// Unlocks this mutex.
55
    ///
56
    /// # Safety
57
    ///
58
    /// This method may only be called if the mutex is held in the current context, i.e. it must
59
    /// be paired with a successful call to [`lock`], [`try_lock`], [`try_lock_for`] or [`try_lock_until`].
60
    ///
61
    /// [`lock`]: RawMutex::lock
62
    /// [`try_lock`]: RawMutex::try_lock
63
    /// [`try_lock_for`]: RawMutexTimed::try_lock_for
64
    /// [`try_lock_until`]: RawMutexTimed::try_lock_until
65
    unsafe fn unlock(&self);
66
67
    /// Checks whether the mutex is currently locked.
68
    #[inline]
69
0
    fn is_locked(&self) -> bool {
70
0
        let acquired_lock = self.try_lock();
71
0
        if acquired_lock {
72
            // Safety: The lock has been successfully acquired above.
73
0
            unsafe {
74
0
                self.unlock();
75
0
            }
76
0
        }
77
0
        !acquired_lock
78
0
    }
79
}
80
81
/// Additional methods for mutexes which support fair unlocking.
82
///
83
/// Fair unlocking means that a lock is handed directly over to the next waiting
84
/// thread if there is one, without giving other threads the opportunity to
85
/// "steal" the lock in the meantime. This is typically slower than unfair
86
/// unlocking, but may be necessary in certain circumstances.
87
pub unsafe trait RawMutexFair: RawMutex {
88
    /// Unlocks this mutex using a fair unlock protocol.
89
    ///
90
    /// # Safety
91
    ///
92
    /// This method may only be called if the mutex is held in the current context, see
93
    /// the documentation of [`unlock`](RawMutex::unlock).
94
    unsafe fn unlock_fair(&self);
95
96
    /// Temporarily yields the mutex to a waiting thread if there is one.
97
    ///
98
    /// This method is functionally equivalent to calling `unlock_fair` followed
99
    /// by `lock`, however it can be much more efficient in the case where there
100
    /// are no waiting threads.
101
    ///
102
    /// # Safety
103
    ///
104
    /// This method may only be called if the mutex is held in the current context, see
105
    /// the documentation of [`unlock`](RawMutex::unlock).
106
0
    unsafe fn bump(&self) {
107
0
        self.unlock_fair();
108
0
        self.lock();
109
0
    }
110
}
111
112
/// Additional methods for mutexes which support locking with timeouts.
113
///
114
/// The `Duration` and `Instant` types are specified as associated types so that
115
/// this trait is usable even in `no_std` environments.
116
pub unsafe trait RawMutexTimed: RawMutex {
117
    /// Duration type used for `try_lock_for`.
118
    type Duration;
119
120
    /// Instant type used for `try_lock_until`.
121
    type Instant;
122
123
    /// Attempts to acquire this lock until a timeout is reached.
124
    fn try_lock_for(&self, timeout: Self::Duration) -> bool;
125
126
    /// Attempts to acquire this lock until a timeout is reached.
127
    fn try_lock_until(&self, timeout: Self::Instant) -> bool;
128
}
129
130
/// A mutual exclusion primitive useful for protecting shared data
131
///
132
/// This mutex will block threads waiting for the lock to become available. The
133
/// mutex can also be statically initialized or created via a `new`
134
/// constructor. Each mutex has a type parameter which represents the data that
135
/// it is protecting. The data can only be accessed through the RAII guards
136
/// returned from `lock` and `try_lock`, which guarantees that the data is only
137
/// ever accessed when the mutex is locked.
138
pub struct Mutex<R, T: ?Sized> {
139
    raw: R,
140
    data: UnsafeCell<T>,
141
}
142
143
unsafe impl<R: RawMutex + Send, T: ?Sized + Send> Send for Mutex<R, T> {}
144
unsafe impl<R: RawMutex + Sync, T: ?Sized + Send> Sync for Mutex<R, T> {}
145
146
impl<R: RawMutex, T> Mutex<R, T> {
147
    /// Creates a new mutex in an unlocked state ready for use.
148
    #[inline]
149
2.85M
    pub const fn new(val: T) -> Mutex<R, T> {
150
2.85M
        Mutex {
151
2.85M
            raw: R::INIT,
152
2.85M
            data: UnsafeCell::new(val),
153
2.85M
        }
154
2.85M
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, core::option::Option<alloc::collections::vec_deque::VecDeque<tokio::runtime::task::Notified<alloc::sync::Arc<tokio::task::local::Shared>>>>>>::new
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<alloc::boxed::Box<tokio::runtime::scheduler::multi_thread::worker::Core>>>>::new
Line
Count
Source
149
17.1k
    pub const fn new(val: T) -> Mutex<R, T> {
150
17.1k
        Mutex {
151
17.1k
            raw: R::INIT,
152
17.1k
            data: UnsafeCell::new(val),
153
17.1k
        }
154
17.1k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::current_thread::Handle>>, tokio::runtime::task::core::Header>>>::new
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>, tokio::runtime::task::core::Header>>>::new
Line
Count
Source
149
2.19M
    pub const fn new(val: T) -> Mutex<R, T> {
150
2.19M
        Mutex {
151
2.19M
            raw: R::INIT,
152
2.19M
            data: UnsafeCell::new(val),
153
2.19M
        }
154
2.19M
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::sync::notify::Waiter, tokio::sync::notify::Waiter>>>::new
Line
Count
Source
149
1.17k
    pub const fn new(val: T) -> Mutex<R, T> {
150
1.17k
        Mutex {
151
1.17k
            raw: R::INIT,
152
1.17k
            data: UnsafeCell::new(val),
153
1.17k
        }
154
1.17k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::sync::batch_semaphore::Waitlist>>::new
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::sync::barrier::BarrierState>>::new
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::time::clock::Inner>>::new
Line
Count
Source
149
17.1k
    pub const fn new(val: T) -> Mutex<R, T> {
150
17.1k
        Mutex {
151
17.1k
            raw: R::INIT,
152
17.1k
            data: UnsafeCell::new(val),
153
17.1k
        }
154
17.1k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::time::InnerState>>::new
Line
Count
Source
149
17.1k
    pub const fn new(val: T) -> Mutex<R, T> {
150
17.1k
        Mutex {
151
17.1k
            raw: R::INIT,
152
17.1k
            data: UnsafeCell::new(val),
153
17.1k
        }
154
17.1k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::io::util::mem::SimplexStream>>::new
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::scheduled_io::Waiters>>::new
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::registration_set::Synced>>::new
Line
Count
Source
149
17.1k
    pub const fn new(val: T) -> Mutex<R, T> {
150
17.1k
        Mutex {
151
17.1k
            raw: R::INIT,
152
17.1k
            data: UnsafeCell::new(val),
153
17.1k
        }
154
17.1k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::blocking::pool::Shared>>::new
Line
Count
Source
149
17.1k
    pub const fn new(val: T) -> Mutex<R, T> {
150
17.1k
        Mutex {
151
17.1k
            raw: R::INIT,
152
17.1k
            data: UnsafeCell::new(val),
153
17.1k
        }
154
17.1k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::multi_thread::worker::Synced>>::new
Line
Count
Source
149
17.1k
    pub const fn new(val: T) -> Mutex<R, T> {
150
17.1k
        Mutex {
151
17.1k
            raw: R::INIT,
152
17.1k
            data: UnsafeCell::new(val),
153
17.1k
        }
154
17.1k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::inject::synced::Synced>>::new
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, ()>>::new
Line
Count
Source
149
564k
    pub const fn new(val: T) -> Mutex<R, T> {
150
564k
        Mutex {
151
564k
            raw: R::INIT,
152
564k
            data: UnsafeCell::new(val),
153
564k
        }
154
564k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<_, _>>::new
155
156
    /// Consumes this mutex, returning the underlying data.
157
    #[inline]
158
0
    pub fn into_inner(self) -> T {
159
0
        self.data.into_inner()
160
0
    }
161
}
162
163
impl<R, T> Mutex<R, T> {
164
    /// Creates a new mutex based on a pre-existing raw mutex.
165
    #[inline]
166
0
    pub const fn from_raw(raw_mutex: R, val: T) -> Mutex<R, T> {
167
0
        Mutex {
168
0
            raw: raw_mutex,
169
0
            data: UnsafeCell::new(val),
170
0
        }
171
0
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::sync::notify::Waiter, tokio::sync::notify::Waiter>>>::from_raw
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::sync::batch_semaphore::Waitlist>>::from_raw
Unexecuted instantiation: <lock_api::mutex::Mutex<_, _>>::from_raw
172
173
    /// Creates a new mutex based on a pre-existing raw mutex.
174
    ///
175
    /// This allows creating a mutex in a constant context on stable Rust.
176
    ///
177
    /// This method is a legacy alias for [`from_raw`](Self::from_raw).
178
    #[inline]
179
0
    pub const fn const_new(raw_mutex: R, val: T) -> Mutex<R, T> {
180
0
        Self::from_raw(raw_mutex, val)
181
0
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::sync::notify::Waiter, tokio::sync::notify::Waiter>>>::const_new
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::sync::batch_semaphore::Waitlist>>::const_new
Unexecuted instantiation: <lock_api::mutex::Mutex<_, _>>::const_new
182
}
183
184
impl<R: RawMutex, T: ?Sized> Mutex<R, T> {
185
    /// Creates a new `MutexGuard` without checking if the mutex is locked.
186
    ///
187
    /// # Safety
188
    ///
189
    /// This method must only be called if the thread logically holds the lock.
190
    ///
191
    /// Calling this function when a guard has already been produced is undefined behaviour unless
192
    /// the guard was forgotten with `mem::forget`.
193
    #[inline]
194
75.2M
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
75.2M
        MutexGuard {
196
75.2M
            mutex: self,
197
75.2M
            marker: PhantomData,
198
75.2M
        }
199
75.2M
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, core::option::Option<tokio::sync::watch::Receiver<()>>>>::make_guard_unchecked
Line
Count
Source
194
20.9k
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
20.9k
        MutexGuard {
196
20.9k
            mutex: self,
197
20.9k
            marker: PhantomData,
198
20.9k
        }
199
20.9k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, core::option::Option<alloc::collections::vec_deque::VecDeque<tokio::runtime::task::Notified<alloc::sync::Arc<tokio::task::local::Shared>>>>>>::make_guard_unchecked
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<alloc::boxed::Box<tokio::runtime::scheduler::multi_thread::worker::Core>>>>::make_guard_unchecked
Line
Count
Source
194
547k
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
547k
        MutexGuard {
196
547k
            mutex: self,
197
547k
            marker: PhantomData,
198
547k
        }
199
547k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<std::process::Child>>>::make_guard_unchecked
Line
Count
Source
194
20.9k
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
20.9k
        MutexGuard {
196
20.9k
            mutex: self,
197
20.9k
            marker: PhantomData,
198
20.9k
        }
199
20.9k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::current_thread::Handle>>, tokio::runtime::task::core::Header>>>::make_guard_unchecked
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>, tokio::runtime::task::core::Header>>>::make_guard_unchecked
Line
Count
Source
194
70.1M
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
70.1M
        MutexGuard {
196
70.1M
            mutex: self,
197
70.1M
            marker: PhantomData,
198
70.1M
        }
199
70.1M
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::sync::notify::Waiter, tokio::sync::notify::Waiter>>>::make_guard_unchecked
Line
Count
Source
194
130
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
130
        MutexGuard {
196
130
            mutex: self,
197
130
            marker: PhantomData,
198
130
        }
199
130
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::sync::batch_semaphore::Waitlist>>::make_guard_unchecked
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::time::clock::Inner>>::make_guard_unchecked
Line
Count
Source
194
38.0k
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
38.0k
        MutexGuard {
196
38.0k
            mutex: self,
197
38.0k
            marker: PhantomData,
198
38.0k
        }
199
38.0k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::time::InnerState>>::make_guard_unchecked
Line
Count
Source
194
59.0k
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
59.0k
        MutexGuard {
196
59.0k
            mutex: self,
197
59.0k
            marker: PhantomData,
198
59.0k
        }
199
59.0k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::io::util::mem::SimplexStream>>::make_guard_unchecked
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::scheduled_io::Waiters>>::make_guard_unchecked
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::registration_set::Synced>>::make_guard_unchecked
Line
Count
Source
194
17.1k
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
17.1k
        MutexGuard {
196
17.1k
            mutex: self,
197
17.1k
            marker: PhantomData,
198
17.1k
        }
199
17.1k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::blocking::pool::Shared>>::make_guard_unchecked
Line
Count
Source
194
1.66M
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
1.66M
        MutexGuard {
196
1.66M
            mutex: self,
197
1.66M
            marker: PhantomData,
198
1.66M
        }
199
1.66M
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::multi_thread::worker::Synced>>::make_guard_unchecked
Line
Count
Source
194
1.66M
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
1.66M
        MutexGuard {
196
1.66M
            mutex: self,
197
1.66M
            marker: PhantomData,
198
1.66M
        }
199
1.66M
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::inject::synced::Synced>>::make_guard_unchecked
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, ()>>::make_guard_unchecked
Line
Count
Source
194
1.08M
    pub unsafe fn make_guard_unchecked(&self) -> MutexGuard<'_, R, T> {
195
1.08M
        MutexGuard {
196
1.08M
            mutex: self,
197
1.08M
            marker: PhantomData,
198
1.08M
        }
199
1.08M
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<_, _>>::make_guard_unchecked
200
201
    /// Acquires a mutex, blocking the current thread until it is able to do so.
202
    ///
203
    /// This function will block the local thread until it is available to acquire
204
    /// the mutex. Upon returning, the thread is the only thread with the mutex
205
    /// held. An RAII guard is returned to allow scoped unlock of the lock. When
206
    /// the guard goes out of scope, the mutex will be unlocked.
207
    ///
208
    /// Attempts to lock a mutex in the thread which already holds the lock will
209
    /// result in a deadlock.
210
    #[inline]
211
    #[track_caller]
212
75.1M
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
75.1M
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
75.1M
        unsafe { self.make_guard_unchecked() }
216
75.1M
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, core::option::Option<alloc::collections::vec_deque::VecDeque<tokio::runtime::task::Notified<alloc::sync::Arc<tokio::task::local::Shared>>>>>>::lock
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<alloc::boxed::Box<tokio::runtime::scheduler::multi_thread::worker::Core>>>>::lock
Line
Count
Source
212
547k
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
547k
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
547k
        unsafe { self.make_guard_unchecked() }
216
547k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<std::process::Child>>>::lock
Line
Count
Source
212
20.9k
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
20.9k
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
20.9k
        unsafe { self.make_guard_unchecked() }
216
20.9k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::current_thread::Handle>>, tokio::runtime::task::core::Header>>>::lock
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>, tokio::runtime::task::core::Header>>>::lock
Line
Count
Source
212
70.1M
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
70.1M
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
70.1M
        unsafe { self.make_guard_unchecked() }
216
70.1M
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::sync::notify::Waiter, tokio::sync::notify::Waiter>>>::lock
Line
Count
Source
212
130
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
130
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
130
        unsafe { self.make_guard_unchecked() }
216
130
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::sync::batch_semaphore::Waitlist>>::lock
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::time::clock::Inner>>::lock
Line
Count
Source
212
38.0k
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
38.0k
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
38.0k
        unsafe { self.make_guard_unchecked() }
216
38.0k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::time::InnerState>>::lock
Line
Count
Source
212
59.0k
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
59.0k
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
59.0k
        unsafe { self.make_guard_unchecked() }
216
59.0k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::io::util::mem::SimplexStream>>::lock
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::scheduled_io::Waiters>>::lock
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::registration_set::Synced>>::lock
Line
Count
Source
212
17.1k
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
17.1k
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
17.1k
        unsafe { self.make_guard_unchecked() }
216
17.1k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::blocking::pool::Shared>>::lock
Line
Count
Source
212
1.66M
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
1.66M
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
1.66M
        unsafe { self.make_guard_unchecked() }
216
1.66M
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::multi_thread::worker::Synced>>::lock
Line
Count
Source
212
1.66M
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
1.66M
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
1.66M
        unsafe { self.make_guard_unchecked() }
216
1.66M
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::inject::synced::Synced>>::lock
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, ()>>::lock
Line
Count
Source
212
1.08M
    pub fn lock(&self) -> MutexGuard<'_, R, T> {
213
1.08M
        self.raw.lock();
214
        // SAFETY: The lock is held, as required.
215
1.08M
        unsafe { self.make_guard_unchecked() }
216
1.08M
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<_, _>>::lock
217
218
    /// Attempts to acquire this lock.
219
    ///
220
    /// If the lock could not be acquired at this time, then `None` is returned.
221
    /// Otherwise, an RAII guard is returned. The lock will be unlocked when the
222
    /// guard is dropped.
223
    ///
224
    /// This function does not block.
225
    #[inline]
226
    #[track_caller]
227
20.9k
    pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> {
228
20.9k
        if self.raw.try_lock() {
229
            // SAFETY: The lock is held, as required.
230
20.9k
            Some(unsafe { self.make_guard_unchecked() })
231
        } else {
232
0
            None
233
        }
234
20.9k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, core::option::Option<tokio::sync::watch::Receiver<()>>>>::try_lock
Line
Count
Source
227
20.9k
    pub fn try_lock(&self) -> Option<MutexGuard<'_, R, T>> {
228
20.9k
        if self.raw.try_lock() {
229
            // SAFETY: The lock is held, as required.
230
20.9k
            Some(unsafe { self.make_guard_unchecked() })
231
        } else {
232
0
            None
233
        }
234
20.9k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<std::process::Child>>>::try_lock
Unexecuted instantiation: <lock_api::mutex::Mutex<_, _>>::try_lock
235
236
    /// Returns a mutable reference to the underlying data.
237
    ///
238
    /// Since this call borrows the `Mutex` mutably, no actual locking needs to
239
    /// take place---the mutable borrow statically guarantees no locks exist.
240
    #[inline]
241
0
    pub fn get_mut(&mut self) -> &mut T {
242
0
        unsafe { &mut *self.data.get() }
243
0
    }
244
245
    /// Checks whether the mutex is currently locked.
246
    #[inline]
247
    #[track_caller]
248
0
    pub fn is_locked(&self) -> bool {
249
0
        self.raw.is_locked()
250
0
    }
251
252
    /// Forcibly unlocks the mutex.
253
    ///
254
    /// This is useful when combined with `mem::forget` to hold a lock without
255
    /// the need to maintain a `MutexGuard` object alive, for example when
256
    /// dealing with FFI.
257
    ///
258
    /// # Safety
259
    ///
260
    /// This method must only be called if the current thread logically owns a
261
    /// `MutexGuard` but that guard has been discarded using `mem::forget`.
262
    /// Behavior is undefined if a mutex is unlocked when not locked.
263
    #[inline]
264
    #[track_caller]
265
0
    pub unsafe fn force_unlock(&self) {
266
0
        self.raw.unlock();
267
0
    }
268
269
    /// Returns the underlying raw mutex object.
270
    ///
271
    /// Note that you will most likely need to import the `RawMutex` trait from
272
    /// `lock_api` to be able to call functions on the raw mutex.
273
    ///
274
    /// # Safety
275
    ///
276
    /// This method is unsafe because it allows unlocking a mutex while
277
    /// still holding a reference to a `MutexGuard`.
278
    #[inline]
279
803k
    pub unsafe fn raw(&self) -> &R {
280
803k
        &self.raw
281
803k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, tokio::runtime::blocking::pool::Shared>>::raw
Line
Count
Source
279
260k
    pub unsafe fn raw(&self) -> &R {
280
260k
        &self.raw
281
260k
    }
<lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, ()>>::raw
Line
Count
Source
279
543k
    pub unsafe fn raw(&self) -> &R {
280
543k
        &self.raw
281
543k
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<_, _>>::raw
282
283
    /// Returns a raw pointer to the underlying data.
284
    ///
285
    /// This is useful when combined with `mem::forget` to hold a lock without
286
    /// the need to maintain a `MutexGuard` object alive, for example when
287
    /// dealing with FFI.
288
    ///
289
    /// # Safety
290
    ///
291
    /// You must ensure that there are no data races when dereferencing the
292
    /// returned pointer, for example if the current thread logically owns
293
    /// a `MutexGuard` but that guard has been discarded using `mem::forget`.
294
    #[inline]
295
0
    pub fn data_ptr(&self) -> *mut T {
296
0
        self.data.get()
297
0
    }
298
299
    /// Creates a new `ArcMutexGuard` without checking if the mutex is locked.
300
    ///
301
    /// # Safety
302
    ///
303
    /// This method must only be called if the thread logically holds the lock.
304
    ///
305
    /// Calling this function when a guard has already been produced is undefined behaviour unless
306
    /// the guard was forgotten with `mem::forget`.
307
    #[cfg(feature = "arc_lock")]
308
    #[inline]
309
    unsafe fn make_arc_guard_unchecked(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
310
        ArcMutexGuard {
311
            mutex: self.clone(),
312
            marker: PhantomData,
313
        }
314
    }
315
316
    /// Acquires a lock through an `Arc`.
317
    ///
318
    /// This method is similar to the `lock` method; however, it requires the `Mutex` to be inside of an `Arc`
319
    /// and the resulting mutex guard has no lifetime requirements.
320
    #[cfg(feature = "arc_lock")]
321
    #[inline]
322
    #[track_caller]
323
    pub fn lock_arc(self: &Arc<Self>) -> ArcMutexGuard<R, T> {
324
        self.raw.lock();
325
        // SAFETY: the locking guarantee is upheld
326
        unsafe { self.make_arc_guard_unchecked() }
327
    }
328
329
    /// Attempts to acquire a lock through an `Arc`.
330
    ///
331
    /// This method is similar to the `try_lock` method; however, it requires the `Mutex` to be inside of an
332
    /// `Arc` and the resulting mutex guard has no lifetime requirements.
333
    #[cfg(feature = "arc_lock")]
334
    #[inline]
335
    #[track_caller]
336
    pub fn try_lock_arc(self: &Arc<Self>) -> Option<ArcMutexGuard<R, T>> {
337
        if self.raw.try_lock() {
338
            // SAFETY: locking guarantee is upheld
339
            Some(unsafe { self.make_arc_guard_unchecked() })
340
        } else {
341
            None
342
        }
343
    }
344
}
345
346
impl<R: RawMutexFair, T: ?Sized> Mutex<R, T> {
347
    /// Forcibly unlocks the mutex using a fair unlock protocol.
348
    ///
349
    /// This is useful when combined with `mem::forget` to hold a lock without
350
    /// the need to maintain a `MutexGuard` object alive, for example when
351
    /// dealing with FFI.
352
    ///
353
    /// # Safety
354
    ///
355
    /// This method must only be called if the current thread logically owns a
356
    /// `MutexGuard` but that guard has been discarded using `mem::forget`.
357
    /// Behavior is undefined if a mutex is unlocked when not locked.
358
    #[inline]
359
    #[track_caller]
360
0
    pub unsafe fn force_unlock_fair(&self) {
361
0
        self.raw.unlock_fair();
362
0
    }
363
}
364
365
impl<R: RawMutexTimed, T: ?Sized> Mutex<R, T> {
366
    /// Attempts to acquire this lock until a timeout is reached.
367
    ///
368
    /// If the lock could not be acquired before the timeout expired, then
369
    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
370
    /// be unlocked when the guard is dropped.
371
    #[inline]
372
    #[track_caller]
373
0
    pub fn try_lock_for(&self, timeout: R::Duration) -> Option<MutexGuard<'_, R, T>> {
374
0
        if self.raw.try_lock_for(timeout) {
375
            // SAFETY: The lock is held, as required.
376
0
            Some(unsafe { self.make_guard_unchecked() })
377
        } else {
378
0
            None
379
        }
380
0
    }
381
382
    /// Attempts to acquire this lock until a timeout is reached.
383
    ///
384
    /// If the lock could not be acquired before the timeout expired, then
385
    /// `None` is returned. Otherwise, an RAII guard is returned. The lock will
386
    /// be unlocked when the guard is dropped.
387
    #[inline]
388
    #[track_caller]
389
0
    pub fn try_lock_until(&self, timeout: R::Instant) -> Option<MutexGuard<'_, R, T>> {
390
0
        if self.raw.try_lock_until(timeout) {
391
            // SAFETY: The lock is held, as required.
392
0
            Some(unsafe { self.make_guard_unchecked() })
393
        } else {
394
0
            None
395
        }
396
0
    }
397
398
    /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
399
    ///
400
    /// This method is similar to the `try_lock_for` method; however, it requires the `Mutex` to be inside of an
401
    /// `Arc` and the resulting mutex guard has no lifetime requirements.
402
    #[cfg(feature = "arc_lock")]
403
    #[inline]
404
    #[track_caller]
405
    pub fn try_lock_arc_for(self: &Arc<Self>, timeout: R::Duration) -> Option<ArcMutexGuard<R, T>> {
406
        if self.raw.try_lock_for(timeout) {
407
            // SAFETY: locking guarantee is upheld
408
            Some(unsafe { self.make_arc_guard_unchecked() })
409
        } else {
410
            None
411
        }
412
    }
413
414
    /// Attempts to acquire this lock through an `Arc` until a timeout is reached.
415
    ///
416
    /// This method is similar to the `try_lock_until` method; however, it requires the `Mutex` to be inside of
417
    /// an `Arc` and the resulting mutex guard has no lifetime requirements.
418
    #[cfg(feature = "arc_lock")]
419
    #[inline]
420
    #[track_caller]
421
    pub fn try_lock_arc_until(
422
        self: &Arc<Self>,
423
        timeout: R::Instant,
424
    ) -> Option<ArcMutexGuard<R, T>> {
425
        if self.raw.try_lock_until(timeout) {
426
            // SAFETY: locking guarantee is upheld
427
            Some(unsafe { self.make_arc_guard_unchecked() })
428
        } else {
429
            None
430
        }
431
    }
432
}
433
434
impl<R: RawMutex, T: ?Sized + Default> Default for Mutex<R, T> {
435
    #[inline]
436
0
    fn default() -> Mutex<R, T> {
437
0
        Mutex::new(Default::default())
438
0
    }
439
}
440
441
impl<R: RawMutex, T> From<T> for Mutex<R, T> {
442
    #[inline]
443
0
    fn from(t: T) -> Mutex<R, T> {
444
0
        Mutex::new(t)
445
0
    }
446
}
447
448
impl<R: RawMutex, T: ?Sized + fmt::Debug> fmt::Debug for Mutex<R, T> {
449
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
450
0
        match self.try_lock() {
451
0
            Some(guard) => f.debug_struct("Mutex").field("data", &&*guard).finish(),
452
            None => {
453
                struct LockedPlaceholder;
454
                impl fmt::Debug for LockedPlaceholder {
455
0
                    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
456
0
                        f.write_str("<locked>")
457
0
                    }
458
                }
459
460
0
                f.debug_struct("Mutex")
461
0
                    .field("data", &LockedPlaceholder)
462
0
                    .finish()
463
            }
464
        }
465
0
    }
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, core::option::Option<tokio::sync::watch::Receiver<()>>> as core::fmt::Debug>::fmt
Unexecuted instantiation: <lock_api::mutex::Mutex<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<std::process::Child>> as core::fmt::Debug>::fmt
Unexecuted instantiation: <lock_api::mutex::Mutex<_, _> as core::fmt::Debug>::fmt
466
}
467
468
// Copied and modified from serde
469
#[cfg(feature = "serde")]
470
impl<R, T> Serialize for Mutex<R, T>
471
where
472
    R: RawMutex,
473
    T: Serialize + ?Sized,
474
{
475
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
476
    where
477
        S: Serializer,
478
    {
479
        self.lock().serialize(serializer)
480
    }
481
}
482
483
#[cfg(feature = "serde")]
484
impl<'de, R, T> Deserialize<'de> for Mutex<R, T>
485
where
486
    R: RawMutex,
487
    T: Deserialize<'de> + ?Sized,
488
{
489
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
490
    where
491
        D: Deserializer<'de>,
492
    {
493
        Deserialize::deserialize(deserializer).map(Mutex::new)
494
    }
495
}
496
497
/// An RAII implementation of a "scoped lock" of a mutex. When this structure is
498
/// dropped (falls out of scope), the lock will be unlocked.
499
///
500
/// The data protected by the mutex can be accessed through this guard via its
501
/// `Deref` and `DerefMut` implementations.
502
#[clippy::has_significant_drop]
503
#[must_use = "if unused the Mutex will immediately unlock"]
504
pub struct MutexGuard<'a, R: RawMutex, T: ?Sized> {
505
    mutex: &'a Mutex<R, T>,
506
    marker: PhantomData<(&'a mut T, R::GuardMarker)>,
507
}
508
509
unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync for MutexGuard<'a, R, T> {}
510
511
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
512
    /// Returns a reference to the original `Mutex` object.
513
803k
    pub fn mutex(s: &Self) -> &'a Mutex<R, T> {
514
803k
        s.mutex
515
803k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::blocking::pool::Shared>>::mutex
Line
Count
Source
513
260k
    pub fn mutex(s: &Self) -> &'a Mutex<R, T> {
514
260k
        s.mutex
515
260k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, ()>>::mutex
Line
Count
Source
513
543k
    pub fn mutex(s: &Self) -> &'a Mutex<R, T> {
514
543k
        s.mutex
515
543k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<_, _>>::mutex
516
517
    /// Makes a new `MappedMutexGuard` for a component of the locked data.
518
    ///
519
    /// This operation cannot fail as the `MutexGuard` passed
520
    /// in already locked the mutex.
521
    ///
522
    /// This is an associated function that needs to be
523
    /// used as `MutexGuard::map(...)`. A method would interfere with methods of
524
    /// the same name on the contents of the locked data.
525
    #[inline]
526
0
    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
527
0
    where
528
0
        F: FnOnce(&mut T) -> &mut U,
529
    {
530
0
        let raw = &s.mutex.raw;
531
0
        let data = f(unsafe { &mut *s.mutex.data.get() });
532
0
        mem::forget(s);
533
0
        MappedMutexGuard {
534
0
            raw,
535
0
            data,
536
0
            marker: PhantomData,
537
0
        }
538
0
    }
539
540
    /// Attempts to make a new `MappedMutexGuard` for a component of the
541
    /// locked data. The original guard is returned if the closure returns `None`.
542
    ///
543
    /// This operation cannot fail as the `MutexGuard` passed
544
    /// in already locked the mutex.
545
    ///
546
    /// This is an associated function that needs to be
547
    /// used as `MutexGuard::try_map(...)`. A method would interfere with methods of
548
    /// the same name on the contents of the locked data.
549
    #[inline]
550
0
    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
551
0
    where
552
0
        F: FnOnce(&mut T) -> Option<&mut U>,
553
    {
554
0
        let raw = &s.mutex.raw;
555
0
        let data = match f(unsafe { &mut *s.mutex.data.get() }) {
556
0
            Some(data) => data,
557
0
            None => return Err(s),
558
        };
559
0
        mem::forget(s);
560
0
        Ok(MappedMutexGuard {
561
0
            raw,
562
0
            data,
563
0
            marker: PhantomData,
564
0
        })
565
0
    }
566
567
    /// Attempts to make a new `MappedMutexGuard` for a component of the
568
    /// locked data. The original guard is returned alongside arbitrary user data
569
    /// if the closure returns `Err`.
570
    ///
571
    /// This operation cannot fail as the `MutexGuard` passed
572
    /// in already locked the mutex.
573
    ///
574
    /// This is an associated function that needs to be
575
    /// used as `MutexGuard::try_map_or_err(...)`. A method would interfere with methods of
576
    /// the same name on the contents of the locked data.
577
    #[inline]
578
0
    pub fn try_map_or_err<U: ?Sized, F, E>(
579
0
        s: Self,
580
0
        f: F,
581
0
    ) -> Result<MappedMutexGuard<'a, R, U>, (Self, E)>
582
0
    where
583
0
        F: FnOnce(&mut T) -> Result<&mut U, E>,
584
    {
585
0
        let raw = &s.mutex.raw;
586
0
        let data = match f(unsafe { &mut *s.mutex.data.get() }) {
587
0
            Ok(data) => data,
588
0
            Err(e) => return Err((s, e)),
589
        };
590
0
        mem::forget(s);
591
0
        Ok(MappedMutexGuard {
592
0
            raw,
593
0
            data,
594
0
            marker: PhantomData,
595
0
        })
596
0
    }
597
598
    /// Temporarily unlocks the mutex to execute the given function.
599
    ///
600
    /// This is safe because `&mut` guarantees that there exist no other
601
    /// references to the data protected by the mutex.
602
    #[inline]
603
    #[track_caller]
604
0
    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
605
0
    where
606
0
        F: FnOnce() -> U,
607
    {
608
        // Safety: A MutexGuard always holds the lock.
609
0
        unsafe {
610
0
            s.mutex.raw.unlock();
611
0
        }
612
0
        defer!(s.mutex.raw.lock());
613
0
        f()
614
0
    }
615
616
    /// Leaks the mutex guard and returns a mutable reference to the data
617
    /// protected by the mutex.
618
    ///
619
    /// This will leave the `Mutex` in a locked state.
620
    #[inline]
621
0
    pub fn leak(s: Self) -> &'a mut T {
622
0
        let r = unsafe { &mut *s.mutex.data.get() };
623
0
        mem::forget(s);
624
0
        r
625
0
    }
626
}
627
628
impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MutexGuard<'a, R, T> {
629
    /// Unlocks the mutex using a fair unlock protocol.
630
    ///
631
    /// By default, mutexes are unfair and allow the current thread to re-lock
632
    /// the mutex before another has the chance to acquire the lock, even if
633
    /// that thread has been blocked on the mutex for a long time. This is the
634
    /// default because it allows much higher throughput as it avoids forcing a
635
    /// context switch on every mutex unlock. This can result in one thread
636
    /// acquiring a mutex many more times than other threads.
637
    ///
638
    /// However in some cases it can be beneficial to ensure fairness by forcing
639
    /// the lock to pass on to a waiting thread if there is one. This is done by
640
    /// using this method instead of dropping the `MutexGuard` normally.
641
    #[inline]
642
    #[track_caller]
643
0
    pub fn unlock_fair(s: Self) {
644
        // Safety: A MutexGuard always holds the lock.
645
0
        unsafe {
646
0
            s.mutex.raw.unlock_fair();
647
0
        }
648
0
        mem::forget(s);
649
0
    }
650
651
    /// Temporarily unlocks the mutex to execute the given function.
652
    ///
653
    /// The mutex is unlocked using a fair unlock protocol.
654
    ///
655
    /// This is safe because `&mut` guarantees that there exist no other
656
    /// references to the data protected by the mutex.
657
    #[inline]
658
    #[track_caller]
659
0
    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
660
0
    where
661
0
        F: FnOnce() -> U,
662
    {
663
        // Safety: A MutexGuard always holds the lock.
664
0
        unsafe {
665
0
            s.mutex.raw.unlock_fair();
666
0
        }
667
0
        defer!(s.mutex.raw.lock());
668
0
        f()
669
0
    }
670
671
    /// Temporarily yields the mutex to a waiting thread if there is one.
672
    ///
673
    /// This method is functionally equivalent to calling `unlock_fair` followed
674
    /// by `lock`, however it can be much more efficient in the case where there
675
    /// are no waiting threads.
676
    #[inline]
677
    #[track_caller]
678
0
    pub fn bump(s: &mut Self) {
679
        // Safety: A MutexGuard always holds the lock.
680
0
        unsafe {
681
0
            s.mutex.raw.bump();
682
0
        }
683
0
    }
684
}
685
686
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MutexGuard<'a, R, T> {
687
    type Target = T;
688
    #[inline]
689
6.46M
    fn deref(&self) -> &T {
690
6.46M
        unsafe { &*self.mutex.data.get() }
691
6.46M
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, core::option::Option<tokio::sync::watch::Receiver<()>>> as core::ops::deref::Deref>::deref
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<alloc::boxed::Box<tokio::runtime::scheduler::multi_thread::worker::Core>>> as core::ops::deref::Deref>::deref
Line
Count
Source
689
547k
    fn deref(&self) -> &T {
690
547k
        unsafe { &*self.mutex.data.get() }
691
547k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<std::process::Child>> as core::ops::deref::Deref>::deref
Line
Count
Source
689
20.9k
    fn deref(&self) -> &T {
690
20.9k
        unsafe { &*self.mutex.data.get() }
691
20.9k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::sync::notify::Waiter, tokio::sync::notify::Waiter>> as core::ops::deref::Deref>::deref
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::sync::batch_semaphore::Waitlist> as core::ops::deref::Deref>::deref
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::time::clock::Inner> as core::ops::deref::Deref>::deref
Line
Count
Source
689
76.1k
    fn deref(&self) -> &T {
690
76.1k
        unsafe { &*self.mutex.data.get() }
691
76.1k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::time::InnerState> as core::ops::deref::Deref>::deref
Line
Count
Source
689
97.1k
    fn deref(&self) -> &T {
690
97.1k
        unsafe { &*self.mutex.data.get() }
691
97.1k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::blocking::pool::Shared> as core::ops::deref::Deref>::deref
Line
Count
Source
689
4.63M
    fn deref(&self) -> &T {
690
4.63M
        unsafe { &*self.mutex.data.get() }
691
4.63M
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::multi_thread::worker::Synced> as core::ops::deref::Deref>::deref
Line
Count
Source
689
1.09M
    fn deref(&self) -> &T {
690
1.09M
        unsafe { &*self.mutex.data.get() }
691
1.09M
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<_, _> as core::ops::deref::Deref>::deref
692
}
693
694
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MutexGuard<'a, R, T> {
695
    #[inline]
696
74.7M
    fn deref_mut(&mut self) -> &mut T {
697
74.7M
        unsafe { &mut *self.mutex.data.get() }
698
74.7M
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, core::option::Option<tokio::sync::watch::Receiver<()>>> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
696
20.9k
    fn deref_mut(&mut self) -> &mut T {
697
20.9k
        unsafe { &mut *self.mutex.data.get() }
698
20.9k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, core::option::Option<alloc::collections::vec_deque::VecDeque<tokio::runtime::task::Notified<alloc::sync::Arc<tokio::task::local::Shared>>>>> as core::ops::deref::DerefMut>::deref_mut
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<alloc::boxed::Box<tokio::runtime::scheduler::multi_thread::worker::Core>>> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
696
564k
    fn deref_mut(&mut self) -> &mut T {
697
564k
        unsafe { &mut *self.mutex.data.get() }
698
564k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<std::process::Child>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::current_thread::Handle>>, tokio::runtime::task::core::Header>> as core::ops::deref::DerefMut>::deref_mut
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>, tokio::runtime::task::core::Header>> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
696
70.1M
    fn deref_mut(&mut self) -> &mut T {
697
70.1M
        unsafe { &mut *self.mutex.data.get() }
698
70.1M
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::sync::notify::Waiter, tokio::sync::notify::Waiter>> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::sync::batch_semaphore::Waitlist> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::time::clock::Inner> as core::ops::deref::DerefMut>::deref_mut
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::time::InnerState> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
696
97.1k
    fn deref_mut(&mut self) -> &mut T {
697
97.1k
        unsafe { &mut *self.mutex.data.get() }
698
97.1k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::io::util::mem::SimplexStream> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::scheduled_io::Waiters> as core::ops::deref::DerefMut>::deref_mut
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::registration_set::Synced> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
696
17.1k
    fn deref_mut(&mut self) -> &mut T {
697
17.1k
        unsafe { &mut *self.mutex.data.get() }
698
17.1k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::blocking::pool::Shared> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
696
3.35M
    fn deref_mut(&mut self) -> &mut T {
697
3.35M
        unsafe { &mut *self.mutex.data.get() }
698
3.35M
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::multi_thread::worker::Synced> as core::ops::deref::DerefMut>::deref_mut
Line
Count
Source
696
564k
    fn deref_mut(&mut self) -> &mut T {
697
564k
        unsafe { &mut *self.mutex.data.get() }
698
564k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::inject::synced::Synced> as core::ops::deref::DerefMut>::deref_mut
Unexecuted instantiation: <lock_api::mutex::MutexGuard<_, _> as core::ops::deref::DerefMut>::deref_mut
699
}
700
701
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MutexGuard<'a, R, T> {
702
    #[inline]
703
75.2M
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
75.2M
        unsafe {
706
75.2M
            self.mutex.raw.unlock();
707
75.2M
        }
708
75.2M
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, core::option::Option<tokio::sync::watch::Receiver<()>>> as core::ops::drop::Drop>::drop
Line
Count
Source
703
20.9k
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
20.9k
        unsafe {
706
20.9k
            self.mutex.raw.unlock();
707
20.9k
        }
708
20.9k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, core::option::Option<alloc::collections::vec_deque::VecDeque<tokio::runtime::task::Notified<alloc::sync::Arc<tokio::task::local::Shared>>>>> as core::ops::drop::Drop>::drop
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<alloc::boxed::Box<tokio::runtime::scheduler::multi_thread::worker::Core>>> as core::ops::drop::Drop>::drop
Line
Count
Source
703
547k
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
547k
        unsafe {
706
547k
            self.mutex.raw.unlock();
707
547k
        }
708
547k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, alloc::vec::Vec<std::process::Child>> as core::ops::drop::Drop>::drop
Line
Count
Source
703
20.9k
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
20.9k
        unsafe {
706
20.9k
            self.mutex.raw.unlock();
707
20.9k
        }
708
20.9k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::current_thread::Handle>>, tokio::runtime::task::core::Header>> as core::ops::drop::Drop>::drop
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::runtime::task::Task<alloc::sync::Arc<tokio::runtime::scheduler::multi_thread::handle::Handle>>, tokio::runtime::task::core::Header>> as core::ops::drop::Drop>::drop
Line
Count
Source
703
70.1M
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
70.1M
        unsafe {
706
70.1M
            self.mutex.raw.unlock();
707
70.1M
        }
708
70.1M
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::util::linked_list::LinkedList<tokio::sync::notify::Waiter, tokio::sync::notify::Waiter>> as core::ops::drop::Drop>::drop
Line
Count
Source
703
130
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
130
        unsafe {
706
130
            self.mutex.raw.unlock();
707
130
        }
708
130
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::sync::batch_semaphore::Waitlist> as core::ops::drop::Drop>::drop
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::time::clock::Inner> as core::ops::drop::Drop>::drop
Line
Count
Source
703
38.0k
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
38.0k
        unsafe {
706
38.0k
            self.mutex.raw.unlock();
707
38.0k
        }
708
38.0k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::time::InnerState> as core::ops::drop::Drop>::drop
Line
Count
Source
703
59.0k
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
59.0k
        unsafe {
706
59.0k
            self.mutex.raw.unlock();
707
59.0k
        }
708
59.0k
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::io::util::mem::SimplexStream> as core::ops::drop::Drop>::drop
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::scheduled_io::Waiters> as core::ops::drop::Drop>::drop
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::io::registration_set::Synced> as core::ops::drop::Drop>::drop
Line
Count
Source
703
17.1k
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
17.1k
        unsafe {
706
17.1k
            self.mutex.raw.unlock();
707
17.1k
        }
708
17.1k
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::blocking::pool::Shared> as core::ops::drop::Drop>::drop
Line
Count
Source
703
1.66M
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
1.66M
        unsafe {
706
1.66M
            self.mutex.raw.unlock();
707
1.66M
        }
708
1.66M
    }
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::multi_thread::worker::Synced> as core::ops::drop::Drop>::drop
Line
Count
Source
703
1.66M
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
1.66M
        unsafe {
706
1.66M
            self.mutex.raw.unlock();
707
1.66M
        }
708
1.66M
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, tokio::runtime::scheduler::inject::synced::Synced> as core::ops::drop::Drop>::drop
<lock_api::mutex::MutexGuard<parking_lot::raw_mutex::RawMutex, ()> as core::ops::drop::Drop>::drop
Line
Count
Source
703
1.08M
    fn drop(&mut self) {
704
        // Safety: A MutexGuard always holds the lock.
705
1.08M
        unsafe {
706
1.08M
            self.mutex.raw.unlock();
707
1.08M
        }
708
1.08M
    }
Unexecuted instantiation: <lock_api::mutex::MutexGuard<_, _> as core::ops::drop::Drop>::drop
709
}
710
711
impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MutexGuard<'a, R, T> {
712
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
713
0
        fmt::Debug::fmt(&**self, f)
714
0
    }
715
}
716
717
impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display for MutexGuard<'a, R, T> {
718
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719
0
        (**self).fmt(f)
720
0
    }
721
}
722
723
#[cfg(feature = "owning_ref")]
724
unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MutexGuard<'a, R, T> {}
725
726
/// An RAII mutex guard returned by the `Arc` locking operations on `Mutex`.
727
///
728
/// This is similar to the `MutexGuard` struct, except instead of using a reference to unlock the `Mutex` it
729
/// uses an `Arc<Mutex>`. This has several advantages, most notably that it has an `'static` lifetime.
730
#[cfg(feature = "arc_lock")]
731
#[clippy::has_significant_drop]
732
#[must_use = "if unused the Mutex will immediately unlock"]
733
pub struct ArcMutexGuard<R: RawMutex, T: ?Sized> {
734
    mutex: Arc<Mutex<R, T>>,
735
    marker: PhantomData<*const ()>,
736
}
737
738
#[cfg(feature = "arc_lock")]
739
unsafe impl<R: RawMutex + Send + Sync, T: Send + ?Sized> Send for ArcMutexGuard<R, T> where
740
    R::GuardMarker: Send
741
{
742
}
743
#[cfg(feature = "arc_lock")]
744
unsafe impl<R: RawMutex + Sync, T: Sync + ?Sized> Sync for ArcMutexGuard<R, T> where
745
    R::GuardMarker: Sync
746
{
747
}
748
749
#[cfg(feature = "arc_lock")]
750
impl<R: RawMutex, T: ?Sized> ArcMutexGuard<R, T> {
751
    /// Returns a reference to the `Mutex` this is guarding, contained in its `Arc`.
752
    #[inline]
753
    pub fn mutex(s: &Self) -> &Arc<Mutex<R, T>> {
754
        &s.mutex
755
    }
756
757
    /// Unlocks the mutex and returns the `Arc` that was held by the [`ArcMutexGuard`].
758
    #[inline]
759
    #[track_caller]
760
    pub fn into_arc(s: Self) -> Arc<Mutex<R, T>> {
761
        // SAFETY: Skip our Drop impl and manually unlock the mutex.
762
        let s = ManuallyDrop::new(s);
763
        unsafe {
764
            s.mutex.raw.unlock();
765
            ptr::read(&s.mutex)
766
        }
767
    }
768
769
    /// Temporarily unlocks the mutex to execute the given function.
770
    ///
771
    /// This is safe because `&mut` guarantees that there exist no other
772
    /// references to the data protected by the mutex.
773
    #[inline]
774
    #[track_caller]
775
    pub fn unlocked<F, U>(s: &mut Self, f: F) -> U
776
    where
777
        F: FnOnce() -> U,
778
    {
779
        // Safety: A MutexGuard always holds the lock.
780
        unsafe {
781
            s.mutex.raw.unlock();
782
        }
783
        defer!(s.mutex.raw.lock());
784
        f()
785
    }
786
}
787
788
#[cfg(feature = "arc_lock")]
789
impl<R: RawMutexFair, T: ?Sized> ArcMutexGuard<R, T> {
790
    /// Unlocks the mutex using a fair unlock protocol.
791
    ///
792
    /// This is functionally identical to the `unlock_fair` method on [`MutexGuard`].
793
    #[inline]
794
    #[track_caller]
795
    pub fn unlock_fair(s: Self) {
796
        drop(Self::into_arc_fair(s));
797
    }
798
799
    /// Unlocks the mutex using a fair unlock protocol and returns the `Arc` that was held by the [`ArcMutexGuard`].
800
    #[inline]
801
    pub fn into_arc_fair(s: Self) -> Arc<Mutex<R, T>> {
802
        // SAFETY: Skip our Drop impl and manually unlock the mutex.
803
        let s = ManuallyDrop::new(s);
804
        unsafe {
805
            s.mutex.raw.unlock_fair();
806
            ptr::read(&s.mutex)
807
        }
808
    }
809
810
    /// Temporarily unlocks the mutex to execute the given function.
811
    ///
812
    /// This is functionally identical to the `unlocked_fair` method on [`MutexGuard`].
813
    #[inline]
814
    #[track_caller]
815
    pub fn unlocked_fair<F, U>(s: &mut Self, f: F) -> U
816
    where
817
        F: FnOnce() -> U,
818
    {
819
        // Safety: A MutexGuard always holds the lock.
820
        unsafe {
821
            s.mutex.raw.unlock_fair();
822
        }
823
        defer!(s.mutex.raw.lock());
824
        f()
825
    }
826
827
    /// Temporarily yields the mutex to a waiting thread if there is one.
828
    ///
829
    /// This is functionally identical to the `bump` method on [`MutexGuard`].
830
    #[inline]
831
    #[track_caller]
832
    pub fn bump(s: &mut Self) {
833
        // Safety: A MutexGuard always holds the lock.
834
        unsafe {
835
            s.mutex.raw.bump();
836
        }
837
    }
838
}
839
840
#[cfg(feature = "arc_lock")]
841
impl<R: RawMutex, T: ?Sized> Deref for ArcMutexGuard<R, T> {
842
    type Target = T;
843
    #[inline]
844
    fn deref(&self) -> &T {
845
        unsafe { &*self.mutex.data.get() }
846
    }
847
}
848
849
#[cfg(feature = "arc_lock")]
850
impl<R: RawMutex, T: ?Sized> DerefMut for ArcMutexGuard<R, T> {
851
    #[inline]
852
    fn deref_mut(&mut self) -> &mut T {
853
        unsafe { &mut *self.mutex.data.get() }
854
    }
855
}
856
857
#[cfg(feature = "arc_lock")]
858
impl<R: RawMutex, T: ?Sized> Drop for ArcMutexGuard<R, T> {
859
    #[inline]
860
    fn drop(&mut self) {
861
        // Safety: A MutexGuard always holds the lock.
862
        unsafe {
863
            self.mutex.raw.unlock();
864
        }
865
    }
866
}
867
868
/// An RAII mutex guard returned by `MutexGuard::map`, which can point to a
869
/// subfield of the protected data.
870
///
871
/// The main difference between `MappedMutexGuard` and `MutexGuard` is that the
872
/// former doesn't support temporarily unlocking and re-locking, since that
873
/// could introduce soundness issues if the locked object is modified by another
874
/// thread.
875
#[clippy::has_significant_drop]
876
#[must_use = "if unused the Mutex will immediately unlock"]
877
pub struct MappedMutexGuard<'a, R: RawMutex, T: ?Sized> {
878
    raw: &'a R,
879
    data: *mut T,
880
    marker: PhantomData<&'a mut T>,
881
}
882
883
unsafe impl<'a, R: RawMutex + Sync + 'a, T: ?Sized + Sync + 'a> Sync
884
    for MappedMutexGuard<'a, R, T>
885
{
886
}
887
unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + Send + 'a> Send for MappedMutexGuard<'a, R, T> where
888
    R::GuardMarker: Send
889
{
890
}
891
892
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
893
    /// Makes a new `MappedMutexGuard` for a component of the locked data.
894
    ///
895
    /// This operation cannot fail as the `MappedMutexGuard` passed
896
    /// in already locked the mutex.
897
    ///
898
    /// This is an associated function that needs to be
899
    /// used as `MappedMutexGuard::map(...)`. A method would interfere with methods of
900
    /// the same name on the contents of the locked data.
901
    #[inline]
902
0
    pub fn map<U: ?Sized, F>(s: Self, f: F) -> MappedMutexGuard<'a, R, U>
903
0
    where
904
0
        F: FnOnce(&mut T) -> &mut U,
905
    {
906
0
        let raw = s.raw;
907
0
        let data = f(unsafe { &mut *s.data });
908
0
        mem::forget(s);
909
0
        MappedMutexGuard {
910
0
            raw,
911
0
            data,
912
0
            marker: PhantomData,
913
0
        }
914
0
    }
915
916
    /// Attempts to make a new `MappedMutexGuard` for a component of the
917
    /// locked data. The original guard is returned if the closure returns `None`.
918
    ///
919
    /// This operation cannot fail as the `MappedMutexGuard` passed
920
    /// in already locked the mutex.
921
    ///
922
    /// This is an associated function that needs to be
923
    /// used as `MappedMutexGuard::try_map(...)`. A method would interfere with methods of
924
    /// the same name on the contents of the locked data.
925
    #[inline]
926
0
    pub fn try_map<U: ?Sized, F>(s: Self, f: F) -> Result<MappedMutexGuard<'a, R, U>, Self>
927
0
    where
928
0
        F: FnOnce(&mut T) -> Option<&mut U>,
929
    {
930
0
        let raw = s.raw;
931
0
        let data = match f(unsafe { &mut *s.data }) {
932
0
            Some(data) => data,
933
0
            None => return Err(s),
934
        };
935
0
        mem::forget(s);
936
0
        Ok(MappedMutexGuard {
937
0
            raw,
938
0
            data,
939
0
            marker: PhantomData,
940
0
        })
941
0
    }
942
943
    /// Attempts to make a new `MappedMutexGuard` for a component of the
944
    /// locked data. The original guard is returned alongside arbitrary user data
945
    /// if the closure returns `Err`.
946
    ///
947
    /// This operation cannot fail as the `MappedMutexGuard` passed
948
    /// in already locked the mutex.
949
    ///
950
    /// This is an associated function that needs to be
951
    /// used as `MappedMutexGuard::try_map_or_err(...)`. A method would interfere with methods of
952
    /// the same name on the contents of the locked data.
953
    #[inline]
954
0
    pub fn try_map_or_err<U: ?Sized, F, E>(
955
0
        s: Self,
956
0
        f: F,
957
0
    ) -> Result<MappedMutexGuard<'a, R, U>, (Self, E)>
958
0
    where
959
0
        F: FnOnce(&mut T) -> Result<&mut U, E>,
960
    {
961
0
        let raw = s.raw;
962
0
        let data = match f(unsafe { &mut *s.data }) {
963
0
            Ok(data) => data,
964
0
            Err(e) => return Err((s, e)),
965
        };
966
0
        mem::forget(s);
967
0
        Ok(MappedMutexGuard {
968
0
            raw,
969
0
            data,
970
0
            marker: PhantomData,
971
0
        })
972
0
    }
973
}
974
975
impl<'a, R: RawMutexFair + 'a, T: ?Sized + 'a> MappedMutexGuard<'a, R, T> {
976
    /// Unlocks the mutex using a fair unlock protocol.
977
    ///
978
    /// By default, mutexes are unfair and allow the current thread to re-lock
979
    /// the mutex before another has the chance to acquire the lock, even if
980
    /// that thread has been blocked on the mutex for a long time. This is the
981
    /// default because it allows much higher throughput as it avoids forcing a
982
    /// context switch on every mutex unlock. This can result in one thread
983
    /// acquiring a mutex many more times than other threads.
984
    ///
985
    /// However in some cases it can be beneficial to ensure fairness by forcing
986
    /// the lock to pass on to a waiting thread if there is one. This is done by
987
    /// using this method instead of dropping the `MutexGuard` normally.
988
    #[inline]
989
    #[track_caller]
990
0
    pub fn unlock_fair(s: Self) {
991
        // Safety: A MutexGuard always holds the lock.
992
0
        unsafe {
993
0
            s.raw.unlock_fair();
994
0
        }
995
0
        mem::forget(s);
996
0
    }
997
}
998
999
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Deref for MappedMutexGuard<'a, R, T> {
1000
    type Target = T;
1001
    #[inline]
1002
0
    fn deref(&self) -> &T {
1003
0
        unsafe { &*self.data }
1004
0
    }
1005
}
1006
1007
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> DerefMut for MappedMutexGuard<'a, R, T> {
1008
    #[inline]
1009
0
    fn deref_mut(&mut self) -> &mut T {
1010
0
        unsafe { &mut *self.data }
1011
0
    }
1012
}
1013
1014
impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> Drop for MappedMutexGuard<'a, R, T> {
1015
    #[inline]
1016
0
    fn drop(&mut self) {
1017
        // Safety: A MappedMutexGuard always holds the lock.
1018
0
        unsafe {
1019
0
            self.raw.unlock();
1020
0
        }
1021
0
    }
1022
}
1023
1024
impl<'a, R: RawMutex + 'a, T: fmt::Debug + ?Sized + 'a> fmt::Debug for MappedMutexGuard<'a, R, T> {
1025
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1026
0
        fmt::Debug::fmt(&**self, f)
1027
0
    }
1028
}
1029
1030
impl<'a, R: RawMutex + 'a, T: fmt::Display + ?Sized + 'a> fmt::Display
1031
    for MappedMutexGuard<'a, R, T>
1032
{
1033
0
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1034
0
        (**self).fmt(f)
1035
0
    }
1036
}
1037
1038
#[cfg(feature = "owning_ref")]
1039
unsafe impl<'a, R: RawMutex + 'a, T: ?Sized + 'a> StableAddress for MappedMutexGuard<'a, R, T> {}