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