You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by an...@apache.org on 2012/08/24 23:57:38 UTC

[4/50] [abbrv] js commit: Make channel safer about adding/removing listeners during a fire.

Make channel safer about adding/removing listeners during a fire.


Project: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/commit/f043d4ea
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/f043d4ea
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/f043d4ea

Branch: refs/heads/master
Commit: f043d4ea3c62bcea451469af0fde2ab973a360df
Parents: 5732d87
Author: Andrew Grieve <ag...@chromium.org>
Authored: Thu Aug 23 23:20:41 2012 -0400
Committer: Anis Kadri <an...@gmail.com>
Committed: Fri Aug 24 13:50:04 2012 -0700

----------------------------------------------------------------------
 lib/common/channel.js |   14 ++++++++------
 test/test.channel.js  |    9 +++++++++
 2 files changed, 17 insertions(+), 6 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/f043d4ea/lib/common/channel.js
----------------------------------------------------------------------
diff --git a/lib/common/channel.js b/lib/common/channel.js
index 7281f1b..e68b9cf 100755
--- a/lib/common/channel.js
+++ b/lib/common/channel.js
@@ -192,7 +192,6 @@ Channel.prototype.unsubscribe = function(g) {
     var handler = this.handlers[g];
     if (handler) {
         if (handler.observer_guid) handler.observer_guid=null;
-        this.handlers[g] = null;
         delete this.handlers[g];
         this.numHandlers--;
         if (this.events.onUnsubscribe) this.events.onUnsubscribe.call(this);
@@ -207,12 +206,15 @@ Channel.prototype.fire = function(e) {
         var fail = false;
         this.fired = true;
         this.fireArgs = arguments;
+        // Copy the values first so that it is safe to modify it from within
+        // callbacks.
+        var toCall = [];
         for (var item in this.handlers) {
-            var handler = this.handlers[item];
-            if (typeof handler == 'function') {
-                var rv = (handler.apply(this, arguments)===false);
-                fail = fail || rv;
-            }
+            toCall.push(this.handlers[item]);
+        }
+        for (var i = 0; i < toCall.length; ++i) {
+            var rv = (toCall[i].apply(this, arguments)===false);
+            fail = fail || rv;
         }
         return !fail;
     }

http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/blob/f043d4ea/test/test.channel.js
----------------------------------------------------------------------
diff --git a/test/test.channel.js b/test/test.channel.js
index b485f6f..ae81527 100644
--- a/test/test.channel.js
+++ b/test/test.channel.js
@@ -233,5 +233,14 @@ describe("channel", function () {
             c.fire();
             expect(count).toEqual(2);
         });
+        it("should not prevent a callback from firing when it is removed during firing.", function() {
+            var count = 0;
+            var handler = jasmine.createSpy().andCallFake(function() { count++; c.unsubscribe(handler2); });
+            var handler2 = jasmine.createSpy().andCallFake(function() { count++; });
+            c.subscribeOnce(handler);
+            c.subscribeOnce(handler2);
+            c.fire();
+            expect(count).toEqual(2);
+        });
     });
 });