timers: use uv_now instead of Date.now

This saves a few calls to gettimeofday which can be expensive, and
potentially subject to clock drift. Instead use the loop time which
uses hrtime internally.

fixes #5497
This commit is contained in:
Timothy J Fontaine 2013-05-22 11:32:54 -07:00
parent f58eb8f5db
commit f8193ab3c4
3 changed files with 16 additions and 5 deletions

View File

@ -45,7 +45,7 @@ var lists = {};
// the main function - creates lists on demand and the watchers associated // the main function - creates lists on demand and the watchers associated
// with them. // with them.
function insert(item, msecs) { function insert(item, msecs) {
item._idleStart = Date.now(); item._idleStart = Timer.now();
item._idleTimeout = msecs; item._idleTimeout = msecs;
if (msecs < 0) return; if (msecs < 0) return;
@ -75,7 +75,7 @@ function listOnTimeout() {
debug('timeout callback %d', msecs); debug('timeout callback %d', msecs);
var now = Date.now(); var now = Timer.now();
debug('now: %s', now); debug('now: %s', now);
var first; var first;
@ -165,7 +165,7 @@ exports.active = function(item) {
if (!list || L.isEmpty(list)) { if (!list || L.isEmpty(list)) {
insert(item, msecs); insert(item, msecs);
} else { } else {
item._idleStart = Date.now(); item._idleStart = Timer.now();
L.append(list, item); L.append(list, item);
} }
} }
@ -277,7 +277,7 @@ var Timeout = function(after) {
Timeout.prototype.unref = function() { Timeout.prototype.unref = function() {
if (!this._handle) { if (!this._handle) {
var now = Date.now(); var now = Timer.now();
if (!this._idleStart) this._idleStart = now; if (!this._idleStart) this._idleStart = now;
var delay = this._idleStart + this._idleTimeout - now; var delay = this._idleStart + this._idleTimeout - now;
if (delay < 0) delay = 0; if (delay < 0) delay = 0;

View File

@ -28,6 +28,8 @@ var stream = require('stream');
var assert = require('assert').ok; var assert = require('assert').ok;
var constants = require('constants'); var constants = require('constants');
var Timer = process.binding('timer_wrap').Timer;
var DEFAULT_CIPHERS = 'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' + // TLS 1.2 var DEFAULT_CIPHERS = 'ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:' + // TLS 1.2
'RC4:HIGH:!MD5:!aNULL:!EDH'; // TLS 1.0 'RC4:HIGH:!MD5:!aNULL:!EDH'; // TLS 1.0
@ -720,7 +722,7 @@ function onhandshakestart() {
var self = this; var self = this;
var ssl = self.ssl; var ssl = self.ssl;
var now = Date.now(); var now = Timer.now();
assert(now >= ssl.lastHandshakeTime); assert(now >= ssl.lastHandshakeTime);

View File

@ -51,6 +51,8 @@ class TimerWrap : public HandleWrap {
constructor->InstanceTemplate()->SetInternalFieldCount(1); constructor->InstanceTemplate()->SetInternalFieldCount(1);
constructor->SetClassName(String::NewSymbol("Timer")); constructor->SetClassName(String::NewSymbol("Timer"));
NODE_SET_METHOD(constructor, "now", Now);
NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close); NODE_SET_PROTOTYPE_METHOD(constructor, "close", HandleWrap::Close);
NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref); NODE_SET_PROTOTYPE_METHOD(constructor, "ref", HandleWrap::Ref);
NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref); NODE_SET_PROTOTYPE_METHOD(constructor, "unref", HandleWrap::Unref);
@ -163,6 +165,13 @@ class TimerWrap : public HandleWrap {
MakeCallback(wrap->object_, ontimeout_sym, ARRAY_SIZE(argv), argv); MakeCallback(wrap->object_, ontimeout_sym, ARRAY_SIZE(argv), argv);
} }
static Handle<Value> Now(const Arguments& args) {
HandleScope scope(node_isolate);
double now = static_cast<double>(uv_now(uv_default_loop()));
return scope.Close(v8::Number::New(now));
}
uv_timer_t handle_; uv_timer_t handle_;
}; };