Skip to content

Commit 35e63e3

Browse files
committed
std: Stabilization pass for mutex/rwlock/condvar
This commit performs a stabilization pass over the sync::{mutex, rwlock, condvar} modules, marking the following items as stable: * Mutex * Mutex::new * Mutex::lock * Mutex::try_lock * MutexGuard * RWLock * RWLock::new * RWLock::read * RWLock::try_read * RWLock::write * RWLock::try_write * RWLockReadGuard * RWLockWriteGuard * Condvar * Condvar::new * Condvar::wait * Condvar::notify_one * Condvar::notify_all * PoisonError * TryLockError * TryLockError::Poisoned * TryLockError::WouldBlock * LockResult * TryLockResult The following items remain unstable to explore future possibilities of unifying the static/non-static variants of the types: * StaticMutex * StaticMutex::new * StaticMutex::lock * StaticMutex::try_lock * StaticMutex::desroy * StaticRWLock * StaticRWLock::new * StaticRWLock::read * StaticRWLock::try_read * StaticRWLock::write * StaticRWLock::try_write * StaticRWLock::destroy The following items were removed in favor of `Guard<'static, ()>` instead. * StaticMutexGuard * StaticRWLockReadGuard * StaticRWLockWriteGuard
1 parent 76e5ed6 commit 35e63e3

File tree

5 files changed

+149
-227
lines changed

5 files changed

+149
-227
lines changed

src/libstd/sync/condvar.rs

+34-32
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ use prelude::*;
1212

1313
use sync::atomic::{mod, AtomicUint};
1414
use sync::poison::{mod, LockResult};
15-
use sync::CondvarGuard;
1615
use sys_common::condvar as sys;
1716
use sys_common::mutex as sys_mutex;
1817
use time::Duration;
18+
use sync::{mutex, MutexGuard};
1919

2020
/// A Condition Variable
2121
///
@@ -57,6 +57,7 @@ use time::Duration;
5757
/// started = cvar.wait(started).unwrap();
5858
/// }
5959
/// ```
60+
#[stable]
6061
pub struct Condvar { inner: Box<StaticCondvar> }
6162

6263
unsafe impl Send for Condvar {}
@@ -74,6 +75,7 @@ unsafe impl Sync for Condvar {}
7475
///
7576
/// static CVAR: StaticCondvar = CONDVAR_INIT;
7677
/// ```
78+
#[unstable = "may be merged with Condvar in the future"]
7779
pub struct StaticCondvar {
7880
inner: sys::Condvar,
7981
mutex: AtomicUint,
@@ -83,24 +85,16 @@ unsafe impl Send for StaticCondvar {}
8385
unsafe impl Sync for StaticCondvar {}
8486

8587
/// Constant initializer for a statically allocated condition variable.
88+
#[unstable = "may be merged with Condvar in the future"]
8689
pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
8790
inner: sys::CONDVAR_INIT,
8891
mutex: atomic::INIT_ATOMIC_UINT,
8992
};
9093

91-
/// A trait for vaules which can be passed to the waiting methods of condition
92-
/// variables. This is implemented by the mutex guards in this module.
93-
///
94-
/// Note that this trait should likely not be implemented manually unless you
95-
/// really know what you're doing.
96-
pub trait AsGuard {
97-
#[allow(missing_docs)]
98-
fn as_guard(&self) -> CondvarGuard;
99-
}
100-
10194
impl Condvar {
10295
/// Creates a new condition variable which is ready to be waited on and
10396
/// notified.
97+
#[stable]
10498
pub fn new() -> Condvar {
10599
Condvar {
106100
inner: box StaticCondvar {
@@ -136,11 +130,12 @@ impl Condvar {
136130
/// over time. Each condition variable is dynamically bound to exactly one
137131
/// mutex to ensure defined behavior across platforms. If this functionality
138132
/// is not desired, then unsafe primitives in `sys` are provided.
139-
pub fn wait<T: AsGuard>(&self, mutex_guard: T)
140-
-> LockResult<T> {
133+
#[stable]
134+
pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>)
135+
-> LockResult<MutexGuard<'a, T>> {
141136
unsafe {
142137
let me: &'static Condvar = &*(self as *const _);
143-
me.inner.wait(mutex_guard)
138+
me.inner.wait(guard)
144139
}
145140
}
146141

@@ -164,11 +159,11 @@ impl Condvar {
164159
// provide. There are also additional concerns about the unix-specific
165160
// implementation which may need to be addressed.
166161
#[allow(dead_code)]
167-
fn wait_timeout<T: AsGuard>(&self, mutex_guard: T, dur: Duration)
168-
-> LockResult<(T, bool)> {
162+
fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration)
163+
-> LockResult<(MutexGuard<'a, T>, bool)> {
169164
unsafe {
170165
let me: &'static Condvar = &*(self as *const _);
171-
me.inner.wait_timeout(mutex_guard, dur)
166+
me.inner.wait_timeout(guard, dur)
172167
}
173168
}
174169

@@ -179,6 +174,7 @@ impl Condvar {
179174
/// `notify_one` are not buffered in any way.
180175
///
181176
/// To wake up all threads, see `notify_one()`.
177+
#[stable]
182178
pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
183179

184180
/// Wake up all blocked threads on this condvar.
@@ -188,6 +184,7 @@ impl Condvar {
188184
/// way.
189185
///
190186
/// To wake up only one thread, see `notify_one()`.
187+
#[stable]
191188
pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
192189
}
193190

@@ -202,17 +199,19 @@ impl StaticCondvar {
202199
/// notification.
203200
///
204201
/// See `Condvar::wait`.
205-
pub fn wait<T: AsGuard>(&'static self, mutex_guard: T) -> LockResult<T> {
202+
#[unstable = "may be merged with Condvar in the future"]
203+
pub fn wait<'a, T>(&'static self, guard: MutexGuard<'a, T>)
204+
-> LockResult<MutexGuard<'a, T>> {
206205
let poisoned = unsafe {
207-
let cvar_guard = mutex_guard.as_guard();
208-
self.verify(cvar_guard.lock);
209-
self.inner.wait(cvar_guard.lock);
210-
cvar_guard.poisoned.get()
206+
let lock = mutex::guard_lock(&guard);
207+
self.verify(lock);
208+
self.inner.wait(lock);
209+
mutex::guard_poison(&guard).get()
211210
};
212211
if poisoned {
213-
Err(poison::new_poison_error(mutex_guard))
212+
Err(poison::new_poison_error(guard))
214213
} else {
215-
Ok(mutex_guard)
214+
Ok(guard)
216215
}
217216
}
218217

@@ -221,29 +220,31 @@ impl StaticCondvar {
221220
///
222221
/// See `Condvar::wait_timeout`.
223222
#[allow(dead_code)] // may want to stabilize this later, see wait_timeout above
224-
fn wait_timeout<T: AsGuard>(&'static self, mutex_guard: T, dur: Duration)
225-
-> LockResult<(T, bool)> {
223+
fn wait_timeout<'a, T>(&'static self, guard: MutexGuard<'a, T>, dur: Duration)
224+
-> LockResult<(MutexGuard<'a, T>, bool)> {
226225
let (poisoned, success) = unsafe {
227-
let cvar_guard = mutex_guard.as_guard();
228-
self.verify(cvar_guard.lock);
229-
let success = self.inner.wait_timeout(cvar_guard.lock, dur);
230-
(cvar_guard.poisoned.get(), success)
226+
let lock = mutex::guard_lock(&guard);
227+
self.verify(lock);
228+
let success = self.inner.wait_timeout(lock, dur);
229+
(mutex::guard_poison(&guard).get(), success)
231230
};
232231
if poisoned {
233-
Err(poison::new_poison_error((mutex_guard, success)))
232+
Err(poison::new_poison_error((guard, success)))
234233
} else {
235-
Ok((mutex_guard, success))
234+
Ok((guard, success))
236235
}
237236
}
238237

239238
/// Wake up one blocked thread on this condvar.
240239
///
241240
/// See `Condvar::notify_one`.
241+
#[unstable = "may be merged with Condvar in the future"]
242242
pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } }
243243

244244
/// Wake up all blocked threads on this condvar.
245245
///
246246
/// See `Condvar::notify_all`.
247+
#[unstable = "may be merged with Condvar in the future"]
247248
pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } }
248249

249250
/// Deallocate all resources associated with this static condvar.
@@ -252,6 +253,7 @@ impl StaticCondvar {
252253
/// active users of the condvar, and this also doesn't prevent any future
253254
/// users of the condvar. This method is required to be called to not leak
254255
/// memory on all platforms.
256+
#[unstable = "may be merged with Condvar in the future"]
255257
pub unsafe fn destroy(&'static self) {
256258
self.inner.destroy()
257259
}

src/libstd/sync/mod.rs

+2-12
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,13 @@
1717
1818
#![experimental]
1919

20-
use sys_common::mutex as sys_mutex;
21-
2220
pub use alloc::arc::{Arc, Weak};
2321

24-
pub use self::mutex::{Mutex, MutexGuard, StaticMutex, StaticMutexGuard};
22+
pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
2523
pub use self::mutex::MUTEX_INIT;
2624
pub use self::rwlock::{RWLock, StaticRWLock, RWLOCK_INIT};
2725
pub use self::rwlock::{RWLockReadGuard, RWLockWriteGuard};
28-
pub use self::rwlock::{StaticRWLockReadGuard, StaticRWLockWriteGuard};
29-
pub use self::condvar::{Condvar, StaticCondvar, CONDVAR_INIT, AsGuard};
26+
pub use self::condvar::{Condvar, StaticCondvar, CONDVAR_INIT};
3027
pub use self::once::{Once, ONCE_INIT};
3128
pub use self::semaphore::{Semaphore, SemaphoreGuard};
3229
pub use self::barrier::Barrier;
@@ -45,10 +42,3 @@ mod poison;
4542
mod rwlock;
4643
mod semaphore;
4744
mod task_pool;
48-
49-
/// Structure returned by `AsGuard` to wait on a condition variable.
50-
// NB: defined here to all modules have access to these private fields.
51-
pub struct CondvarGuard<'a> {
52-
lock: &'a sys_mutex::Mutex,
53-
poisoned: &'a poison::Flag,
54-
}

0 commit comments

Comments
 (0)