Skip to content

Commit 799ed3b

Browse files
authored
Merge pull request #51 from expenses/wasm-support
Support for `wasm32-unknown-unknown`
2 parents 4586461 + 9f620d7 commit 799ed3b

File tree

10 files changed

+98
-33
lines changed

10 files changed

+98
-33
lines changed

.idea/.gitignore

+2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/futures-timer.iml

+14
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/misc.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/modules.xml

+8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/vcs.xml

+6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+8
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,15 @@ Timeouts for futures.
1313
"""
1414

1515
[dependencies]
16+
gloo-timers = { version = "0.2.0", features = ["futures"], optional = true }
17+
send_wrapper = { version = "0.4.0", optional = true }
1618

1719
[dev-dependencies]
1820
async-std = { version = "1.0.1", features = ["attributes"] }
1921
futures = "0.3.1"
22+
23+
[features]
24+
wasm-bindgen = [
25+
"gloo-timers",
26+
"send_wrapper"
27+
]

src/delay.rs

+8-27
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ use crate::{ScheduledTimer, TimerHandle};
2525
/// at.
2626
pub struct Delay {
2727
state: Option<Arc<Node<ScheduledTimer>>>,
28-
when: Instant,
2928
}
3029

3130
impl Delay {
@@ -38,25 +37,14 @@ impl Delay {
3837
Delay::new_handle(Instant::now() + dur, Default::default())
3938
}
4039

41-
/// Return the `Instant` when this delay will fire.
42-
#[inline]
43-
pub fn when(&self) -> Instant {
44-
self.when
45-
}
46-
4740
/// Creates a new future which will fire at the time specified by `at`.
4841
///
4942
/// The returned instance of `Delay` will be bound to the timer specified by
5043
/// the `handle` argument.
5144
pub(crate) fn new_handle(at: Instant, handle: TimerHandle) -> Delay {
5245
let inner = match handle.inner.upgrade() {
5346
Some(i) => i,
54-
None => {
55-
return Delay {
56-
state: None,
57-
when: at,
58-
}
59-
}
47+
None => return Delay { state: None },
6048
};
6149
let state = Arc::new(Node::new(ScheduledTimer {
6250
at: Mutex::new(Some(at)),
@@ -70,30 +58,23 @@ impl Delay {
7058
// timer, meaning that we'll want to immediately return an error from
7159
// `poll`.
7260
if inner.list.push(&state).is_err() {
73-
return Delay {
74-
state: None,
75-
when: at,
76-
};
61+
return Delay { state: None };
7762
}
7863

7964
inner.waker.wake();
80-
Delay {
81-
state: Some(state),
82-
when: at,
83-
}
65+
Delay { state: Some(state) }
8466
}
8567

8668
/// Resets this timeout to an new timeout which will fire at the time
8769
/// specified by `at`.
8870
#[inline]
89-
pub fn reset(&mut self, at: Instant) {
90-
self.when = at;
91-
if self._reset(self.when).is_err() {
71+
pub fn reset(&mut self, dur: Duration) {
72+
if self._reset(dur).is_err() {
9273
self.state = None
9374
}
9475
}
9576

96-
fn _reset(&mut self, at: Instant) -> Result<(), ()> {
77+
fn _reset(&mut self, dur: Duration) -> Result<(), ()> {
9778
let state = match self.state {
9879
Some(ref state) => state,
9980
None => return Err(()),
@@ -111,7 +92,7 @@ impl Delay {
11192
Err(s) => bits = s,
11293
}
11394
}
114-
*state.at.lock().unwrap() = Some(at);
95+
*state.at.lock().unwrap() = Some(Instant::now() + dur);
11596
// If we fail to push our node then we've become an inert timer, so
11697
// we'll want to clear our `state` field accordingly
11798
timeouts.list.push(state)?;
@@ -165,6 +146,6 @@ impl Drop for Delay {
165146

166147
impl fmt::Debug for Delay {
167148
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
168-
f.debug_struct("Delay").field("when", &self.when).finish()
149+
f.debug_struct("Delay").finish()
169150
}
170151
}

src/delay_wasm.rs

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
//! A version of `Delay` that works on wasm.
2+
3+
use gloo_timers::future::TimeoutFuture;
4+
use send_wrapper::SendWrapper;
5+
use std::{
6+
future::Future,
7+
pin::Pin,
8+
task::{Context, Poll},
9+
time::Duration,
10+
};
11+
12+
/// A version of `Delay` that works on wasm.
13+
#[derive(Debug)]
14+
pub struct Delay(SendWrapper<TimeoutFuture>);
15+
16+
impl Delay {
17+
/// Creates a new future which will fire at `dur` time into the future.
18+
#[inline]
19+
pub fn new(dur: Duration) -> Delay {
20+
Self(SendWrapper::new(TimeoutFuture::new(dur.as_millis() as u32)))
21+
}
22+
23+
/// Resets the timeout.
24+
#[inline]
25+
pub fn reset(&mut self, dur: Duration) {
26+
*self = Delay::new(at);
27+
}
28+
}
29+
30+
impl Future for Delay {
31+
type Output = ();
32+
33+
fn poll(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
34+
Pin::new(&mut *Pin::into_inner(self).0).poll(cx)
35+
}
36+
}

src/lib.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,24 @@
22
//!
33
//! # Examples
44
//!
5-
//! ```no_run
6-
//! # #[async_std::main]
7-
//! # async fn main() {
5+
//! ```
86
//! use std::time::Duration;
97
//! use futures_timer::Delay;
8+
//! use futures::executor::block_on;
109
//!
11-
//! let now = Delay::new(Duration::from_secs(3)).await;
10+
//! let now = block_on(Delay::new(Duration::from_secs(3)));
1211
//! println!("waited for 3 secs");
13-
//! # }
1412
//! ```
1513
1614
#![deny(missing_docs)]
1715
#![warn(missing_debug_implementations)]
1816

1917
mod arc_list;
2018
mod atomic_waker;
19+
#[cfg(not(all(target_arch = "wasm32", feature = "wasm-bindgen")))]
2120
mod delay;
21+
#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
22+
mod delay_wasm;
2223
mod global;
2324
mod heap;
2425
mod heap_timer;
@@ -30,4 +31,7 @@ use heap::{Heap, Slot};
3031
use heap_timer::HeapTimer;
3132
use timer::{ScheduledTimer, Timer, TimerHandle};
3233

34+
#[cfg(not(all(target_arch = "wasm32", feature = "wasm-bindgen")))]
3335
pub use self::delay::Delay;
36+
#[cfg(all(target_arch = "wasm32", feature = "wasm-bindgen"))]
37+
pub use self::delay_wasm::Delay;

tests/smoke.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ async fn reset() -> Result<(), Box<dyn Error + Send + Sync + 'static>> {
2424
assert!(i.elapsed() > dur);
2525

2626
let i = Instant::now();
27-
d.reset(Instant::now() + dur);
27+
d.reset(dur);
2828
d.await;
2929
assert!(i.elapsed() > dur);
3030
Ok(())

0 commit comments

Comments
 (0)