diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-08-31 10:08:59 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-31 10:08:59 +0200 |
| commit | 25e3b6641018a917c7e7bcbd1dfc593f15eeb6e3 (patch) | |
| tree | 56962b1c7e8f6064ad1b13548feb2ec07b0e30be | |
| parent | a59c1a429188c8e15ad8d6c6692520b575736869 (diff) | |
| parent | c824c1ada7278ac508143b21dc23aeb1ed7e05a5 (diff) | |
| download | rust-25e3b6641018a917c7e7bcbd1dfc593f15eeb6e3.tar.gz rust-25e3b6641018a917c7e7bcbd1dfc593f15eeb6e3.zip | |
Rollup merge of #129754 - alexcrichton:fix-wasi-long-sleep, r=workingjubilee
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.
| -rw-r--r-- | library/std/src/sys/pal/wasi/thread.rs | 61 |
1 files changed, 31 insertions, 30 deletions
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs index 31c9cbd4699..4b83870fdea 100644 --- a/library/std/src/sys/pal/wasi/thread.rs +++ b/library/std/src/sys/pal/wasi/thread.rs @@ -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"), + } } } } |
