Skip to content

Commit a9aabe5

Browse files
committed
Move actual Timer implementation to other file
This commit moves the native Timer implementation into another file. The goal is to setup the ability to toggle between web-based and IO-based Timer implementations. Signed-off-by: John Nunley <[email protected]>
1 parent a96d4be commit a9aabe5

File tree

2 files changed

+220
-127
lines changed

2 files changed

+220
-127
lines changed

src/lib.rs

+28-127
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@
6363

6464
use std::future::Future;
6565
use std::pin::Pin;
66-
use std::task::{Context, Poll, Waker};
66+
use std::task::{Context, Poll};
6767
use std::time::{Duration, Instant};
6868

6969
use futures_lite::stream::Stream;
@@ -74,6 +74,9 @@ mod driver;
7474
mod io;
7575
mod reactor;
7676

77+
#[path = "timer/native.rs"]
78+
mod timer;
79+
7780
pub mod os;
7881

7982
pub use driver::block_on;
@@ -123,22 +126,7 @@ pub use reactor::{Readable, ReadableOwned, Writable, WritableOwned};
123126
/// # std::io::Result::Ok(()) });
124127
/// ```
125128
#[derive(Debug)]
126-
pub struct Timer {
127-
/// This timer's ID and last waker that polled it.
128-
///
129-
/// When this field is set to `None`, this timer is not registered in the reactor.
130-
id_and_waker: Option<(usize, Waker)>,
131-
132-
/// The next instant at which this timer fires.
133-
///
134-
/// If this timer is a blank timer, this value is None. If the timer
135-
/// must be set, this value contains the next instant at which the
136-
/// timer must fire.
137-
when: Option<Instant>,
138-
139-
/// The period.
140-
period: Duration,
141-
}
129+
pub struct Timer(timer::Timer);
142130

143131
impl Timer {
144132
/// Creates a timer that will never fire.
@@ -173,12 +161,9 @@ impl Timer {
173161
/// run_with_timeout(None).await;
174162
/// # });
175163
/// ```
164+
#[inline]
176165
pub fn never() -> Timer {
177-
Timer {
178-
id_and_waker: None,
179-
when: None,
180-
period: Duration::MAX,
181-
}
166+
Timer(timer::Timer::never())
182167
}
183168

184169
/// Creates a timer that emits an event once after the given duration of time.
@@ -193,10 +178,9 @@ impl Timer {
193178
/// Timer::after(Duration::from_secs(1)).await;
194179
/// # });
195180
/// ```
181+
#[inline]
196182
pub fn after(duration: Duration) -> Timer {
197-
Instant::now()
198-
.checked_add(duration)
199-
.map_or_else(Timer::never, Timer::at)
183+
Timer(timer::Timer::after(duration))
200184
}
201185

202186
/// Creates a timer that emits an event once at the given time instant.
@@ -213,8 +197,9 @@ impl Timer {
213197
/// Timer::at(when).await;
214198
/// # });
215199
/// ```
200+
#[inline]
216201
pub fn at(instant: Instant) -> Timer {
217-
Timer::interval_at(instant, Duration::MAX)
202+
Timer(timer::Timer::at(instant))
218203
}
219204

220205
/// Creates a timer that emits events periodically.
@@ -231,10 +216,9 @@ impl Timer {
231216
/// Timer::interval(period).next().await;
232217
/// # });
233218
/// ```
219+
#[inline]
234220
pub fn interval(period: Duration) -> Timer {
235-
Instant::now()
236-
.checked_add(period)
237-
.map_or_else(Timer::never, |at| Timer::interval_at(at, period))
221+
Timer(timer::Timer::interval(period))
238222
}
239223

240224
/// Creates a timer that emits events periodically, starting at `start`.
@@ -252,12 +236,9 @@ impl Timer {
252236
/// Timer::interval_at(start, period).next().await;
253237
/// # });
254238
/// ```
239+
#[inline]
255240
pub fn interval_at(start: Instant, period: Duration) -> Timer {
256-
Timer {
257-
id_and_waker: None,
258-
when: Some(start),
259-
period,
260-
}
241+
Timer(timer::Timer::interval_at(start, period))
261242
}
262243

263244
/// Indicates whether or not this timer will ever fire.
@@ -299,7 +280,7 @@ impl Timer {
299280
/// ```
300281
#[inline]
301282
pub fn will_fire(&self) -> bool {
302-
self.when.is_some()
283+
self.0.will_fire()
303284
}
304285

305286
/// Sets the timer to emit an en event once after the given duration of time.
@@ -319,15 +300,9 @@ impl Timer {
319300
/// t.set_after(Duration::from_millis(100));
320301
/// # });
321302
/// ```
303+
#[inline]
322304
pub fn set_after(&mut self, duration: Duration) {
323-
match Instant::now().checked_add(duration) {
324-
Some(instant) => self.set_at(instant),
325-
None => {
326-
// Overflow to never going off.
327-
self.clear();
328-
self.when = None;
329-
}
330-
}
305+
self.0.set_after(duration)
331306
}
332307

333308
/// Sets the timer to emit an event once at the given time instant.
@@ -350,16 +325,9 @@ impl Timer {
350325
/// t.set_at(when);
351326
/// # });
352327
/// ```
328+
#[inline]
353329
pub fn set_at(&mut self, instant: Instant) {
354-
self.clear();
355-
356-
// Update the timeout.
357-
self.when = Some(instant);
358-
359-
if let Some((id, waker)) = self.id_and_waker.as_mut() {
360-
// Re-register the timer with the new timeout.
361-
*id = Reactor::get().insert_timer(instant, waker);
362-
}
330+
self.0.set_at(instant)
363331
}
364332

365333
/// Sets the timer to emit events periodically.
@@ -382,15 +350,9 @@ impl Timer {
382350
/// t.set_interval(period);
383351
/// # });
384352
/// ```
353+
#[inline]
385354
pub fn set_interval(&mut self, period: Duration) {
386-
match Instant::now().checked_add(period) {
387-
Some(instant) => self.set_interval_at(instant, period),
388-
None => {
389-
// Overflow to never going off.
390-
self.clear();
391-
self.when = None;
392-
}
393-
}
355+
self.0.set_interval(period)
394356
}
395357

396358
/// Sets the timer to emit events periodically, starting at `start`.
@@ -414,39 +376,16 @@ impl Timer {
414376
/// t.set_interval_at(start, period);
415377
/// # });
416378
/// ```
379+
#[inline]
417380
pub fn set_interval_at(&mut self, start: Instant, period: Duration) {
418-
self.clear();
419-
420-
self.when = Some(start);
421-
self.period = period;
422-
423-
if let Some((id, waker)) = self.id_and_waker.as_mut() {
424-
// Re-register the timer with the new timeout.
425-
*id = Reactor::get().insert_timer(start, waker);
426-
}
427-
}
428-
429-
/// Helper function to clear the current timer.
430-
fn clear(&mut self) {
431-
if let (Some(when), Some((id, _))) = (self.when, self.id_and_waker.as_ref()) {
432-
// Deregister the timer from the reactor.
433-
Reactor::get().remove_timer(when, *id);
434-
}
435-
}
436-
}
437-
438-
impl Drop for Timer {
439-
fn drop(&mut self) {
440-
if let (Some(when), Some((id, _))) = (self.when, self.id_and_waker.take()) {
441-
// Deregister the timer from the reactor.
442-
Reactor::get().remove_timer(when, id);
443-
}
381+
self.0.set_interval_at(start, period)
444382
}
445383
}
446384

447385
impl Future for Timer {
448386
type Output = Instant;
449387

388+
#[inline]
450389
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
451390
match self.poll_next(cx) {
452391
Poll::Ready(Some(when)) => Poll::Ready(when),
@@ -459,46 +398,8 @@ impl Future for Timer {
459398
impl Stream for Timer {
460399
type Item = Instant;
461400

462-
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
463-
let this = self.get_mut();
464-
465-
if let Some(ref mut when) = this.when {
466-
// Check if the timer has already fired.
467-
if Instant::now() >= *when {
468-
if let Some((id, _)) = this.id_and_waker.take() {
469-
// Deregister the timer from the reactor.
470-
Reactor::get().remove_timer(*when, id);
471-
}
472-
let result_time = *when;
473-
if let Some(next) = (*when).checked_add(this.period) {
474-
*when = next;
475-
// Register the timer in the reactor.
476-
let id = Reactor::get().insert_timer(next, cx.waker());
477-
this.id_and_waker = Some((id, cx.waker().clone()));
478-
} else {
479-
this.when = None;
480-
}
481-
return Poll::Ready(Some(result_time));
482-
} else {
483-
match &this.id_and_waker {
484-
None => {
485-
// Register the timer in the reactor.
486-
let id = Reactor::get().insert_timer(*when, cx.waker());
487-
this.id_and_waker = Some((id, cx.waker().clone()));
488-
}
489-
Some((id, w)) if !w.will_wake(cx.waker()) => {
490-
// Deregister the timer from the reactor to remove the old waker.
491-
Reactor::get().remove_timer(*when, *id);
492-
493-
// Register the timer in the reactor with the new waker.
494-
let id = Reactor::get().insert_timer(*when, cx.waker());
495-
this.id_and_waker = Some((id, cx.waker().clone()));
496-
}
497-
Some(_) => {}
498-
}
499-
}
500-
}
501-
502-
Poll::Pending
401+
#[inline]
402+
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
403+
self.0.poll_next(cx)
503404
}
504405
}

0 commit comments

Comments
 (0)