Skip to main content

wasmtime_wasi/p3/clocks/
host.rs

1use crate::clocks::WasiClocksCtxView;
2use crate::p3::bindings::clocks::{monotonic_clock, system_clock, types};
3use crate::p3::clocks::WasiClocks;
4use core::time::Duration;
5use tokio::time::sleep;
6use wasmtime::component::Accessor;
7
8impl WasiClocksCtxView<'_> {
9    fn monotonic_wait_until_duration(&mut self, when: monotonic_clock::Mark) -> Option<Duration> {
10        let clock_now = self.ctx.monotonic_clock.now();
11        if when > clock_now {
12            Some(Duration::from_nanos(when - clock_now))
13        } else {
14            None
15        }
16    }
17}
18
19impl types::Host for WasiClocksCtxView<'_> {}
20
21impl system_clock::Host for WasiClocksCtxView<'_> {
22    fn now(&mut self) -> wasmtime::Result<system_clock::Instant> {
23        let now = self.ctx.wall_clock.now();
24        Ok(system_clock::Instant {
25            seconds: now.as_secs().try_into()?,
26            nanoseconds: now.subsec_nanos(),
27        })
28    }
29
30    fn get_resolution(&mut self) -> wasmtime::Result<types::Duration> {
31        let res = self.ctx.wall_clock.resolution();
32        Ok(res.as_nanos().try_into()?)
33    }
34}
35
36impl<U> monotonic_clock::HostWithStore<U> for WasiClocks {
37    async fn wait_until(
38        store: &Accessor<U, Self>,
39        when: monotonic_clock::Mark,
40    ) -> wasmtime::Result<()> {
41        if let Some(dur) = store.with(|mut view| view.get().monotonic_wait_until_duration(when)) {
42            sleep(dur).await;
43        }
44        Ok(())
45    }
46
47    async fn wait_for(
48        _store: &Accessor<U, Self>,
49        duration: types::Duration,
50    ) -> wasmtime::Result<()> {
51        if duration > 0 {
52            sleep(Duration::from_nanos(duration)).await;
53        }
54        Ok(())
55    }
56}
57
58impl monotonic_clock::Host for WasiClocksCtxView<'_> {
59    fn now(&mut self) -> wasmtime::Result<monotonic_clock::Mark> {
60        Ok(self.ctx.monotonic_clock.now())
61    }
62
63    fn get_resolution(&mut self) -> wasmtime::Result<types::Duration> {
64        Ok(self.ctx.monotonic_clock.resolution())
65    }
66}
67
68mod named {
69    use crate::clocks::{WasiClocksNamed, WasiClocksNamedView};
70    use crate::p3::bindings::clocks::monotonic_clock::Mark;
71    use crate::p3::bindings::clocks::system_clock::Instant;
72    use crate::p3::bindings::clocks::types;
73    use crate::p3::bindings::named_imports::wasi::clocks::{monotonic_clock, system_clock};
74    use crate::{NamedId, WasiCtxNamedView};
75    use core::time::Duration;
76    use tokio::time::sleep;
77    use wasmtime::component::Accessor;
78
79    impl<T> system_clock::Host for WasiCtxNamedView<'_, T>
80    where
81        T: WasiClocksNamedView,
82    {
83        fn now(&mut self, id: NamedId) -> wasmtime::Result<Instant> {
84            super::system_clock::Host::now(&mut self.0.clocks(id))
85        }
86
87        fn get_resolution(&mut self, id: NamedId) -> wasmtime::Result<types::Duration> {
88            super::system_clock::Host::get_resolution(&mut self.0.clocks(id))
89        }
90    }
91
92    impl<T, U> monotonic_clock::HostWithStore<U> for WasiClocksNamed<T>
93    where
94        T: WasiClocksNamedView,
95    {
96        async fn wait_until(
97            store: &Accessor<U, Self>,
98            id: NamedId,
99            when: Mark,
100        ) -> wasmtime::Result<()> {
101            if let Some(dur) =
102                store.with(|mut view| view.get().0.clocks(id).monotonic_wait_until_duration(when))
103            {
104                sleep(dur).await;
105            }
106            Ok(())
107        }
108
109        async fn wait_for(
110            _store: &Accessor<U, Self>,
111            _id: NamedId,
112            duration: types::Duration,
113        ) -> wasmtime::Result<()> {
114            if duration > 0 {
115                sleep(Duration::from_nanos(duration)).await;
116            }
117            Ok(())
118        }
119    }
120
121    impl<T> monotonic_clock::Host for WasiCtxNamedView<'_, T>
122    where
123        T: WasiClocksNamedView,
124    {
125        fn now(&mut self, id: NamedId) -> wasmtime::Result<Mark> {
126            super::monotonic_clock::Host::now(&mut self.0.clocks(id))
127        }
128
129        fn get_resolution(&mut self, id: NamedId) -> wasmtime::Result<types::Duration> {
130            super::monotonic_clock::Host::get_resolution(&mut self.0.clocks(id))
131        }
132    }
133}