Skip to content

Commit 4f38687

Browse files
Rollup merge of rust-lang#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.
2 parents d79798d + c824c1a commit 4f38687

File tree

1 file changed

+31
-30
lines changed

1 file changed

+31
-30
lines changed

library/std/src/sys/pal/wasi/thread.rs

+31-30
Original file line numberDiff line numberDiff line change
@@ -136,36 +136,37 @@ impl Thread {
136136
}
137137

138138
pub fn sleep(dur: Duration) {
139-
let nanos = dur.as_nanos();
140-
assert!(nanos <= u64::MAX as u128);
141-
142-
const USERDATA: wasi::Userdata = 0x0123_45678;
143-
144-
let clock = wasi::SubscriptionClock {
145-
id: wasi::CLOCKID_MONOTONIC,
146-
timeout: nanos as u64,
147-
precision: 0,
148-
flags: 0,
149-
};
150-
151-
let in_ = wasi::Subscription {
152-
userdata: USERDATA,
153-
u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } },
154-
};
155-
unsafe {
156-
let mut event: wasi::Event = mem::zeroed();
157-
let res = wasi::poll_oneoff(&in_, &mut event, 1);
158-
match (res, event) {
159-
(
160-
Ok(1),
161-
wasi::Event {
162-
userdata: USERDATA,
163-
error: wasi::ERRNO_SUCCESS,
164-
type_: wasi::EVENTTYPE_CLOCK,
165-
..
166-
},
167-
) => {}
168-
_ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
139+
let mut nanos = dur.as_nanos();
140+
while nanos > 0 {
141+
const USERDATA: wasi::Userdata = 0x0123_45678;
142+
143+
let clock = wasi::SubscriptionClock {
144+
id: wasi::CLOCKID_MONOTONIC,
145+
timeout: u64::try_from(nanos).unwrap_or(u64::MAX),
146+
precision: 0,
147+
flags: 0,
148+
};
149+
nanos -= u128::from(clock.timeout);
150+
151+
let in_ = wasi::Subscription {
152+
userdata: USERDATA,
153+
u: wasi::SubscriptionU { tag: 0, u: wasi::SubscriptionUU { clock } },
154+
};
155+
unsafe {
156+
let mut event: wasi::Event = mem::zeroed();
157+
let res = wasi::poll_oneoff(&in_, &mut event, 1);
158+
match (res, event) {
159+
(
160+
Ok(1),
161+
wasi::Event {
162+
userdata: USERDATA,
163+
error: wasi::ERRNO_SUCCESS,
164+
type_: wasi::EVENTTYPE_CLOCK,
165+
..
166+
},
167+
) => {}
168+
_ => panic!("thread::sleep(): unexpected result of poll_oneoff"),
169+
}
169170
}
170171
}
171172
}

0 commit comments

Comments
 (0)