aboutsummaryrefslogtreecommitdiff
path: root/embassy-time/src/timer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-time/src/timer.rs')
-rw-r--r--embassy-time/src/timer.rs38
1 files changed, 18 insertions, 20 deletions
diff --git a/embassy-time/src/timer.rs b/embassy-time/src/timer.rs
index fe0e93951..763bfdeeb 100644
--- a/embassy-time/src/timer.rs
+++ b/embassy-time/src/timer.rs
@@ -1,6 +1,6 @@
1use core::future::{poll_fn, Future}; 1use core::future::{poll_fn, Future};
2use core::pin::Pin; 2use core::pin::Pin;
3use core::task::{Context, Poll, Waker}; 3use core::task::{Context, Poll};
4 4
5use futures_util::future::{select, Either}; 5use futures_util::future::{select, Either};
6use futures_util::stream::FusedStream; 6use futures_util::stream::FusedStream;
@@ -8,7 +8,7 @@ use futures_util::{pin_mut, Stream};
8 8
9use crate::{Duration, Instant}; 9use crate::{Duration, Instant};
10 10
11/// Error returned by [`with_timeout`] on timeout. 11/// Error returned by [`with_timeout`] and [`with_deadline`] on timeout.
12#[derive(Debug, Clone, PartialEq, Eq)] 12#[derive(Debug, Clone, PartialEq, Eq)]
13#[cfg_attr(feature = "defmt", derive(defmt::Format))] 13#[cfg_attr(feature = "defmt", derive(defmt::Format))]
14pub struct TimeoutError; 14pub struct TimeoutError;
@@ -26,6 +26,19 @@ pub async fn with_timeout<F: Future>(timeout: Duration, fut: F) -> Result<F::Out
26 } 26 }
27} 27}
28 28
29/// Runs a given future with a deadline time.
30///
31/// If the future completes before the deadline, its output is returned. Otherwise, on timeout,
32/// work on the future is stopped (`poll` is no longer called), the future is dropped and `Err(TimeoutError)` is returned.
33pub async fn with_deadline<F: Future>(at: Instant, fut: F) -> Result<F::Output, TimeoutError> {
34 let timeout_fut = Timer::at(at);
35 pin_mut!(fut);
36 match select(fut, timeout_fut).await {
37 Either::Left((r, _)) => Ok(r),
38 Either::Right(_) => Err(TimeoutError),
39 }
40}
41
29/// A future that completes at a specified [Instant](struct.Instant.html). 42/// A future that completes at a specified [Instant](struct.Instant.html).
30#[must_use = "futures do nothing unless you `.await` or poll them"] 43#[must_use = "futures do nothing unless you `.await` or poll them"]
31pub struct Timer { 44pub struct Timer {
@@ -47,9 +60,6 @@ impl Timer {
47 /// 60 ///
48 /// Example: 61 /// Example:
49 /// ``` no_run 62 /// ``` no_run
50 /// # #![feature(type_alias_impl_trait)]
51 /// #
52 /// # fn foo() {}
53 /// use embassy_time::{Duration, Timer}; 63 /// use embassy_time::{Duration, Timer};
54 /// 64 ///
55 /// #[embassy_executor::task] 65 /// #[embassy_executor::task]
@@ -119,7 +129,7 @@ impl Future for Timer {
119 if self.yielded_once && self.expires_at <= Instant::now() { 129 if self.yielded_once && self.expires_at <= Instant::now() {
120 Poll::Ready(()) 130 Poll::Ready(())
121 } else { 131 } else {
122 schedule_wake(self.expires_at, cx.waker()); 132 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
123 self.yielded_once = true; 133 self.yielded_once = true;
124 Poll::Pending 134 Poll::Pending
125 } 135 }
@@ -132,8 +142,6 @@ impl Future for Timer {
132/// 142///
133/// For instance, consider the following code fragment. 143/// For instance, consider the following code fragment.
134/// ``` no_run 144/// ``` no_run
135/// # #![feature(type_alias_impl_trait)]
136/// #
137/// use embassy_time::{Duration, Timer}; 145/// use embassy_time::{Duration, Timer};
138/// # fn foo() {} 146/// # fn foo() {}
139/// 147///
@@ -152,8 +160,6 @@ impl Future for Timer {
152/// Example using ticker, which will consistently call `foo` once a second. 160/// Example using ticker, which will consistently call `foo` once a second.
153/// 161///
154/// ``` no_run 162/// ``` no_run
155/// # #![feature(type_alias_impl_trait)]
156/// #
157/// use embassy_time::{Duration, Ticker}; 163/// use embassy_time::{Duration, Ticker};
158/// # fn foo(){} 164/// # fn foo(){}
159/// 165///
@@ -204,7 +210,7 @@ impl Ticker {
204 self.expires_at += dur; 210 self.expires_at += dur;
205 Poll::Ready(()) 211 Poll::Ready(())
206 } else { 212 } else {
207 schedule_wake(self.expires_at, cx.waker()); 213 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
208 Poll::Pending 214 Poll::Pending
209 } 215 }
210 }) 216 })
@@ -221,7 +227,7 @@ impl Stream for Ticker {
221 self.expires_at += dur; 227 self.expires_at += dur;
222 Poll::Ready(Some(())) 228 Poll::Ready(Some(()))
223 } else { 229 } else {
224 schedule_wake(self.expires_at, cx.waker()); 230 embassy_time_queue_driver::schedule_wake(self.expires_at.as_ticks(), cx.waker());
225 Poll::Pending 231 Poll::Pending
226 } 232 }
227 } 233 }
@@ -233,11 +239,3 @@ impl FusedStream for Ticker {
233 false 239 false
234 } 240 }
235} 241}
236
237extern "Rust" {
238 fn _embassy_time_schedule_wake(at: Instant, waker: &Waker);
239}
240
241fn schedule_wake(at: Instant, waker: &Waker) {
242 unsafe { _embassy_time_schedule_wake(at, waker) }
243}