Permalink
Browse files

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.
  • Loading branch information...
1 parent 78aaf8d commit 50c0d16208aab392d815e420f3423d23283a31de @ry ry committed Jul 24, 2009
Showing with 20 additions and 10 deletions.
  1. +18 −9 src/events.cc
  2. +2 −1 src/events.js
View
@@ -33,24 +33,33 @@ EventEmitter::Initialize (v8::Handle<v8::Object> target)
bool
EventEmitter::Emit (const char *type, int argc, Handle<Value> argv[])
{
+ HandleScope scope;
+
Local<Value> emit_v = handle_->Get(String::NewSymbol("emit"));
assert(emit_v->IsFunction());
Local<Function> emit = Local<Function>::Cast(emit_v);
- Local<Array> event_args = Array::New(argc);
- for (int i = 0; i < argc; i++) {
- event_args->Set(Integer::New(i), argv[i]);
- }
+ Local<Value> events_v = handle_->Get(String::NewSymbol("_events"));
+ if (!events_v->IsObject()) return false;
+ Local<Object> events = events_v->ToObject();
- Handle<Value> emit_argv[2] = { String::NewSymbol(type), event_args };
+ Local<Value> listeners_v = events->Get(String::NewSymbol(type));
+ if (!listeners_v->IsArray()) return false;
+ Local<Array> listeners = Local<Array>::Cast(listeners_v);
TryCatch try_catch;
- emit->Call(handle_, 2, emit_argv);
+ for (int i = 0; i < listeners->Length(); i++) {
+ Local<Value> listener_v = listeners->Get(Integer::New(i));
+ if (!listener_v->IsFunction()) continue;
+ Local<Function> listener = Local<Function>::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;
View
@@ -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);

0 comments on commit 50c0d16

Please sign in to comment.