Skip to content

Commit

Permalink
Rollup merge of #129754 - alexcrichton:fix-wasi-long-sleep, r=working…
Browse files Browse the repository at this point in the history
…jubilee

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.

I'll note that I haven't included a test for this since it's sort of difficult to test. I've tested this locally though that long sleeps do indeed block and short sleeps still only sleep for a short amount of time.
  • Loading branch information
matthiaskrgr authored Aug 31, 2024
2 parents a59c1a4 + c824c1a commit 25e3b66
Showing 1 changed file with 31 additions and 30 deletions.
61 changes: 31 additions & 30 deletions library/std/src/sys/pal/wasi/thread.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,36 +136,37 @@ impl Thread {
}

pub fn sleep(dur: Duration) {
let nanos = dur.as_nanos();
assert!(nanos <= u64::MAX as u128);

const USERDATA: wasi::Userdata = 0x0123_45678;

let clock = wasi::SubscriptionClock {
id: wasi::CLOCKID_MONOTONIC,
timeout: nanos as u64,
precision: 0,
flags: 0,
};

let in_ = wasi::Subscription {
userdata: USERDATA,
u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } },
};
unsafe {
let mut event: wasi::Event = mem::zeroed();
let res = wasi::poll_oneoff(&in_, &mut event, 1);
match (res, event) {
(
Ok(1),
wasi::Event {
userdata: USERDATA,
error: wasi::ERRNO_SUCCESS,
type_: wasi::EVENTTYPE_CLOCK,
..
},
) => {}
_ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
let mut nanos = dur.as_nanos();
while nanos > 0 {
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 in_ = wasi::Subscription {
userdata: USERDATA,
u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } },
};
unsafe {
let mut event: wasi::Event = mem::zeroed();
let res = wasi::poll_oneoff(&in_, &mut event, 1);
match (res, event) {
(
Ok(1),
wasi::Event {
userdata: USERDATA,
error: wasi::ERRNO_SUCCESS,
type_: wasi::EVENTTYPE_CLOCK,
..
},
) => {}
_ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
}
}
}
}
Expand Down

0 comments on commit 25e3b66

Please sign in to comment.