Support "sleep" forms of poll_oneoff.

Add support for `poll_oneoff` calls which just sleep on a relative
timeout. This fixes a bug handling code compiled with WASI libc's `sleep`
family of functions, which call `poll_oneoff` with a `CLOCK_REALTIME`
timer, which wasn't previously implemented.
This commit is contained in:
Dan Gohman
2021-03-22 09:11:55 -07:00
parent cba0144612
commit 6b40724d18
2 changed files with 65 additions and 1 deletions

View File

@@ -16,6 +16,7 @@ use std::cell::{Ref, RefMut};
use std::convert::{TryFrom, TryInto};
use std::io::{IoSlice, IoSliceMut};
use std::ops::{Deref, DerefMut};
use std::thread;
use tracing::debug;
use wiggle::GuestPtr;
@@ -909,6 +910,30 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
return Err(Error::invalid_argument().context("nsubscriptions must be nonzero"));
}
// Special-case a `poll_oneoff` which is just sleeping on a single
// relative timer event, such as what WASI libc uses to implement sleep
// functions. This supports all clock IDs, because POSIX says that
// `clock_settime` doesn't effect relative sleeps.
if nsubscriptions == 1 {
let sub = subs.read()?;
if let types::SubscriptionU::Clock(clocksub) = sub.u {
if !clocksub
.flags
.contains(types::Subclockflags::SUBSCRIPTION_CLOCK_ABSTIME)
{
thread::sleep(Duration::from_nanos(clocksub.timeout));
events.write(types::Event {
userdata: sub.userdata,
error: types::Errno::Success,
type_: types::Eventtype::Clock,
fd_readwrite: fd_readwrite_empty(),
})?;
return Ok(1);
}
}
}
let table = self.table();
let mut poll = Poll::new();