Skip to content

Commit 4de4acb

Browse files
authored
Unrolled build for #144651
Rollup merge of #144651 - connortsui20:nonpoison_condvar, r=joboet Implementation: `#[feature(nonpoison_condvar)]` Tracking Issue: #134645 This PR continues the effort made in #144022 by adding the implementation of `nonpoison::condvar`. Many of the changes here are similar to the changes made to implement `nonpoison::mutex`. There are two other changes here. The first is that the `Barrier` implementation is migrated to use the `nonpoison::Condvar` instead of the `poison` variant. The second (which might be subject to some discussion) is that `WaitTimeoutResult` is moved up to `mod.rs`, as both `condvar` variants need that type (and I do not know if there is a better place to put it now). ### Related PRs - `nonpoison_rwlock` implementation: #144648 - `nonpoison_once` implementation: #144653
2 parents 846e377 + d210ce7 commit 4de4acb

File tree

11 files changed

+771
-271
lines changed

11 files changed

+771
-271
lines changed

library/std/src/sync/barrier.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
use crate::fmt;
2-
// FIXME(nonpoison_mutex,nonpoison_condvar): switch to nonpoison versions once they are available
3-
use crate::sync::{Condvar, Mutex};
2+
use crate::sync::nonpoison::{Condvar, Mutex};
43

54
/// A barrier enables multiple threads to synchronize the beginning
65
/// of some computation.
@@ -118,12 +117,11 @@ impl Barrier {
118117
/// ```
119118
#[stable(feature = "rust1", since = "1.0.0")]
120119
pub fn wait(&self) -> BarrierWaitResult {
121-
let mut lock = self.lock.lock().unwrap();
120+
let mut lock = self.lock.lock();
122121
let local_gen = lock.generation_id;
123122
lock.count += 1;
124123
if lock.count < self.num_threads {
125-
let _guard =
126-
self.cvar.wait_while(lock, |state| local_gen == state.generation_id).unwrap();
124+
let _guard = self.cvar.wait_while(lock, |state| local_gen == state.generation_id);
127125
BarrierWaitResult(false)
128126
} else {
129127
lock.count = 0;

library/std/src/sync/mod.rs

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ pub use self::poison::{LockResult, PoisonError};
209209
#[doc(inline)]
210210
pub use self::poison::{
211211
Mutex, MutexGuard, TryLockError, TryLockResult,
212-
Condvar, WaitTimeoutResult,
212+
Condvar,
213213
Once, OnceState,
214214
RwLock, RwLockReadGuard, RwLockWriteGuard,
215215
};
@@ -234,3 +234,66 @@ mod barrier;
234234
mod lazy_lock;
235235
mod once_lock;
236236
mod reentrant_lock;
237+
238+
/// A type indicating whether a timed wait on a condition variable returned
239+
/// due to a time out or not.
240+
///
241+
/// It is returned by the [`wait_timeout`] method.
242+
///
243+
/// [`wait_timeout`]: Condvar::wait_timeout
244+
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
245+
#[stable(feature = "wait_timeout", since = "1.5.0")]
246+
pub struct WaitTimeoutResult(bool);
247+
248+
impl WaitTimeoutResult {
249+
/// Returns `true` if the wait was known to have timed out.
250+
///
251+
/// # Examples
252+
///
253+
/// This example spawns a thread which will sleep 20 milliseconds before
254+
/// updating a boolean value and then notifying the condvar.
255+
///
256+
/// The main thread will wait with a 10 millisecond timeout on the condvar
257+
/// and will leave the loop upon timeout.
258+
///
259+
/// ```
260+
/// use std::sync::{Arc, Condvar, Mutex};
261+
/// use std::thread;
262+
/// use std::time::Duration;
263+
///
264+
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
265+
/// let pair2 = Arc::clone(&pair);
266+
///
267+
/// # let handle =
268+
/// thread::spawn(move || {
269+
/// let (lock, cvar) = &*pair2;
270+
///
271+
/// // Let's wait 20 milliseconds before notifying the condvar.
272+
/// thread::sleep(Duration::from_millis(20));
273+
///
274+
/// let mut started = lock.lock().unwrap();
275+
/// // We update the boolean value.
276+
/// *started = true;
277+
/// cvar.notify_one();
278+
/// });
279+
///
280+
/// // Wait for the thread to start up.
281+
/// let (lock, cvar) = &*pair;
282+
/// loop {
283+
/// // Let's put a timeout on the condvar's wait.
284+
/// let result = cvar.wait_timeout(lock.lock().unwrap(), Duration::from_millis(10)).unwrap();
285+
/// // 10 milliseconds have passed.
286+
/// if result.1.timed_out() {
287+
/// // timed out now and we can leave.
288+
/// break
289+
/// }
290+
/// }
291+
/// # // Prevent leaks for Miri.
292+
/// # let _ = handle.join();
293+
/// ```
294+
#[must_use]
295+
#[stable(feature = "wait_timeout", since = "1.5.0")]
296+
pub fn timed_out(&self) -> bool {
297+
self.0
298+
}
299+
}

library/std/src/sync/nonpoison.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ impl fmt::Display for WouldBlock {
2929
}
3030
}
3131

32+
#[unstable(feature = "nonpoison_condvar", issue = "134645")]
33+
pub use self::condvar::Condvar;
3234
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
3335
pub use self::mutex::MappedMutexGuard;
3436
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
@@ -38,5 +40,6 @@ pub use self::rwlock::{MappedRwLockReadGuard, MappedRwLockWriteGuard};
3840
#[unstable(feature = "nonpoison_rwlock", issue = "134645")]
3941
pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
4042

43+
mod condvar;
4144
mod mutex;
4245
mod rwlock;

0 commit comments

Comments
 (0)