wasmtime_wasi/p3/clocks/
host.rs1use 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}