Skip to content

Instantly share code, notes, and snippets.

@piscisaureus
Created May 27, 2011 03:22
Show Gist options
  • Save piscisaureus/994580 to your computer and use it in GitHub Desktop.
Save piscisaureus/994580 to your computer and use it in GitHub Desktop.
From 587f45283732156709d645665279fd156ffebac0 Mon Sep 17 00:00:00 2001
From: Bert Belder <bert@piscisaureus2.(none)>
Date: Fri, 27 May 2011 22:11:42 +0200
Subject: [PATCH 1/1] Use timer_wrap instead of the old timer binding
---
lib/dns.js | 11 +++---
lib/timers.js | 101 ++++++++++++++++++++++++++---------------------------
src/node.cc | 6 ---
src/timer_wrap.cc | 5 ++-
4 files changed, 60 insertions(+), 63 deletions(-)
diff --git a/lib/dns.js b/lib/dns.js
index 3ee997b..e1c854b 100644
--- a/lib/dns.js
+++ b/lib/dns.js
@@ -23,14 +23,13 @@ var dns = process.binding('cares');
var net = process.binding('net');
var IOWatcher = process.binding('io_watcher').IOWatcher;
+var timer;
var watchers = {};
var activeWatchers = {};
-var Timer = process.binding('timer').Timer;
-var timer = new Timer();
-timer.callback = function() {
+function timerCallback() {
var sockets = Object.keys(activeWatchers);
for (var i = 0, l = sockets.length; i < l; i++) {
var socket = sockets[i];
@@ -43,13 +42,15 @@ timer.callback = function() {
function updateTimer() {
- timer.stop();
+ if (timer) {
+ clearTimeout(timer);
+ }
// Were just checking to see if activeWatchers is empty or not
if (0 === Object.keys(activeWatchers).length) return;
var max = 20000;
var timeout = channel.timeout(max);
- timer.start(timeout, 0);
+ timer = setTimeout(timerCallback, timer);
}
diff --git a/lib/timers.js b/lib/timers.js
index d6fede1..8a41afb 100644
--- a/lib/timers.js
+++ b/lib/timers.js
@@ -19,7 +19,7 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
// USE OR OTHER DEALINGS IN THE SOFTWARE.
-var Timer = process.binding('timer').Timer;
+var Timer = process.binding('timer_wrap').Timer;
var L = require('_linklist');
var assert = require('assert').ok;
@@ -59,14 +59,15 @@ function insert(item, msecs) {
list = lists[msecs];
} else {
list = new Timer();
+ list.start(msecs, msecs);
+
L.init(list);
lists[msecs] = list;
- list.callback = function() {
+ list.ontimeout = function() {
debug('timeout callback ' + msecs);
- // TODO - don't stop and start the watcher all the time.
- // just set its repeat
+
var now = new Date();
debug('now: ' + now);
@@ -74,7 +75,8 @@ function insert(item, msecs) {
while (first = L.peek(list)) {
var diff = now - first._idleStart;
if (diff + 1 < msecs) {
- list.again(msecs - diff);
+ list.setRepeat(msecs - diff);
+ list.again();
debug(msecs + ' list wait because diff is ' + diff);
return;
} else {
@@ -86,15 +88,11 @@ function insert(item, msecs) {
debug(msecs + ' list empty');
assert(L.isEmpty(list));
- list.stop();
+ list.close();
+ delete lists[msecs];
};
}
- if (L.isEmpty(list)) {
- // if empty (re)start the timer
- list.again(msecs);
- }
-
L.append(list, item);
assert(!L.isEmpty(list)); // list is not empty
}
@@ -108,7 +106,8 @@ var unenroll = exports.unenroll = function(item) {
debug('unenroll');
if (list && L.isEmpty(list)) {
debug('unenroll: list empty');
- list.stop();
+ list.close();
+ delete lists[item._idleTimeout];
}
};
@@ -146,43 +145,43 @@ exports.active = function(item) {
exports.setTimeout = function(callback, after) {
- var timer;
+ var timer, c, args;
if (after <= 0) {
// Use the slow case for after == 0
timer = new Timer();
- timer.callback = callback;
+ timer.ontimeout = callback;
+
+ args = Array.prototype.slice.call(arguments, 2);
+ timer.ontimeout = function() {
+ callback.apply(timer, args);
+ timer.close();
+ }
+
+ timer.start(0, 0);
} else {
- timer = { _idleTimeout: after, _onTimeout: callback };
+ timer = { _idleTimeout: after };
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);
- var c = function() {
- callback.apply(timer, args);
- };
- if (timer instanceof Timer) {
- timer.callback = c;
+ if (arguments.length <= 2) {
+ timer._onTimeout = callback;
} else {
- timer._onTimeout = c;
+ /*
+ * 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.
+ */
+ args = Array.prototype.slice.call(arguments, 2);
+ timer._onTimeout = function() {
+ callback.apply(timer, args);
+ }
}
- }
- if (timer instanceof Timer) {
- timer.start(0, 0);
- } else {
exports.active(timer);
}
@@ -191,10 +190,13 @@ exports.setTimeout = function(callback, after) {
exports.clearTimeout = function(timer) {
- if (timer && (timer.callback || timer._onTimeout)) {
- timer.callback = timer._onTimeout = null;
- exports.unenroll(timer);
- if (timer instanceof Timer) timer.stop(); // for after === 0
+ if (timer && (timer.ontimeout || timer._onTimeout)) {
+ timer.ontimeout = timer._onTimeout = null;
+ if (timer instanceof Timer) {
+ timer.close(); // for after === 0
+ } else {
+ exports.unenroll(timer);
+ }
}
};
@@ -202,13 +204,10 @@ exports.clearTimeout = function(timer) {
exports.setInterval = function(callback, repeat) {
var timer = new Timer();
- if (arguments.length > 2) {
- var args = Array.prototype.slice.call(arguments, 2);
- timer.callback = function() {
- callback.apply(timer, args);
- };
- } else {
- timer.callback = callback;
+ var args = Array.prototype.slice.call(arguments, 2);
+ timer._onTimeout = function() {
+ callback.apply(timer, args);
+ timer.close();
}
timer.start(repeat, repeat ? repeat : 1);
@@ -218,7 +217,7 @@ exports.setInterval = function(callback, repeat) {
exports.clearInterval = function(timer) {
if (timer instanceof Timer) {
- timer.callback = null;
- timer.stop();
+ timer.ontimeout = null;
+ timer.close();
}
};
diff --git a/src/node.cc b/src/node.cc
index 8e62770..12ece7f 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -64,7 +64,6 @@
#include <node_http_parser.h>
#include <node_signal_watcher.h>
#include <node_stat_watcher.h>
-#include <node_timer.h>
#include <node_child_process.h>
#include <node_constants.h>
#include <node_stdio.h>
@@ -1839,11 +1838,6 @@ static Handle<Value> Binding(const Arguments& args) {
IOWatcher::Initialize(exports);
binding_cache->Set(module, exports);
- } else if (!strcmp(*module_v, "timer")) {
- exports = Object::New();
- Timer::Initialize(exports);
- binding_cache->Set(module, exports);
-
} else if (!strcmp(*module_v, "natives")) {
exports = Object::New();
DefineJavaScript(exports);
diff --git a/src/timer_wrap.cc b/src/timer_wrap.cc
index 53da51d..ec8d58d 100644
--- a/src/timer_wrap.cc
+++ b/src/timer_wrap.cc
@@ -78,7 +78,10 @@ static void MakeCallback(Handle<Object> object,
HandleScope scope;
Local<Value> callback_v = object->Get(String::New(method));
- assert(callback_v->IsFunction());
+ if (!callback_v->IsFunction()) {
+ return;
+ }
+
Local<Function> callback = Local<Function>::Cast(callback_v);
// TODO Hook for long stack traces to be made here.
--
1.7.4.1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment