1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
use crate::clocks::WasiMonotonicClock; use crate::file::WasiFile; use crate::Error; use cap_std::time::Instant; pub mod subscription; pub use cap_std::time::Duration; pub use subscription::{ MonotonicClockSubscription, RwEventFlags, RwSubscription, Subscription, SubscriptionResult, }; #[wiggle::async_trait] pub trait WasiSched { async fn poll_oneoff<'a>(&self, poll: &mut Poll<'a>) -> Result<(), Error>; async fn sched_yield(&self) -> Result<(), Error>; async fn sleep(&self, duration: Duration) -> Result<(), Error>; } #[derive(Debug, Copy, Clone, PartialEq, Eq)] pub struct Userdata(u64); impl From<u64> for Userdata { fn from(u: u64) -> Userdata { Userdata(u) } } impl From<Userdata> for u64 { fn from(u: Userdata) -> u64 { u.0 } } pub type PollResults = Vec<(SubscriptionResult, Userdata)>; pub struct Poll<'a> { subs: Vec<(Subscription<'a>, Userdata)>, } impl<'a> Poll<'a> { pub fn new() -> Self { Self { subs: Vec::new() } } pub fn subscribe_monotonic_clock( &mut self, clock: &'a dyn WasiMonotonicClock, deadline: Instant, precision: Duration, ud: Userdata, ) { self.subs.push(( Subscription::MonotonicClock(MonotonicClockSubscription { clock, deadline, precision, }), ud, )); } pub fn subscribe_read(&mut self, file: &'a mut dyn WasiFile, ud: Userdata) { self.subs .push((Subscription::Read(RwSubscription::new(file)), ud)); } pub fn subscribe_write(&mut self, file: &'a mut dyn WasiFile, ud: Userdata) { self.subs .push((Subscription::Write(RwSubscription::new(file)), ud)); } pub fn results(self) -> Vec<(SubscriptionResult, Userdata)> { self.subs .into_iter() .filter_map(|(s, ud)| SubscriptionResult::from_subscription(s).map(|r| (r, ud))) .collect() } pub fn is_empty(&self) -> bool { self.subs.is_empty() } pub fn earliest_clock_deadline(&self) -> Option<&MonotonicClockSubscription<'a>> { self.subs .iter() .filter_map(|(s, _ud)| match s { Subscription::MonotonicClock(t) => Some(t), _ => None, }) .min_by(|a, b| a.deadline.cmp(&b.deadline)) } pub fn rw_subscriptions<'b>(&'b mut self) -> impl Iterator<Item = &'b mut Subscription<'a>> { self.subs.iter_mut().filter_map(|(s, _ud)| match s { Subscription::Read { .. } | Subscription::Write { .. } => Some(s), _ => None, }) } }