ctx builder: fix warnings, test harness

This commit is contained in:
Pat Hickey
2021-01-13 11:07:06 -08:00
parent 28c57c0fe3
commit e0e205f8d2
5 changed files with 40 additions and 55 deletions

View File

@@ -15,7 +15,7 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any
// Additionally register any preopened directories if we have them. // Additionally register any preopened directories if we have them.
let mut builder = wasi_c2::WasiCtx::builder(); let mut builder = wasi_c2::WasiCtx::builder();
builder builder = builder
.arg(bin_name)? .arg(bin_name)?
.arg(".")? .arg(".")?
.stdin(Box::new(ReadPipe::from(Vec::new()))) .stdin(Box::new(ReadPipe::from(Vec::new())))
@@ -27,7 +27,7 @@ pub fn instantiate(data: &[u8], bin_name: &str, workspace: Option<&Path>) -> any
let dirfd = let dirfd =
File::open(workspace).context(format!("error while preopening {:?}", workspace))?; File::open(workspace).context(format!("error while preopening {:?}", workspace))?;
let preopen_dir = unsafe { cap_std::fs::Dir::from_std_file(dirfd) }; let preopen_dir = unsafe { cap_std::fs::Dir::from_std_file(dirfd) };
builder.preopened_dir(Box::new(preopen_dir), ".")?; builder = builder.preopened_dir(Box::new(preopen_dir), ".")?;
} }
let snapshot1 = wasi_c2_wasmtime::Wasi::new(&store, builder.build()?); let snapshot1 = wasi_c2_wasmtime::Wasi::new(&store, builder.build()?);

View File

@@ -71,7 +71,7 @@ impl WasiCtxBuilder {
Ok(self) Ok(self)
} }
pub fn stdin(mut self, f: Box<dyn WasiFile>) -> Self { pub fn stdin(self, f: Box<dyn WasiFile>) -> Self {
self.0.insert_file( self.0.insert_file(
0, 0,
f, f,
@@ -80,7 +80,7 @@ impl WasiCtxBuilder {
self self
} }
pub fn stdout(mut self, f: Box<dyn WasiFile>) -> Self { pub fn stdout(self, f: Box<dyn WasiFile>) -> Self {
self.0.insert_file( self.0.insert_file(
1, 1,
f, f,
@@ -89,7 +89,7 @@ impl WasiCtxBuilder {
self self
} }
pub fn stderr(mut self, f: Box<dyn WasiFile>) -> Self { pub fn stderr(self, f: Box<dyn WasiFile>) -> Self {
self.0.insert_file( self.0.insert_file(
2, 2,
f, f,
@@ -105,7 +105,7 @@ impl WasiCtxBuilder {
} }
pub fn preopened_dir( pub fn preopened_dir(
mut self, self,
dir: Box<dyn WasiDir>, dir: Box<dyn WasiDir>,
path: impl AsRef<Path>, path: impl AsRef<Path>,
) -> Result<Self, Error> { ) -> Result<Self, Error> {
@@ -120,7 +120,7 @@ impl WasiCtxBuilder {
Ok(self) Ok(self)
} }
pub fn random(mut self, random: Box<dyn RngCore>) -> Self { pub fn random(self, random: Box<dyn RngCore>) -> Self {
self.0.random.replace(random); self.0.random.replace(random);
self self
} }

View File

@@ -1,13 +1,11 @@
use crate::clocks::WasiSystemClock; use crate::clocks::WasiSystemClock;
use crate::file::WasiFile; use crate::file::WasiFile;
use crate::Error; use crate::Error;
use cap_std::time::SystemTime; use cap_std::time::{Duration, SystemTime};
use std::cell::Ref; use std::cell::Ref;
pub mod subscription; pub mod subscription;
use subscription::{ use subscription::{RwSubscription, Subscription, SubscriptionResult, SystemTimerSubscription};
RwSubscription, Subscription, SubscriptionResult, SubscriptionSet, TimerSubscription,
};
pub trait WasiSched { pub trait WasiSched {
fn poll_oneoff<'a>(&self, poll: &mut Poll<'a>) -> Result<(), Error>; fn poll_oneoff<'a>(&self, poll: &mut Poll<'a>) -> Result<(), Error>;
@@ -47,9 +45,21 @@ impl<'a> Poll<'a> {
pub fn new() -> Self { pub fn new() -> Self {
Self { subs: Vec::new() } Self { subs: Vec::new() }
} }
pub fn subscribe_timer(&mut self, deadline: SystemTime, ud: Userdata) { pub fn subscribe_system_timer(
self.subs &mut self,
.push((Subscription::Timer(TimerSubscription { deadline }), ud)); clock: &'a dyn WasiSystemClock,
deadline: SystemTime,
precision: Duration,
ud: Userdata,
) {
self.subs.push((
Subscription::SystemTimer(SystemTimerSubscription {
clock,
deadline,
precision,
}),
ud,
));
} }
pub fn subscribe_read(&mut self, file: Ref<'a, dyn WasiFile>, ud: Userdata) { pub fn subscribe_read(&mut self, file: Ref<'a, dyn WasiFile>, ud: Userdata) {
self.subs self.subs
@@ -59,15 +69,13 @@ impl<'a> Poll<'a> {
self.subs self.subs
.push((Subscription::Read(RwSubscription::new(file)), ud)); .push((Subscription::Read(RwSubscription::new(file)), ud));
} }
pub fn results(self, clock: &dyn WasiSystemClock) -> Vec<(SubscriptionResult, Userdata)> { pub fn results(self) -> Vec<(SubscriptionResult, Userdata)> {
self.subs self.subs
.into_iter() .into_iter()
.filter_map(|(s, ud)| SubscriptionResult::from_subscription(s, clock).map(|r| (r, ud))) .filter_map(|(s, ud)| SubscriptionResult::from_subscription(s).map(|r| (r, ud)))
.collect() .collect()
} }
pub(crate) fn subscriptions(&'a mut self) -> SubscriptionSet<'a> { pub fn subscriptions(&'a mut self) -> impl Iterator<Item = &Subscription<'a>> {
SubscriptionSet { self.subs.iter().map(|(s, _ud)| s)
subs: self.subs.iter().map(|(s, _ud)| s).collect(),
}
} }
} }

View File

@@ -34,15 +34,17 @@ impl<'a> RwSubscription<'a> {
} }
} }
pub struct TimerSubscription { pub struct SystemTimerSubscription<'a> {
pub clock: &'a dyn WasiSystemClock,
pub deadline: SystemTime, pub deadline: SystemTime,
pub precision: Duration,
} }
impl TimerSubscription { impl<'a> SystemTimerSubscription<'a> {
pub fn result(&self, clock: &dyn WasiSystemClock) -> Option<Result<(), Error>> { pub fn result(&self) -> Option<Result<(), Error>> {
if self if self
.deadline .deadline
.duration_since(clock.now(Duration::from_secs(0))) .duration_since(self.clock.now(self.precision))
.is_ok() .is_ok()
{ {
Some(Ok(())) Some(Ok(()))
@@ -55,46 +57,21 @@ impl TimerSubscription {
pub enum Subscription<'a> { pub enum Subscription<'a> {
Read(RwSubscription<'a>), Read(RwSubscription<'a>),
Write(RwSubscription<'a>), Write(RwSubscription<'a>),
Timer(TimerSubscription), SystemTimer(SystemTimerSubscription<'a>),
}
pub struct SubscriptionSet<'a> {
pub subs: Vec<&'a Subscription<'a>>,
}
impl<'a> SubscriptionSet<'a> {
pub fn earliest_deadline(&self) -> Option<SystemTime> {
self.subs
.iter()
.filter_map(|s| match s {
Subscription::Timer(ts) => Some(ts.deadline),
_ => None,
})
.fold(None, |early, ts| {
if let Some(early) = early {
Some(early.min(ts))
} else {
Some(ts)
}
})
}
} }
pub enum SubscriptionResult { pub enum SubscriptionResult {
Read(Result<(u64, RwEventFlags), Error>), Read(Result<(u64, RwEventFlags), Error>),
Write(Result<(u64, RwEventFlags), Error>), Write(Result<(u64, RwEventFlags), Error>),
Timer(Result<(), Error>), SystemTimer(Result<(), Error>),
} }
impl SubscriptionResult { impl SubscriptionResult {
pub fn from_subscription( pub fn from_subscription(s: Subscription) -> Option<SubscriptionResult> {
s: Subscription,
clock: &dyn WasiSystemClock,
) -> Option<SubscriptionResult> {
match s { match s {
Subscription::Read(s) => s.result().map(SubscriptionResult::Read), Subscription::Read(s) => s.result().map(SubscriptionResult::Read),
Subscription::Write(s) => s.result().map(SubscriptionResult::Write), Subscription::Write(s) => s.result().map(SubscriptionResult::Write),
Subscription::Timer(s) => s.result(clock).map(SubscriptionResult::Timer), Subscription::SystemTimer(s) => s.result().map(SubscriptionResult::SystemTimer),
} }
} }
} }

View File

@@ -909,7 +909,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
self.sched.poll_oneoff(&mut poll)?; self.sched.poll_oneoff(&mut poll)?;
let results = poll.results(self.clocks.system.deref()); let results = poll.results();
let num_results = results.len(); let num_results = results.len();
assert!( assert!(
num_results <= nsubscriptions as usize, num_results <= nsubscriptions as usize,
@@ -964,7 +964,7 @@ impl<'a> wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiCtx {
}, },
} }
} }
SubscriptionResult::Timer(r) => { SubscriptionResult::SystemTimer(r) => {
let type_ = types::Eventtype::Clock; let type_ = types::Eventtype::Clock;
types::Event { types::Event {
userdata, userdata,