1use super::*;
4
5use core::pin::Pin;
6use derive_more::{Display, Error};
7use std::future::Future;
8use std::task::{Context, Poll};
9use std::time::Duration;
10
11use crate::ResourceId;
12
13pub struct Sleep {
15 id: ResourceId,
16}
17
18pub fn sleep(duration: Duration) -> Sleep {
26 let id = ocall::create_timer(duration.as_millis() as i32).expect("failed to create timer");
27 Sleep { id: ResourceId(id) }
28}
29
30impl Future for Sleep {
31 type Output = ();
32
33 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
34 use env::OcallError;
35 let waker_id = env::tasks::intern_waker(cx.waker().clone());
36 let rv = ocall::poll_read(waker_id, self.id.0, &mut []);
37 match rv {
38 Ok(_) => Poll::Ready(()),
39 Err(OcallError::Pending) => Poll::Pending,
40 Err(err) => panic!("unexpected error: {:?}", err),
41 }
42 }
43}
44
45#[derive(Display, Error, Debug)]
47pub struct TimedOut;
48
49pub async fn timeout<T: Future<Output = O>, O>(
51 duration: Duration,
52 future: T,
53) -> Result<O, TimedOut> {
54 use futures::FutureExt;
55 futures::select! {
56 v = future.fuse() => Ok(v),
57 _ = sleep(duration).fuse() => Err(TimedOut),
58 }
59}
60
61pub struct Rest {
63 resting: bool,
64}
65
66impl Rest {
67 pub fn new(resting: bool) -> Self {
69 Rest { resting }
70 }
71}
72
73impl Future for Rest {
74 type Output = ();
75 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
76 if self.resting {
77 self.resting = false;
79 cx.waker().wake_by_ref();
80 Poll::Pending
81 } else {
82 Poll::Ready(())
83 }
84 }
85}
86
87pub fn maybe_rest() -> Rest {
93 let remaining = ocall::gas_remaining().expect("failed to get gas remaining");
94 Rest::new(remaining < 30)
96}