8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
10
11
- //! A native mutex and condition variable type
11
+ //! A native mutex and condition variable type.
12
12
//!
13
13
//! This module contains bindings to the platform's native mutex/condition
14
- //! variable primitives. It provides a single type, `StaticNativeMutex`, which can be
15
- //! statically initialized via the `NATIVE_MUTEX_INIT` value. This object serves as
16
- //! both a mutex and a condition variable simultaneously.
14
+ //! variable primitives. It provides two types: `StaticNativeMutex`, which can
15
+ //! be statically initialized via the `NATIVE_MUTEX_INIT` value, and a simple
16
+ //! wrapper `NativeMutex` that has a destructor to clean up after itself. These
17
+ //! objects serve as both mutexes and condition variables simultaneously.
17
18
//!
18
- //! The lock is lazily initialized, but it can only be unsafely destroyed. A
19
- //! statically initialized lock doesn't necessarily have a time at which it can
20
- //! get deallocated. For this reason, there is no `Drop` implementation of the
21
- //! mutex, but rather the `destroy()` method must be invoked manually if
22
- //! destruction of the mutex is desired.
19
+ //! The static lock is lazily initialized, but it can only be unsafely
20
+ //! destroyed. A statically initialized lock doesn't necessarily have a time at
21
+ //! which it can get deallocated. For this reason, there is no `Drop`
22
+ //! implementation of the static mutex, but rather the `destroy()` method must
23
+ //! be invoked manually if destruction of the mutex is desired.
23
24
//!
24
- //! It is not recommended to use this type for idiomatic rust use. This type is
25
- //! appropriate where no other options are available, but other rust concurrency
26
- //! primitives should be used before this type.
25
+ //! The non-static `NativeMutex` type does have a destructor, but cannot be
26
+ //! statically initialized.
27
+ //!
28
+ //! It is not recommended to use this type for idiomatic rust use. These types
29
+ //! are appropriate where no other options are available, but other rust
30
+ //! concurrency primitives should be used before them.
27
31
//!
28
32
//! # Example
29
33
//!
30
34
//! use std::unstable::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
31
35
//!
32
36
//! // Use a statically initialized mutex
33
- //! static mut lock : StaticNativeMutex = NATIVE_MUTEX_INIT;
37
+ //! static mut LOCK : StaticNativeMutex = NATIVE_MUTEX_INIT;
34
38
//!
35
39
//! unsafe {
36
- //! let _guard = lock .lock();
40
+ //! let _guard = LOCK .lock();
37
41
//! } // automatically unlocked here
38
42
//!
39
43
//! // Use a normally initialized mutex
40
44
//! unsafe {
41
- //! let mut lock = StaticNativeMutex::new();
45
+ //! let mut lock = NativeMutex::new();
46
+ //!
47
+ //! {
48
+ //! let _guard = lock.lock();
49
+ //! } // unlocked here
42
50
//!
43
51
//! // sometimes the RAII guard isn't appropriate
44
52
//! lock.lock_noguard();
45
53
//! lock.unlock_noguard();
46
- //!
47
- //! lock.destroy();
48
- //! }
54
+ //! } // `lock` is deallocated here
49
55
50
56
#[ allow( non_camel_case_types) ] ;
51
57
@@ -54,10 +60,20 @@ use ops::Drop;
54
60
55
61
/// A native mutex suitable for storing in statics (that is, it has
56
62
/// the `destroy` method rather than a destructor).
63
+ ///
64
+ /// Prefer the `NativeMutex` type where possible.
57
65
pub struct StaticNativeMutex {
58
66
priv inner : imp:: Mutex ,
59
67
}
60
68
69
+ /// A native mutex with a destructor for clean-up.
70
+ ///
71
+ /// See `StaticNativeMutex` for a version that is suitable for storing in
72
+ /// statics.
73
+ pub struct NativeMutex {
74
+ priv inner : StaticNativeMutex
75
+ }
76
+
61
77
/// Automatically unlocks the mutex that it was created from on
62
78
/// destruction.
63
79
///
@@ -144,6 +160,72 @@ impl StaticNativeMutex {
144
160
pub unsafe fn destroy ( & mut self ) { self . inner . destroy ( ) }
145
161
}
146
162
163
+ impl NativeMutex {
164
+ /// Creates a new mutex.
165
+ ///
166
+ /// The user must be careful to ensure the mutex is not locked when its is
167
+ /// being destroyed.
168
+ pub unsafe fn new ( ) -> NativeMutex {
169
+ NativeMutex { inner : StaticNativeMutex :: new ( ) }
170
+ }
171
+
172
+ /// Acquires this lock. This assumes that the current thread does not
173
+ /// already hold the lock.
174
+ ///
175
+ /// # Example
176
+ /// ```rust
177
+ /// use std::unstable::mutex::NativeMutex;
178
+ /// let mut lock = NativeMutex::new();
179
+ /// unsafe {
180
+ /// let _guard = lock.lock();
181
+ /// // critical section...
182
+ /// } // automatically unlocked in `_guard`'s destructor
183
+ /// ```
184
+ pub unsafe fn lock < ' a > ( & ' a mut self ) -> LockGuard < ' a > {
185
+ self . inner . lock ( )
186
+ }
187
+
188
+ /// Attempts to acquire the lock. The value returned is `Some` if
189
+ /// the attempt succeeded.
190
+ pub unsafe fn trylock < ' a > ( & ' a mut self ) -> Option < LockGuard < ' a > > {
191
+ self . inner . trylock ( )
192
+ }
193
+
194
+ /// Acquire the lock without creating a `LockGuard`.
195
+ ///
196
+ /// Prefer using `.lock`.
197
+ pub unsafe fn lock_noguard ( & mut self ) { self . inner . lock_noguard ( ) }
198
+
199
+ /// Attempts to acquire the lock without creating a
200
+ /// `LockGuard`. The value returned is whether the lock was
201
+ /// acquired or not.
202
+ ///
203
+ /// Prefer using `.trylock`.
204
+ pub unsafe fn trylock_noguard ( & mut self ) -> bool {
205
+ self . inner . trylock_noguard ( )
206
+ }
207
+
208
+ /// Unlocks the lock. This assumes that the current thread already holds the
209
+ /// lock.
210
+ pub unsafe fn unlock_noguard ( & mut self ) { self . inner . unlock_noguard ( ) }
211
+
212
+ /// Block on the internal condition variable.
213
+ ///
214
+ /// This function assumes that the lock is already held. Prefer
215
+ /// using `LockGuard.wait` since that guarantees that the lock is
216
+ /// held.
217
+ pub unsafe fn wait_noguard ( & mut self ) { self . inner . wait_noguard ( ) }
218
+
219
+ /// Signals a thread in `wait` to wake up
220
+ pub unsafe fn signal_noguard ( & mut self ) { self . inner . signal_noguard ( ) }
221
+ }
222
+
223
+ impl Drop for NativeMutex {
224
+ fn drop ( & mut self ) {
225
+ unsafe { self . inner . destroy ( ) }
226
+ }
227
+ }
228
+
147
229
impl < ' a > LockGuard < ' a > {
148
230
/// Block on the internal condition variable.
149
231
pub unsafe fn wait ( & mut self ) {
0 commit comments