Skip to content

Commit 1276ee3

Browse files
committed
name the timer wait() future explicitly, now thats how task::sleep, sleep_until work
1 parent 419466c commit 1276ee3

File tree

7 files changed

+39
-100
lines changed

7 files changed

+39
-100
lines changed

src/runtime/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ mod block_on;
1414
mod reactor;
1515

1616
pub use block_on::block_on;
17-
pub use reactor::{AsyncPollable, Reactor};
17+
pub use reactor::{AsyncPollable, Reactor, WaitFor};
1818
use std::cell::RefCell;
1919

2020
// There are no threads in WASI 0.2, so this is just a safe way to thread a single reactor to all

src/task/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@
33
mod sleep;
44
mod sleep_until;
55

6-
pub use sleep::{sleep, Sleep};
7-
pub use sleep_until::{sleep_until, SleepUntil};
6+
pub use sleep::sleep;
7+
pub use sleep_until::sleep_until;

src/task/sleep.rs

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,8 @@
1-
use std::future::Future;
2-
use std::pin::Pin;
3-
use std::task::{Context, Poll};
4-
5-
use crate::time::Timer as AsyncTimer;
6-
use pin_project_lite::pin_project;
7-
8-
use crate::time::{Duration, Instant};
1+
use crate::time::{Duration, Timer, Wait};
92

103
/// Sleeps for the specified amount of time.
114
///
125
/// This future can be `push_deadline` to be moved
13-
pub fn sleep(dur: Duration) -> Sleep {
14-
Sleep {
15-
dur,
16-
timer: AsyncTimer::after(dur.into()),
17-
completed: false,
18-
}
19-
}
20-
21-
pin_project! {
22-
/// Sleeps for the specified amount of time.
23-
#[must_use = "futures do nothing unless polled or .awaited"]
24-
pub struct Sleep {
25-
#[pin]
26-
timer: AsyncTimer,
27-
completed: bool,
28-
dur: Duration,
29-
}
30-
}
31-
32-
impl Future for Sleep {
33-
type Output = Instant;
34-
35-
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
36-
assert!(!self.completed, "future polled after completing");
37-
let this = self.project();
38-
match this.timer.poll(cx) {
39-
Poll::Ready(instant) => {
40-
*this.completed = true;
41-
Poll::Ready(instant.into())
42-
}
43-
Poll::Pending => Poll::Pending,
44-
}
45-
}
6+
pub fn sleep(dur: Duration) -> Wait {
7+
Timer::after(dur).wait()
468
}

src/task/sleep_until.rs

Lines changed: 3 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,6 @@
1-
use std::future::Future;
2-
use std::pin::Pin;
3-
use std::task::{Context, Poll};
4-
5-
use crate::time::{Instant, Timer};
6-
use pin_project_lite::pin_project;
1+
use crate::time::{Instant, Timer, Wait};
72

83
/// Sleeps until the specified instant.
9-
pub fn sleep_until(deadline: Instant) -> SleepUntil {
10-
SleepUntil {
11-
timer: Timer::at(deadline.into()),
12-
completed: false,
13-
}
14-
}
15-
16-
pin_project! {
17-
/// Sleeps until the specified instant.
18-
#[must_use = "futures do nothing unless polled or .awaited"]
19-
pub struct SleepUntil {
20-
#[pin]
21-
timer: Timer,
22-
completed: bool,
23-
}
24-
}
25-
26-
impl Future for SleepUntil {
27-
type Output = Instant;
28-
29-
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
30-
assert!(!self.completed, "future polled after completing");
31-
let this = self.project();
32-
match this.timer.poll(cx) {
33-
Poll::Ready(instant) => {
34-
*this.completed = true;
35-
Poll::Ready(instant.into())
36-
}
37-
Poll::Pending => Poll::Pending,
38-
}
39-
}
4+
pub fn sleep_until(deadline: Instant) -> Wait {
5+
Timer::at(deadline).wait()
406
}

src/time/duration.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use super::Instant;
2-
use crate::task::Sleep;
1+
use super::{Instant, Wait};
32
use std::future::IntoFuture;
43
use std::ops::{Add, AddAssign, Sub, SubAssign};
54
use wasi::clocks::monotonic_clock;
@@ -135,7 +134,7 @@ impl SubAssign<Duration> for Duration {
135134
impl IntoFuture for Duration {
136135
type Output = Instant;
137136

138-
type IntoFuture = Sleep;
137+
type IntoFuture = Wait;
139138

140139
fn into_future(self) -> Self::IntoFuture {
141140
crate::task::sleep(self)

src/time/instant.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
use super::Duration;
2-
use crate::task::SleepUntil;
1+
use super::{Duration, Wait};
32
use std::future::IntoFuture;
43
use std::ops::{Add, AddAssign, Sub, SubAssign};
54
use wasi::clocks::monotonic_clock;
@@ -85,7 +84,7 @@ impl std::ops::DerefMut for Instant {
8584
impl IntoFuture for Instant {
8685
type Output = Instant;
8786

88-
type IntoFuture = SleepUntil;
87+
type IntoFuture = Wait;
8988

9089
fn into_future(self) -> Self::IntoFuture {
9190
crate::task::sleep_until(self)

src/time/mod.rs

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mod instant;
77
pub use duration::Duration;
88
pub use instant::Instant;
99

10+
use pin_project_lite::pin_project;
1011
use std::future::Future;
1112
use std::pin::Pin;
1213
use std::task::{Context, Poll};
@@ -48,7 +49,7 @@ impl AsyncIterator for Interval {
4849
type Item = Instant;
4950

5051
async fn next(&mut self) -> Option<Self::Item> {
51-
Some(Timer::after(self.duration).await)
52+
Some(Timer::after(self.duration).wait().await)
5253
}
5354
}
5455

@@ -70,21 +71,33 @@ impl Timer {
7071
pub fn set_after(&mut self, duration: Duration) {
7172
*self = Self::after(duration);
7273
}
73-
pub async fn wait(&self) -> Instant {
74-
match &self.0 {
75-
Some(pollable) => pollable.wait_for().await,
76-
None => std::future::pending().await,
77-
}
78-
Instant::now()
74+
pub fn wait(&self) -> Wait {
75+
let wait_for = self.0.as_ref().map(|pollable| pollable.wait_for());
76+
Wait { wait_for }
77+
}
78+
}
79+
80+
pin_project! {
81+
/// Future created by [`Timer::wait`]
82+
#[must_use = "futures do nothing unless polled or .awaited"]
83+
pub struct Wait {
84+
#[pin]
85+
wait_for: Option<crate::runtime::WaitFor>
7986
}
8087
}
8188

82-
impl Future for Timer {
89+
impl Future for Wait {
8390
type Output = Instant;
91+
8492
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
85-
let this = self.as_ref();
86-
let pinned = std::pin::pin!(this.wait());
87-
pinned.poll(cx)
93+
let this = self.project();
94+
match this.wait_for.as_pin_mut() {
95+
None => Poll::Pending,
96+
Some(f) => match f.poll(cx) {
97+
Poll::Pending => Poll::Pending,
98+
Poll::Ready(()) => Poll::Ready(Instant::now()),
99+
},
100+
}
88101
}
89102
}
90103

@@ -103,14 +116,14 @@ mod test {
103116
#[test]
104117
fn timer_now() {
105118
crate::runtime::block_on(debug_duration("timer_now", async {
106-
Timer::at(Instant::now()).await
119+
Timer::at(Instant::now()).wait().await
107120
}));
108121
}
109122

110123
#[test]
111124
fn timer_after_100_milliseconds() {
112125
crate::runtime::block_on(debug_duration("timer_after_100_milliseconds", async {
113-
Timer::after(Duration::from_millis(100)).await
126+
Timer::after(Duration::from_millis(100)).wait().await
114127
}));
115128
}
116129
}

0 commit comments

Comments
 (0)