add ref/unref to setTimeout timers
authorTimothy J Fontaine <tjfontaine@gmail.com>
Fri, 13 Jul 2012 02:19:01 +0000 (22:19 -0400)
committerBert Belder <bertbelder@gmail.com>
Mon, 23 Jul 2012 16:31:30 +0000 (18:31 +0200)
lib/timers.js

index d969247..03db989 100644 (file)
@@ -47,7 +47,6 @@ if (process.env.NODE_DEBUG && /timer/.test(process.env.NODE_DEBUG)) {
 // value = list
 var lists = {};
 
-
 // the main function - creates lists on demand and the watchers associated
 // with them.
 function insert(item, msecs) {
@@ -151,6 +150,7 @@ exports.enroll = function(item, msecs) {
 exports.active = function(item) {
   var msecs = item._idleTimeout;
   if (msecs >= 0) {
+
     var list = lists[msecs];
     if (!list || L.isEmpty(list)) {
       insert(item, msecs);
@@ -176,9 +176,7 @@ exports.setTimeout = function(callback, after) {
     after = 1; // schedule on next tick, follows browser behaviour
   }
 
-  timer = { _idleTimeout: after };
-  timer._idlePrev = timer;
-  timer._idleNext = timer;
+  timer = new Timeout(after);
 
   if (arguments.length <= 2) {
     timer._onTimeout = callback;
@@ -209,7 +207,7 @@ exports.setTimeout = function(callback, after) {
 exports.clearTimeout = function(timer) {
   if (timer && (timer.ontimeout || timer._onTimeout)) {
     timer.ontimeout = timer._onTimeout = null;
-    if (timer instanceof Timer) {
+    if (timer instanceof Timer || timer instanceof Timeout) {
       timer.close(); // for after === 0
     } else {
       exports.unenroll(timer);
@@ -245,3 +243,37 @@ exports.clearInterval = function(timer) {
     timer.close();
   }
 };
+
+var Timeout = function(after) {
+  this._idleTimeout = after;
+  this._idlePrev = this;
+  this._idleNext = this;
+  this._when = Date.now() + after;
+};
+
+Timeout.prototype.unref = function() {
+  if (!this._handle) {
+    exports.unenroll(this);
+    this._handle = new Timer();
+    this._handle.ontimeout = this._onTimeout;
+    this._handle.start(this._when - Date.now(), 0);
+    this._handle.unref();
+  } else {
+    this._handle.unref();
+  }
+};
+
+Timeout.prototype.ref = function() {
+  if (this._handle)
+    this._handle.ref();
+};
+
+Timeout.prototype.close = function() {
+  this._onTimeout = null;
+  if (this._handle) {
+    this._handle.ontimeout = null;
+    this._handle.close();
+  } else {
+    exports.unenroll(this);
+  }
+};