From e72b072d5333c87e2ca972f0d88dabfa0cedbec2 Mon Sep 17 00:00:00 2001 From: Ryan Dahl Date: Fri, 5 Mar 2010 15:31:21 -0800 Subject: [PATCH] Decouple timer from EventEmitter --- src/node.js | 14 ++++++-------- src/node_timer.cc | 42 ++++++++++++++++++++++++++++++++---------- src/node_timer.h | 7 ++++--- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/src/node.js b/src/node.js index 12686e674c..afc70bf88f 100644 --- a/src/node.js +++ b/src/node.js @@ -246,35 +246,33 @@ function addTimerListener (callback) { // Special case the no param case to avoid the extra object creation. if (arguments.length > 2) { var args = Array.prototype.slice.call(arguments, 2); - timer.addListener("timeout", function(){ - callback.apply(timer, args); - }); + timer.callback = function () { callback.apply(timer, args); }; } else { - timer.addListener("timeout", callback); + timer.callback = callback; } } -GLOBAL.setTimeout = function (callback, after) { +global.setTimeout = function (callback, after) { var timer = new process.Timer(); addTimerListener.apply(timer, arguments); timer.start(after, 0); return timer; }; -GLOBAL.setInterval = function (callback, repeat) { +global.setInterval = function (callback, repeat) { var timer = new process.Timer(); addTimerListener.apply(timer, arguments); timer.start(repeat, repeat); return timer; }; -GLOBAL.clearTimeout = function (timer) { +global.clearTimeout = function (timer) { if (timer instanceof process.Timer) { timer.stop(); } }; -GLOBAL.clearInterval = GLOBAL.clearTimeout; +global.clearInterval = global.clearTimeout; diff --git a/src/node_timer.cc b/src/node_timer.cc index 5d60126c8a..1fa470aad3 100644 --- a/src/node_timer.cc +++ b/src/node_timer.cc @@ -9,6 +9,7 @@ Persistent Timer::constructor_template; static Persistent timeout_symbol; static Persistent repeat_symbol; +static Persistent callback_symbol; void Timer::Initialize (Handle target) @@ -17,12 +18,12 @@ Timer::Initialize (Handle target) Local t = FunctionTemplate::New(Timer::New); constructor_template = Persistent::New(t); - constructor_template->Inherit(EventEmitter::constructor_template); constructor_template->InstanceTemplate()->SetInternalFieldCount(1); constructor_template->SetClassName(String::NewSymbol("Timer")); timeout_symbol = NODE_PSYMBOL("timeout"); repeat_symbol = NODE_PSYMBOL("repeat"); + callback_symbol = NODE_PSYMBOL("callback"); NODE_SET_PROTOTYPE_METHOD(constructor_template, "start", Timer::Start); NODE_SET_PROTOTYPE_METHOD(constructor_template, "stop", Timer::Stop); @@ -66,7 +67,23 @@ Timer::OnTimeout (EV_P_ ev_timer *watcher, int revents) assert(revents == EV_TIMEOUT); - timer->Emit(timeout_symbol, 0, NULL); + HandleScope scope; + + Local callback_v = timer->handle_->Get(callback_symbol); + if (!callback_v->IsFunction()) { + timer->Stop(); + return; + } + + Local callback = Local::Cast(callback_v); + + TryCatch try_catch; + + callback->Call(timer->handle_, 0, NULL); + + if (try_catch.HasCaught()) { + FatalException(try_catch); + } if (timer->watcher_.repeat == 0) timer->Unref(); } @@ -90,8 +107,8 @@ Timer::New (const Arguments& args) Handle Timer::Start (const Arguments& args) { - Timer *timer = ObjectWrap::Unwrap(args.Holder()); HandleScope scope; + Timer *timer = ObjectWrap::Unwrap(args.Holder()); if (args.Length() != 2) return ThrowException(String::New("Bad arguments")); @@ -108,13 +125,18 @@ Timer::Start (const Arguments& args) return Undefined(); } -Handle -Timer::Stop (const Arguments& args) -{ + +Handle Timer::Stop(const Arguments& args) { + HandleScope scope; Timer *timer = ObjectWrap::Unwrap(args.Holder()); - if (ev_is_active(&timer->watcher_)) { - ev_timer_stop(EV_DEFAULT_UC_ &timer->watcher_); - timer->Unref(); - } + timer->Stop(); return Undefined(); } + + +void Timer::Stop () { + if (watcher_.active) { + ev_timer_stop(EV_DEFAULT_UC_ &watcher_); + Unref(); + } +} diff --git a/src/node_timer.h b/src/node_timer.h index d662f9a0fa..0472fdb0d6 100644 --- a/src/node_timer.h +++ b/src/node_timer.h @@ -2,20 +2,20 @@ #define node_timer_h #include -#include +#include #include #include namespace node { -class Timer : EventEmitter { +class Timer : ObjectWrap { public: static void Initialize (v8::Handle target); protected: static v8::Persistent constructor_template; - Timer () : EventEmitter () { } + Timer () : ObjectWrap () { } ~Timer(); static v8::Handle New (const v8::Arguments& args); @@ -26,6 +26,7 @@ class Timer : EventEmitter { private: static void OnTimeout (EV_P_ ev_timer *watcher, int revents); + void Stop (); ev_timer watcher_; };