Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 4208764

Browse files
committed
Auto merge of rust-lang#2466 - RalfJung:longsleep, r=RalfJung
fix an ICE in nanosleep()
2 parents 74c5f1b + d7875ea commit 4208764

File tree

2 files changed

+23
-1
lines changed

2 files changed

+23
-1
lines changed

src/shims/time.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
210210
return Ok(-1);
211211
}
212212
};
213-
let timeout_time = Time::Monotonic(Instant::now().checked_add(duration).unwrap());
213+
// If adding the duration overflows, let's just sleep for an hour. Waking up early is always acceptable.
214+
let timeout_time = Instant::now()
215+
.checked_add(duration)
216+
.unwrap_or_else(|| Instant::now().checked_add(Duration::from_secs(3600)).unwrap());
217+
let timeout_time = Time::Monotonic(timeout_time);
214218

215219
let active_thread = this.get_active_thread();
216220
this.block_thread(active_thread);

tests/pass/sleep_long.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
//@ignore-target-windows: no threads nor sleep on Windows
2+
//@compile-flags: -Zmiri-ignore-leaks -Zmiri-disable-isolation
3+
use std::sync::{Arc, Mutex};
4+
use std::thread;
5+
use std::time::Duration;
6+
7+
fn main() {
8+
let finished = Arc::new(Mutex::new(false));
9+
let t_finished = finished.clone();
10+
thread::spawn(move || {
11+
// Sleep very, very long.
12+
thread::sleep(Duration::new(u64::MAX, 0));
13+
*t_finished.lock().unwrap() = true;
14+
});
15+
thread::sleep(Duration::from_millis(100));
16+
assert_eq!(*finished.lock().unwrap(), false);
17+
// Stopping the main thread will also kill the sleeper.
18+
}

0 commit comments

Comments
 (0)