diff options
| author | Manish Goregaokar <manishsmail@gmail.com> | 2016-06-22 09:51:07 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2016-06-22 09:51:07 +0100 |
| commit | 2aaf6a0e5cf5a857eb801fc8d9ebf5ae8e662085 (patch) | |
| tree | 47dbf70939900fb58c4ea94a59b96ba0861a6b93 | |
| parent | e4ff7f0107a1c612285e6c3c265f227830761e26 (diff) | |
| parent | c02414e9bd4326d3db8d54a1cf4707089737b414 (diff) | |
| download | rust-2aaf6a0e5cf5a857eb801fc8d9ebf5ae8e662085.tar.gz rust-2aaf6a0e5cf5a857eb801fc8d9ebf5ae8e662085.zip | |
Rollup merge of #34363 - GuillaumeGomez:sleep, r=alexcrichton
Fix overflow error in thread::sleep Fixes #34330 I added a test to have a more clear error inside the function. Since `time_t` is `i64` and we expect `u64`, maybe we should changed the awaited type?
| -rw-r--r-- | src/libstd/sys/unix/thread.rs | 21 | ||||
| -rw-r--r-- | src/test/run-pass/sleep.rs | 25 |
2 files changed, 40 insertions, 6 deletions
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs index cb34d1a5fbc..371319a93d2 100644 --- a/src/libstd/sys/unix/thread.rs +++ b/src/libstd/sys/unix/thread.rs @@ -125,16 +125,25 @@ impl Thread { } pub fn sleep(dur: Duration) { - let mut ts = libc::timespec { - tv_sec: dur.as_secs() as libc::time_t, - tv_nsec: dur.subsec_nanos() as libc::c_long, - }; + let mut secs = dur.as_secs(); + let mut nsecs = dur.subsec_nanos() as libc::c_long; // If we're awoken with a signal then the return value will be -1 and // nanosleep will fill in `ts` with the remaining time. unsafe { - while libc::nanosleep(&ts, &mut ts) == -1 { - assert_eq!(os::errno(), libc::EINTR); + while secs > 0 || nsecs > 0 { + let mut ts = libc::timespec { + tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t, + tv_nsec: nsecs, + }; + secs -= ts.tv_sec as u64; + if libc::nanosleep(&ts, &mut ts) == -1 { + assert_eq!(os::errno(), libc::EINTR); + secs += ts.tv_sec as u64; + nsecs = ts.tv_nsec; + } else { + nsecs = 0; + } } } } diff --git a/src/test/run-pass/sleep.rs b/src/test/run-pass/sleep.rs new file mode 100644 index 00000000000..8b06b02f3cb --- /dev/null +++ b/src/test/run-pass/sleep.rs @@ -0,0 +1,25 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or +// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license +// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::thread::{self, sleep}; +use std::time::Duration; +use std::sync::{Arc, Mutex}; +use std::u64; + +fn main() { + let finished = Arc::new(Mutex::new(false)); + let t_finished = finished.clone(); + thread::spawn(move || { + sleep(Duration::new(u64::MAX, 0)); + *t_finished.lock().unwrap() = true; + }); + sleep(Duration::from_millis(100)); + assert_eq!(*finished.lock().unwrap(), false); +} |
