wasi_common/
sched.rs

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