summaryrefslogtreecommitdiff
path: root/src/global_timer.rs
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2019-03-10 15:37:05 -0400
committerRyan Dahl <ry@tinyclouds.org>2019-03-12 19:25:57 -0400
commit58cc69f672f91841984fc4e1e9bcfb1a75362677 (patch)
treea3e50ff11dfe8348c6574eeedcd2577e3690b440 /src/global_timer.rs
parent9691d7b53bea5a2656ec47e8437fac1f527b3cce (diff)
Make timers act like normal ops
This is in preperation for core integration.
Diffstat (limited to 'src/global_timer.rs')
-rw-r--r--src/global_timer.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/src/global_timer.rs b/src/global_timer.rs
new file mode 100644
index 000000000..eef70ddc2
--- /dev/null
+++ b/src/global_timer.rs
@@ -0,0 +1,49 @@
+// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
+
+//! This module helps deno implement timers.
+//!
+//! As an optimization, we want to avoid an expensive calls into rust for every
+//! setTimeout in JavaScript. Thus in //js/timers.ts a data structure is
+//! implemented that calls into Rust for only the smallest timeout. Thus we
+//! only need to be able to start and cancel a single timer (or Delay, as Tokio
+//! calls it) for an entire Isolate. This is what is implemented here.
+
+use crate::tokio_util::panic_on_error;
+use futures::Future;
+use std::time::Instant;
+use tokio::sync::oneshot;
+use tokio::timer::Delay;
+
+pub struct GlobalTimer {
+ tx: Option<oneshot::Sender<()>>,
+}
+
+impl GlobalTimer {
+ pub fn new() -> Self {
+ Self { tx: None }
+ }
+
+ pub fn cancel(&mut self) {
+ if let Some(tx) = self.tx.take() {
+ tx.send(()).ok();
+ }
+ }
+
+ pub fn new_timeout(
+ &mut self,
+ deadline: Instant,
+ ) -> impl Future<Item = (), Error = ()> {
+ if self.tx.is_some() {
+ self.cancel();
+ }
+ assert!(self.tx.is_none());
+
+ let (tx, rx) = oneshot::channel();
+ self.tx = Some(tx);
+
+ let delay = panic_on_error(Delay::new(deadline));
+ let rx = panic_on_error(rx);
+
+ delay.select(rx).then(|_| Ok(()))
+ }
+}