diff options
author | Ben Noordhuis <info@bnoordhuis.nl> | 2011-07-12 00:30:24 +0200 |
---|---|---|
committer | isaacs <i@izs.me> | 2012-03-15 13:56:30 -0700 |
commit | 7fc835afe362ebd30a0dbec81d3360bd24525222 (patch) | |
tree | bc428f0058794fa7270ef22d7d4fe05b887354d8 /lib/timers.js | |
parent | 9a3565621011b66a27386cc5a4daca34502088c2 (diff) | |
download | nodejs-7fc835afe362ebd30a0dbec81d3360bd24525222.tar.gz nodejs-7fc835afe362ebd30a0dbec81d3360bd24525222.tar.bz2 nodejs-7fc835afe362ebd30a0dbec81d3360bd24525222.zip |
timers: handle negative or non-numeric timeout values
Follows browser behaviour by scheduling the callback on the next tick.
Fixes #593.
Diffstat (limited to 'lib/timers.js')
-rw-r--r-- | lib/timers.js | 64 |
1 files changed, 32 insertions, 32 deletions
diff --git a/lib/timers.js b/lib/timers.js index c5592bf0a..97e5830e6 100644 --- a/lib/timers.js +++ b/lib/timers.js @@ -23,6 +23,9 @@ var Timer = process.binding('timer_wrap').Timer; var L = require('_linklist'); var assert = require('assert').ok; +// Timeout values > TIMEOUT_MAX are set to 1. +var TIMEOUT_MAX = 2147483647; // 2^31-1 + var debug; if (process.env.NODE_DEBUG && /timer/.test(process.env.NODE_DEBUG)) { debug = function() { require('util').error.apply(this, arguments); }; @@ -162,43 +165,35 @@ exports.active = function(item) { exports.setTimeout = function(callback, after) { var timer; - if (after <= 0) { - // Use the slow case for after == 0 - timer = new Timer(); - timer._callback = callback; + after = ~~after; + if (after < 1 || after > TIMEOUT_MAX) { + after = 1; // schedule on next tick, follows browser behaviour + } - if (arguments.length <= 2) { - timer._onTimeout = function() { - this._callback(); - this.close(); - } - } else { - var args = Array.prototype.slice.call(arguments, 2); - timer._onTimeout = function() { - this._callback.apply(timer, args); - this.close(); - } - } + timer = { _idleTimeout: after }; + timer._idlePrev = timer; + timer._idleNext = timer; - timer.ontimeout = timer._onTimeout; - timer.start(0, 0); + if (arguments.length <= 2) { + timer._onTimeout = callback; } else { - timer = { _idleTimeout: after }; - timer._idlePrev = timer; - timer._idleNext = timer; - - if (arguments.length <= 2) { - timer._onTimeout = callback; - } else { - var args = Array.prototype.slice.call(arguments, 2); - timer._onTimeout = function() { - callback.apply(timer, args); - } + /* + * 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. + */ + var args = Array.prototype.slice.call(arguments, 2); + timer._onTimeout = function() { + callback.apply(timer, args); } - - exports.active(timer); } + exports.active(timer); + return timer; }; @@ -218,12 +213,17 @@ exports.clearTimeout = function(timer) { exports.setInterval = function(callback, repeat) { var timer = new Timer(); + repeat = ~~repeat; + if (repeat < 1 || repeat > TIMEOUT_MAX) { + repeat = 1; // schedule on next tick, follows browser behaviour + } + var args = Array.prototype.slice.call(arguments, 2); timer.ontimeout = function() { callback.apply(timer, args); } - timer.start(repeat, repeat ? repeat : 1); + timer.start(repeat, repeat); return timer; }; |