Skip to content

Commit 2aaf6a0

Browse files
authored
Rollup merge of rust-lang#34363 - GuillaumeGomez:sleep, r=alexcrichton
Fix overflow error in thread::sleep Fixes rust-lang#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?
2 parents e4ff7f0 + c02414e commit 2aaf6a0

File tree

2 files changed

+40
-6
lines changed

2 files changed

+40
-6
lines changed

src/libstd/sys/unix/thread.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,25 @@ impl Thread {
125125
}
126126

127127
pub fn sleep(dur: Duration) {
128-
let mut ts = libc::timespec {
129-
tv_sec: dur.as_secs() as libc::time_t,
130-
tv_nsec: dur.subsec_nanos() as libc::c_long,
131-
};
128+
let mut secs = dur.as_secs();
129+
let mut nsecs = dur.subsec_nanos() as libc::c_long;
132130

133131
// If we're awoken with a signal then the return value will be -1 and
134132
// nanosleep will fill in `ts` with the remaining time.
135133
unsafe {
136-
while libc::nanosleep(&ts, &mut ts) == -1 {
137-
assert_eq!(os::errno(), libc::EINTR);
134+
while secs > 0 || nsecs > 0 {
135+
let mut ts = libc::timespec {
136+
tv_sec: cmp::min(libc::time_t::max_value() as u64, secs) as libc::time_t,
137+
tv_nsec: nsecs,
138+
};
139+
secs -= ts.tv_sec as u64;
140+
if libc::nanosleep(&ts, &mut ts) == -1 {
141+
assert_eq!(os::errno(), libc::EINTR);
142+
secs += ts.tv_sec as u64;
143+
nsecs = ts.tv_nsec;
144+
} else {
145+
nsecs = 0;
146+
}
138147
}
139148
}
140149
}

src/test/run-pass/sleep.rs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
use std::thread::{self, sleep};
12+
use std::time::Duration;
13+
use std::sync::{Arc, Mutex};
14+
use std::u64;
15+
16+
fn main() {
17+
let finished = Arc::new(Mutex::new(false));
18+
let t_finished = finished.clone();
19+
thread::spawn(move || {
20+
sleep(Duration::new(u64::MAX, 0));
21+
*t_finished.lock().unwrap() = true;
22+
});
23+
sleep(Duration::from_millis(100));
24+
assert_eq!(*finished.lock().unwrap(), false);
25+
}

0 commit comments

Comments
 (0)