Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion library/std/src/sync/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ pub use self::poison::{LockResult, PoisonError};
#[doc(inline)]
pub use self::poison::{
Mutex, MutexGuard, TryLockError, TryLockResult,
Condvar, WaitTimeoutResult,
Condvar,
Once, OnceState,
RwLock, RwLockReadGuard, RwLockWriteGuard,
};
Expand All @@ -234,3 +234,66 @@ mod barrier;
mod lazy_lock;
mod once_lock;
mod reentrant_lock;

/// A type indicating whether a timed wait on a condition variable returned
/// due to a time out or not.
///
/// It is returned by the [`wait_timeout`] method.
///
/// [`wait_timeout`]: Condvar::wait_timeout
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[stable(feature = "wait_timeout", since = "1.5.0")]
pub struct WaitTimeoutResult(bool);
Comment on lines +238 to +246
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not actually sure that this is the best place to put it, but I do think this is still better than leaving it in poison


impl WaitTimeoutResult {
/// Returns `true` if the wait was known to have timed out.
///
/// # Examples
///
/// This example spawns a thread which will sleep 20 milliseconds before
/// updating a boolean value and then notifying the condvar.
///
/// The main thread will wait with a 10 millisecond timeout on the condvar
/// and will leave the loop upon timeout.
///
/// ```
/// use std::sync::{Arc, Condvar, Mutex};
/// use std::thread;
/// use std::time::Duration;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = Arc::clone(&pair);
///
/// # let handle =
/// thread::spawn(move || {
/// let (lock, cvar) = &*pair2;
///
/// // Let's wait 20 milliseconds before notifying the condvar.
/// thread::sleep(Duration::from_millis(20));
///
/// let mut started = lock.lock().unwrap();
/// // We update the boolean value.
/// *started = true;
/// cvar.notify_one();
/// });
///
/// // Wait for the thread to start up.
/// let (lock, cvar) = &*pair;
/// loop {
/// // Let's put a timeout on the condvar's wait.
/// let result = cvar.wait_timeout(lock.lock().unwrap(), Duration::from_millis(10)).unwrap();
/// // 10 milliseconds have passed.
/// if result.1.timed_out() {
/// // timed out now and we can leave.
/// break
/// }
/// }
/// # // Prevent leaks for Miri.
/// # let _ = handle.join();
/// ```
#[must_use]
#[stable(feature = "wait_timeout", since = "1.5.0")]
pub fn timed_out(&self) -> bool {
self.0
}
}
2 changes: 1 addition & 1 deletion library/std/src/sync/nonpoison.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ impl fmt::Display for WouldBlock {
}

#[unstable(feature = "nonpoison_condvar", issue = "134645")]
pub use self::condvar::{Condvar, WaitTimeoutResult};
pub use self::condvar::Condvar;
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
pub use self::mutex::MappedMutexGuard;
#[unstable(feature = "nonpoison_mutex", issue = "134645")]
Expand Down
70 changes: 1 addition & 69 deletions library/std/src/sync/nonpoison/condvar.rs
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reviewers: since this is a semi-large file, it might be good to compare this directly with the poison::condvar module (with the additional reorganizations made in the first commit)

(for copy paste)

delta library/std/src/sync/poison/condvar.rs library/std/src/sync/nonpoison/condvar.rs
diff library/std/src/sync/poison/condvar.rs library/std/src/sync/nonpoison/condvar.rs

Original file line number Diff line number Diff line change
@@ -1,77 +1,9 @@
use crate::fmt;
use crate::sync::WaitTimeoutResult;
use crate::sync::nonpoison::{MutexGuard, mutex};
use crate::sys::sync as sys;
use crate::time::{Duration, Instant};

/// A type indicating whether a timed wait on a condition variable returned
/// due to a time out or not.
///
/// It is returned by the [`wait_timeout`] method.
///
/// [`wait_timeout`]: Condvar::wait_timeout
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[unstable(feature = "nonpoison_condvar", issue = "134645")]
pub struct WaitTimeoutResult(bool);

// FIXME(nonpoison_condvar) this type is duplicated in `poison`. How do we share types that are
// poison-agnostic?
impl WaitTimeoutResult {
/// Returns `true` if the wait was known to have timed out.
///
/// # Examples
///
/// This example spawns a thread which will sleep 20 milliseconds before
/// updating a boolean value and then notifying the condvar.
///
/// The main thread will wait with a 10 millisecond timeout on the condvar
/// and will leave the loop upon timeout.
///
/// ```
/// #![feature(nonpoison_mutex)]
/// #![feature(nonpoison_condvar)]
///
/// use std::sync::nonpoison::{Mutex, Condvar};
/// use std::sync::Arc;
/// use std::thread;
/// use std::time::Duration;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = Arc::clone(&pair);
///
/// # let handle =
/// thread::spawn(move || {
/// let (lock, cvar) = &*pair2;
///
/// // Let's wait 20 milliseconds before notifying the condvar.
/// thread::sleep(Duration::from_millis(20));
///
/// let mut started = lock.lock();
/// // We update the boolean value.
/// *started = true;
/// cvar.notify_one();
/// });
///
/// // Wait for the thread to start up.
/// let (lock, cvar) = &*pair;
/// loop {
/// // Let's put a timeout on the condvar's wait.
/// let result = cvar.wait_timeout(lock.lock(), Duration::from_millis(10));
/// // 10 milliseconds have passed.
/// if result.1.timed_out() {
/// // timed out now and we can leave.
/// break
/// }
/// }
/// # // Prevent leaks for Miri.
/// # let _ = handle.join();
/// ```
#[must_use]
#[unstable(feature = "nonpoison_condvar", issue = "134645")]
pub fn timed_out(&self) -> bool {
self.0
}
}

/// A Condition Variable
///
/// For more information about condition variables, check out the documentation for the poisoning
Expand Down
2 changes: 1 addition & 1 deletion library/std/src/sync/poison.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
//! then the lock will not be poisoned.

#[stable(feature = "rust1", since = "1.0.0")]
pub use self::condvar::{Condvar, WaitTimeoutResult};
pub use self::condvar::Condvar;
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
pub use self::mutex::MappedMutexGuard;
#[stable(feature = "rust1", since = "1.0.0")]
Expand Down
66 changes: 1 addition & 65 deletions library/std/src/sync/poison/condvar.rs
Original file line number Diff line number Diff line change
@@ -1,73 +1,9 @@
use crate::fmt;
use crate::sync::WaitTimeoutResult;
use crate::sync::poison::{self, LockResult, MutexGuard, PoisonError, mutex};
use crate::sys::sync as sys;
use crate::time::{Duration, Instant};

/// A type indicating whether a timed wait on a condition variable returned
/// due to a time out or not.
///
/// It is returned by the [`wait_timeout`] method.
///
/// [`wait_timeout`]: Condvar::wait_timeout
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
#[stable(feature = "wait_timeout", since = "1.5.0")]
pub struct WaitTimeoutResult(bool);

// FIXME(nonpoison_condvar): `WaitTimeoutResult` is actually poisoning-agnostic, it seems.
// Should we take advantage of this fact?
impl WaitTimeoutResult {
/// Returns `true` if the wait was known to have timed out.
///
/// # Examples
///
/// This example spawns a thread which will sleep 20 milliseconds before
/// updating a boolean value and then notifying the condvar.
///
/// The main thread will wait with a 10 millisecond timeout on the condvar
/// and will leave the loop upon timeout.
///
/// ```
/// use std::sync::{Arc, Condvar, Mutex};
/// use std::thread;
/// use std::time::Duration;
///
/// let pair = Arc::new((Mutex::new(false), Condvar::new()));
/// let pair2 = Arc::clone(&pair);
///
/// # let handle =
/// thread::spawn(move || {
/// let (lock, cvar) = &*pair2;
///
/// // Let's wait 20 milliseconds before notifying the condvar.
/// thread::sleep(Duration::from_millis(20));
///
/// let mut started = lock.lock().unwrap();
/// // We update the boolean value.
/// *started = true;
/// cvar.notify_one();
/// });
///
/// // Wait for the thread to start up.
/// let (lock, cvar) = &*pair;
/// loop {
/// // Let's put a timeout on the condvar's wait.
/// let result = cvar.wait_timeout(lock.lock().unwrap(), Duration::from_millis(10)).unwrap();
/// // 10 milliseconds have passed.
/// if result.1.timed_out() {
/// // timed out now and we can leave.
/// break
/// }
/// }
/// # // Prevent leaks for Miri.
/// # let _ = handle.join();
/// ```
#[must_use]
#[stable(feature = "wait_timeout", since = "1.5.0")]
pub fn timed_out(&self) -> bool {
self.0
}
}

/// A Condition Variable
///
/// Condition variables represent the ability to block a thread such that it
Expand Down
Loading