1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
/// Const Init Trait
///
/// This trait is intended for use when implementers of [`ScopedRawMutex`] that can
/// be constructed in const context, e.g. for placing in a `static`
/// Raw scoped mutex trait.
///
/// This mutex is "raw", which means it does not actually contain the protected data, it
/// just implements the mutex mechanism. For most uses you should use `BlockingMutex`
/// from the `scoped-mutex-impls` crate instead, which is generic over a
/// `ScopedRawMutex` and contains the protected data.
///
/// # Safety
///
/// ScopedRawMutex implementations must ensure that, while locked, no other thread can lock
/// the RawMutex concurrently. This can usually be implemented using an [`AtomicBool`]
/// to track the "taken" state. See the `scoped-mutex-impls` crate for examples of
/// correct implementations.
///
/// Unsafe code is allowed to rely on this fact, so incorrect implementations will cause undefined behavior.
///
/// [`AtomicBool`]: core::sync::atomic::AtomicBool
pub unsafe
/// Raw mutex trait.
///
/// This trait represents an implementation of a generic mutual-exclusion lock
/// which may be locked and unlocked freely at any time.
///
/// This mutex is "raw", which means it does not actually contain the protected
/// data, it just implements the mutex mechanism. For most uses you should use
/// `BlockingMutex` from the `mutex` crate instead, which is generic over a
/// `RawMutex` and contains the protected data.
///
/// # `RawMutex` and [`ScopedRawMutex`]
///
/// The `RawMutex` trait is a superset of the [`ScopedRawMutex`] trait. The
/// interface defined in [`ScopedRawMutex`] is more restrictive, and only
/// permits the mutex to be locked for the duration of a single [`FnOnce`] call
/// and unlocked immediately when that closure exits. `RawMutex`, on the other
/// hand, permits a much wider range of potential usage patterns: it may be used
/// to implement a RAII-style lock guard like [`std::sync::Mutex`][s], a
/// "C-style" mutex where explicit `lock` and `unlock` calls have to be paired
/// manually, *or* a scoped closure-based API like [`ScopedRawMutex`].
/// Therefore, **there is [a blanket implementation][blanket] of
/// [`ScopedRawMutex`] for all types that implement `RawMutex`**.
///
/// Some mutex implementations may not be able to implement the full `RawMutex`
/// trait, and may only be able to implement the closure-based
/// [`ScopedRawMutex`] subset. For example, implementations for the
/// [`critical-section`] crate (in [`mutex::raw_impls::cs`][cs]) can only
/// implement the `ScopedRawMutex` trait. However, in general, **mutex
/// implementations that *can* implement the more general `RawMutex` trait
/// should prefer to do so**, as they will be able to be used in code that
/// requires either interface.
///
/// # Safety
///
/// Implementations of this trait must ensure that the mutex is actually
/// exclusive: a lock can't be acquired while the mutex is already locked.
///
/// [blanket]: ScopedRawMutex#impl-ScopedRawMutex-for-M
/// [s]: https://doc.rust-lang.org/stable/std/sync/struct.Mutex.html
/// [cs]: https://docs.rs/mutex/latest/mutex/raw_impls/cs/index.html
/// [critical-section]: https://docs.rs/critical-section/latest/critical_section/
pub unsafe
unsafe
/// Implementation detail of the `ScopedRawMutex` implementation for `RawMutex`.
/// This is a drop guard that unlocks the `RawMutex` when it's dropped. This is
/// used to ensure that the `RawMutex` is always unlocked when the
/// `ScopedRawMutex::with_lock` or `ScopedRawMutex::try_with_lock` closures are
/// exited, even if they are exited by a panic rather than by a normal return.
;