summaryrefslogtreecommitdiff
path: root/lib/timers.js
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2010-10-26 12:52:31 -0700
committerRyan Dahl <ry@tinyclouds.org>2010-10-26 14:53:18 -0700
commitbc47353bbe1836e4415cb08f1b6619839bff4d82 (patch)
tree6751b394baee67bb14127b680aef14bfd83658bf /lib/timers.js
parent79944006e252170933e35862bdff2f7fba6bd762 (diff)
downloadnodejs-bc47353bbe1836e4415cb08f1b6619839bff4d82.tar.gz
nodejs-bc47353bbe1836e4415cb08f1b6619839bff4d82.tar.bz2
nodejs-bc47353bbe1836e4415cb08f1b6619839bff4d82.zip
Use the timer list for setTimeout
Diffstat (limited to 'lib/timers.js')
-rw-r--r--lib/timers.js91
1 files changed, 66 insertions, 25 deletions
diff --git a/lib/timers.js b/lib/timers.js
index 6a8249700..b835ba586 100644
--- a/lib/timers.js
+++ b/lib/timers.js
@@ -1,7 +1,7 @@
var Timer = process.binding('timer').Timer;
var assert = process.assert;
-/*
+/*
* To enable debug statements for the timers do NODE_DEBUG=8 ./node script.js
*/
var debugLevel = parseInt(process.env.NODE_DEBUG, 16);
@@ -48,9 +48,8 @@ function remove (item) {
// remove a item from its list and place at the end.
function append (list, item) {
- remove(item);
item._idleNext = list._idleNext;
- item._idleNext._idlePrev = item;
+ list._idleNext._idlePrev = item;
item._idlePrev = list;
list._idleNext = item;
}
@@ -62,7 +61,7 @@ function insert (item, msecs) {
item._idleStart = new Date();
item._idleTimeout = msecs;
- if (!msecs) return;
+ if (msecs < 0) return;
var list;
@@ -90,23 +89,23 @@ function insert (item, msecs) {
return;
} else {
remove(first);
- assert(first != peek(list));
+ assert(first !== peek(list));
if (first._onTimeout) first._onTimeout();
}
}
debug(msecs + ' list empty');
- assert(list._idleNext == list); // list is empty
+ assert(list._idleNext === list); // list is empty
list.stop();
};
}
- if (list._idleNext == list) {
+ if (list._idleNext === list) {
// if empty (re)start the timer
list.again(msecs);
}
append(list, item);
- assert(list._idleNext != list); // list is not empty
+ assert(list._idleNext !== list); // list is not empty
}
@@ -141,7 +140,7 @@ exports.enroll = function (item, msecs) {
// it will reset its timeout.
exports.active = function (item) {
var msecs = item._idleTimeout;
- if (msecs) {
+ if (msecs >= 0) {
var list = lists[msecs];
if (item._idleNext == item) {
insert(item, msecs);
@@ -159,41 +158,83 @@ exports.active = function (item) {
};
+/*
+ * DOM-style timers
+ */
+exports.setTimeout = function (callback, after) {
+ var timer;
-// Timers
-function addTimerListener (callback) {
- var timer = this;
- // Special case the no param case to avoid the extra object creation.
+ if (after <= 0) {
+ // Use the slow case for after == 0
+ timer = new Timer();
+ timer.callback = callback;
+ } else {
+ timer = { _idleTimeout: after, _onTimeout: callback };
+ timer._idlePrev = timer;
+ timer._idleNext = timer;
+ }
+
+ /*
+ * Sometimes setTimeout is called with arguments, EG
+ *
+ * setTimeout(callback, 2000, "hello", "world")
+ *
+ * If that's the case we need to call the callback with
+ * those args. The overhead of an extra closure is not
+ * desired in the normal case.
+ */
if (arguments.length > 2) {
var args = Array.prototype.slice.call(arguments, 2);
- timer.callback = function () { callback.apply(timer, args); };
- } else {
- timer.callback = callback;
+ var c = function () {
+ callback.apply(timer, args);
+ };
+
+ if (timer instanceof Timer) {
+ timer.callback = c;
+ } else {
+ timer._onTimeout = c;
+ }
}
-}
+ if (timer instanceof Timer) {
+ timer.start(0, 0);
+ } else {
+ exports.active(timer);
+ }
-exports.setTimeout = function (callback, after) {
- var timer = new Timer();
- addTimerListener.apply(timer, arguments);
- timer.start(after, 0);
return timer;
};
+
+exports.clearTimeout = function (timer) {
+ timer.callback = timer._onTimeout = null;
+ exports.unenroll(timer);
+ if (timer instanceof Timer) timer.stop(); // for after === 0
+};
+
+
exports.setInterval = function (callback, repeat) {
var timer = new Timer();
- addTimerListener.apply(timer, arguments);
+
+ if (arguments.length > 2) {
+ var args = Array.prototype.slice.call(arguments, 2);
+ timer.callback = function () {
+ callback.apply(timer, args);
+ };
+ } else {
+ timer.callback = callback;
+ }
+
timer.start(repeat, repeat ? repeat : 1);
return timer;
};
-exports.clearTimeout = function (timer) {
+
+exports.clearInterval = function (timer) {
if (timer instanceof Timer) {
timer.callback = null;
timer.stop();
}
};
-
-exports.clearInterval = exports.clearTimeout;