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

[2/5] 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/e4448110
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/tree/e4448110
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cordova-js/diff/e4448110

Branch: refs/heads/master
Commit: e4448110fd2dd9da97c22276dfa1458a71c9f658
Parents: 470ac67
Author: Andrew Grieve <ag...@chromium.org>
Authored: Thu Aug 23 23:20:41 2012 -0400
Committer: Andrew Grieve <ag...@chromium.org>
Committed: Thu Aug 23 23:35:56 2012 -0400

----------------------------------------------------------------------
 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/e4448110/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/e4448110/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);
+        });
     });
 });