From 50c0d16208aab392d815e420f3423d23283a31de Mon Sep 17 00:00:00 2001 From: Ryan Date: Fri, 24 Jul 2009 12:53:46 +0200 Subject: [PATCH] Fix memory leak. It was only a missing HandleScope in Emit()! This change also tries to optimize Emit by looping through the listeners in C++. The javascript version of this function is still there and being used, but only by javascript code. Not an ideal solution - there should only be one implementation - however for now it seems to help. This doesn't solve all of the memory leaks that we're experiencing, there seems to be another subtle problem. --- src/events.cc | 27 ++++++++++++++++++--------- src/events.js | 3 ++- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/events.cc b/src/events.cc index 9967c1cb36..0116087a30 100644 --- a/src/events.cc +++ b/src/events.cc @@ -33,24 +33,33 @@ EventEmitter::Initialize (v8::Handle target) bool EventEmitter::Emit (const char *type, int argc, Handle argv[]) { + HandleScope scope; + Local emit_v = handle_->Get(String::NewSymbol("emit")); assert(emit_v->IsFunction()); Local emit = Local::Cast(emit_v); - Local event_args = Array::New(argc); - for (int i = 0; i < argc; i++) { - event_args->Set(Integer::New(i), argv[i]); - } + Local events_v = handle_->Get(String::NewSymbol("_events")); + if (!events_v->IsObject()) return false; + Local events = events_v->ToObject(); - Handle emit_argv[2] = { String::NewSymbol(type), event_args }; + Local listeners_v = events->Get(String::NewSymbol(type)); + if (!listeners_v->IsArray()) return false; + Local listeners = Local::Cast(listeners_v); TryCatch try_catch; - emit->Call(handle_, 2, emit_argv); + for (int i = 0; i < listeners->Length(); i++) { + Local listener_v = listeners->Get(Integer::New(i)); + if (!listener_v->IsFunction()) continue; + Local listener = Local::Cast(listener_v); + + listener->Call(handle_, argc, argv); - if (try_catch.HasCaught()) { - FatalException(try_catch); - return false; + if (try_catch.HasCaught()) { + FatalException(try_catch); + return false; + } } return true; diff --git a/src/events.js b/src/events.js index a43a6036cc..0430533a4f 100644 --- a/src/events.js +++ b/src/events.js @@ -18,13 +18,14 @@ emitter.listeners = function (type) { }; // This function is called often from C++. +// FIXME there is a counterpart for this function in C++ +// both must have the same behavior. // See events.cc emitter.emit = function (type, args) { if (!this._events) return; if (!this._events.hasOwnProperty(type)) return; var listeners = this._events[type]; - var length = listeners.length; for (var i = 0; i < listeners.length; i++) { listeners[i].apply(this, args);