From: Aaron Turon Date: Wed, 1 Apr 2015 19:20:57 +0000 (-0700) Subject: Stabilize basic timeout functionality X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=371277fb0d210152eb8c79e30bd7f7749c5af63c;p=rust.git Stabilize basic timeout functionality This commit renames and stabilizes: * `Condvar::wait_timeout_ms` (renamed from `wait_timeout`) * `thread::park_timeout_ms` (renamed from `park_timeout`) * `thread::sleep_ms` (renamed from `sleep`) In each case, the timeout is taken as a `u32` number of milliseconds, rather than a `Duration`. These functions are likely to be deprecated once a stable form of `Duration` is available, but there is little cost to having these named variants around, and it's crucial functionality for 1.0. [breaking-change] --- diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 69c5267ab69..a7d8b287a64 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -140,33 +140,43 @@ pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) /// Wait on this condition variable for a notification, timing out after a /// specified duration. /// - /// The semantics of this function are equivalent to `wait()` except that - /// the thread will be blocked for roughly no longer than `dur`. This method - /// should not be used for precise timing due to anomalies such as - /// preemption or platform differences that may not cause the maximum amount - /// of time waited to be precisely `dur`. + /// The semantics of this function are equivalent to `wait()` + /// except that the thread will be blocked for roughly no longer + /// than `ms` milliseconds. This method should not be used for + /// precise timing due to anomalies such as preemption or platform + /// differences that may not cause the maximum amount of time + /// waited to be precisely `ms`. /// - /// If the wait timed out, then `false` will be returned. Otherwise if a - /// notification was received then `true` will be returned. + /// The returned boolean is `false` only if the timeout is known + /// to have elapsed. /// /// Like `wait`, the lock specified will be re-acquired when this function /// returns, regardless of whether the timeout elapsed or not. - #[unstable(feature = "std_misc")] - pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration) - -> LockResult<(MutexGuard<'a, T>, bool)> { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn wait_timeout_ms<'a, T>(&self, guard: MutexGuard<'a, T>, ms: u32) + -> LockResult<(MutexGuard<'a, T>, bool)> { unsafe { let me: &'static Condvar = &*(self as *const _); - me.inner.wait_timeout(guard, dur) + me.inner.wait_timeout_ms(guard, ms) } } + /// Deprecated: use `wait_timeout_ms` instead. + #[unstable(feature = "std_misc")] + #[deprecated(since = "1.0.0", reason = "use wait_timeout_ms instead")] + pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration) + -> LockResult<(MutexGuard<'a, T>, bool)> { + self.wait_timeout_ms(guard, dur.num_milliseconds() as u32) + } + /// Wait on this condition variable for a notification, timing out after a /// specified duration. /// /// The semantics of this function are equivalent to `wait_timeout` except /// that the implementation will repeatedly wait while the duration has not /// passed and the provided function returns `false`. - #[unstable(feature = "std_misc")] + #[unstable(feature = "wait_timeout_with", + reason = "unsure if this API is broadly needed or what form it should take")] pub fn wait_timeout_with<'a, T, F>(&self, guard: MutexGuard<'a, T>, dur: Duration, @@ -235,12 +245,12 @@ pub fn wait<'a, T>(&'static self, guard: MutexGuard<'a, T>) /// See `Condvar::wait_timeout`. #[unstable(feature = "std_misc", reason = "may be merged with Condvar in the future")] - pub fn wait_timeout<'a, T>(&'static self, guard: MutexGuard<'a, T>, dur: Duration) - -> LockResult<(MutexGuard<'a, T>, bool)> { + pub fn wait_timeout_ms<'a, T>(&'static self, guard: MutexGuard<'a, T>, ms: u32) + -> LockResult<(MutexGuard<'a, T>, bool)> { let (poisoned, success) = unsafe { let lock = mutex::guard_lock(&guard); self.verify(lock); - let success = self.inner.wait_timeout(lock, dur); + let success = self.inner.wait_timeout(lock, Duration::milliseconds(ms as i64)); (mutex::guard_poison(&guard).get(), success) }; if poisoned { @@ -275,7 +285,8 @@ pub fn wait_timeout_with<'a, T, F>(&'static self, let now = SteadyTime::now(); let consumed = &now - &start; let guard = guard_result.unwrap_or_else(|e| e.into_inner()); - let (new_guard_result, no_timeout) = match self.wait_timeout(guard, dur - consumed) { + let res = self.wait_timeout_ms(guard, (dur - consumed).num_milliseconds() as u32); + let (new_guard_result, no_timeout) = match res { Ok((new_guard, no_timeout)) => (Ok(new_guard), no_timeout), Err(err) => { let (new_guard, no_timeout) = err.into_inner(); @@ -350,6 +361,7 @@ mod tests { use sync::atomic::{AtomicUsize, ATOMIC_USIZE_INIT, Ordering}; use thread; use time::Duration; + use u32; #[test] fn smoke() { @@ -418,19 +430,19 @@ fn notify_all() { } #[test] - fn wait_timeout() { + fn wait_timeout_ms() { static C: StaticCondvar = CONDVAR_INIT; static M: StaticMutex = MUTEX_INIT; let g = M.lock().unwrap(); - let (g, _no_timeout) = C.wait_timeout(g, Duration::nanoseconds(1000)).unwrap(); + let (g, _no_timeout) = C.wait_timeout_ms(g, 1).unwrap(); // spurious wakeups mean this isn't necessarily true // assert!(!no_timeout); let _t = thread::spawn(move || { let _g = M.lock().unwrap(); C.notify_one(); }); - let (g, no_timeout) = C.wait_timeout(g, Duration::days(1)).unwrap(); + let (g, no_timeout) = C.wait_timeout_ms(g, u32::MAX).unwrap(); assert!(no_timeout); drop(g); unsafe { C.destroy(); M.destroy(); } diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs index 1202b353317..c06d89e498d 100644 --- a/src/libstd/thread/mod.rs +++ b/src/libstd/thread/mod.rs @@ -465,9 +465,16 @@ pub fn catch_panic(f: F) -> Result /// specifics or platform-dependent functionality. Note that on unix platforms /// this function will not return early due to a signal being received or a /// spurious wakeup. +#[stable(feature = "rust1", since = "1.0.0")] +pub fn sleep_ms(ms: u32) { + imp::sleep(Duration::milliseconds(ms as i64)) +} + +/// Deprecated: use `sleep_ms` instead. #[unstable(feature = "thread_sleep", reason = "recently added, needs an RFC, and `Duration` itself is \ unstable")] +#[deprecated(since = "1.0.0", reason = "use sleep_ms instead")] pub fn sleep(dur: Duration) { imp::sleep(dur) } @@ -501,17 +508,24 @@ pub fn park() { /// amount of time waited to be precisely *duration* long. /// /// See the module doc for more detail. -#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")] -pub fn park_timeout(duration: Duration) { +#[stable(feature = "rust1", since = "1.0.0")] +pub fn park_timeout_ms(ms: u32) { let thread = current(); let mut guard = thread.inner.lock.lock().unwrap(); if !*guard { - let (g, _) = thread.inner.cvar.wait_timeout(guard, duration).unwrap(); + let (g, _) = thread.inner.cvar.wait_timeout_ms(guard, ms).unwrap(); guard = g; } *guard = false; } +/// Deprecated: use `park_timeout_ms` +#[unstable(feature = "std_misc", reason = "recently introduced, depends on Duration")] +#[deprecated(since = "1.0.0", reason = "use park_timeout_ms instead")] +pub fn park_timeout(duration: Duration) { + park_timeout_ms(duration.num_milliseconds() as u32) +} + //////////////////////////////////////////////////////////////////////////////// // Thread //////////////////////////////////////////////////////////////////////////////// @@ -716,6 +730,7 @@ mod test { use thread; use thunk::Thunk; use time::Duration; + use u32; // !!! These tests are dangerous. If something is buggy, they will hang, !!! // !!! instead of exiting cleanly. This might wedge the buildbots. !!! @@ -936,14 +951,14 @@ fn test_try_panic_message_unit_struct() { fn test_park_timeout_unpark_before() { for _ in 0..10 { thread::current().unpark(); - thread::park_timeout(Duration::seconds(10_000_000)); + thread::park_timeout_ms(u32::MAX); } } #[test] fn test_park_timeout_unpark_not_called() { for _ in 0..10 { - thread::park_timeout(Duration::milliseconds(10)); + thread::park_timeout_ms(10); } } @@ -959,14 +974,13 @@ fn test_park_timeout_unpark_called_other_thread() { th.unpark(); }); - thread::park_timeout(Duration::seconds(10_000_000)); + thread::park_timeout_ms(u32::MAX); } } #[test] - fn sleep_smoke() { - thread::sleep(Duration::milliseconds(2)); - thread::sleep(Duration::milliseconds(-2)); + fn sleep_ms_smoke() { + thread::sleep_ms(2); } // NOTE: the corresponding test for stderr is in run-pass/task-stderr, due