Fix overflow error in thread::sleep
This commit is contained in:
parent
3313e50594
commit
c02414e9bd
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
25
src/test/run-pass/sleep.rs
Normal file
25
src/test/run-pass/sleep.rs
Normal file
@ -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);
|
||||
}
|
Loading…
Reference in New Issue
Block a user