wasi: Fix sleeping for Duration::MAX

This commit fixes an assert in the WASI-specific implementation of
thread sleep to ensure that sleeping for a very large period of time
blocks instead of panicking. This can come up when testing programs that
sleep "forever", for example.
This commit is contained in:
Alex Crichton 2024-08-29 10:31:17 -07:00
parent 6cf068db56
commit c824c1ada7

View File

@ -136,36 +136,37 @@ pub fn set_name(_name: &CStr) {
} }
pub fn sleep(dur: Duration) { pub fn sleep(dur: Duration) {
let nanos = dur.as_nanos(); let mut nanos = dur.as_nanos();
assert!(nanos <= u64::MAX as u128); while nanos > 0 {
const USERDATA: wasi::Userdata = 0x0123_45678;
const USERDATA: wasi::Userdata = 0x0123_45678; let clock = wasi::SubscriptionClock {
id: wasi::CLOCKID_MONOTONIC,
timeout: u64::try_from(nanos).unwrap_or(u64::MAX),
precision: 0,
flags: 0,
};
nanos -= u128::from(clock.timeout);
let clock = wasi::SubscriptionClock { let in_ = wasi::Subscription {
id: wasi::CLOCKID_MONOTONIC, userdata: USERDATA,
timeout: nanos as u64, u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } },
precision: 0, };
flags: 0, unsafe {
}; let mut event: wasi::Event = mem::zeroed();
let res = wasi::poll_oneoff(&in_, &mut event, 1);
let in_ = wasi::Subscription { match (res, event) {
userdata: USERDATA, (
u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } }, Ok(1),
}; wasi::Event {
unsafe { userdata: USERDATA,
let mut event: wasi::Event = mem::zeroed(); error: wasi::ERRNO_SUCCESS,
let res = wasi::poll_oneoff(&in_, &mut event, 1); type_: wasi::EVENTTYPE_CLOCK,
match (res, event) { ..
( },
Ok(1), ) => {}
wasi::Event { _ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
userdata: USERDATA, }
error: wasi::ERRNO_SUCCESS,
type_: wasi::EVENTTYPE_CLOCK,
..
},
) => {}
_ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
} }
} }
} }