mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-11 20:35:50 +00:00
Bug 1185486 - Part 2: Prevent message listeners from a failed command from causing an out of order response when a content command hangs. r=ato
--HG-- extra : commitid : 9x2P0ubHLCZ
This commit is contained in:
parent
7c2c936f02
commit
cc73ee6143
@ -72,12 +72,18 @@ var ContentSender = function(mmFn, sendAsyncFn) {
|
||||
this.curId = null;
|
||||
this.sendAsync = sendAsyncFn;
|
||||
this.mmFn_ = mmFn;
|
||||
this._listeners = [];
|
||||
};
|
||||
|
||||
Object.defineProperty(ContentSender.prototype, "mm", {
|
||||
get: function() { return this.mmFn_(); }
|
||||
});
|
||||
|
||||
ContentSender.prototype.removeListeners = function () {
|
||||
this._listeners.map(l => this.mm.removeMessageListener(l[0], l[1]));
|
||||
this._listeners = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Call registered function in the frame script environment of the
|
||||
* current browsing context's content frame.
|
||||
@ -94,6 +100,13 @@ Object.defineProperty(ContentSender.prototype, "mm", {
|
||||
* A promise that resolves to the result of the command.
|
||||
*/
|
||||
ContentSender.prototype.send = function(name, args) {
|
||||
if (this._listeners[0]) {
|
||||
// A prior (probably timed-out) request has left listeners behind.
|
||||
// Remove them before proceeding.
|
||||
logger.warn("A previous failed command left content listeners behind!");
|
||||
this.removeListeners();
|
||||
}
|
||||
|
||||
this.curId = uuidgen.generateUUID().toString();
|
||||
|
||||
let proxy = new Promise((resolve, reject) => {
|
||||
@ -106,40 +119,33 @@ ContentSender.prototype.send = function(name, args) {
|
||||
return;
|
||||
}
|
||||
|
||||
listeners.remove();
|
||||
this.removeListeners();
|
||||
modal.removeHandler(handleDialog);
|
||||
|
||||
fn(msg);
|
||||
this.curId = null;
|
||||
};
|
||||
|
||||
listeners.push([n, rmFn]);
|
||||
this._listeners.push([n, rmFn]);
|
||||
return rmFn;
|
||||
};
|
||||
|
||||
let listeners = [];
|
||||
listeners.add = () => {
|
||||
this.mm.addMessageListener(MARIONETTE_OK, removeListeners(MARIONETTE_OK, okListener));
|
||||
this.mm.addMessageListener(MARIONETTE_DONE, removeListeners(MARIONETTE_DONE, valListener));
|
||||
this.mm.addMessageListener(MARIONETTE_ERROR, removeListeners(MARIONETTE_ERROR, errListener));
|
||||
};
|
||||
listeners.remove = () =>
|
||||
listeners.map(l => this.mm.removeMessageListener(l[0], l[1]));
|
||||
|
||||
let okListener = () => resolve();
|
||||
let valListener = msg => resolve(msg.json.value);
|
||||
let errListener = msg => reject(msg.objects.error);
|
||||
|
||||
let handleDialog = function(subject, topic) {
|
||||
listeners.remove();
|
||||
let handleDialog = (subject, topic) => {
|
||||
this.removeListeners()
|
||||
modal.removeHandler(handleDialog);
|
||||
this.sendAsync("cancelRequest");
|
||||
resolve();
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
// start content process listeners, and install observers for global-
|
||||
// and tab modal dialogues
|
||||
listeners.add();
|
||||
this.mm.addMessageListener(MARIONETTE_OK, removeListeners(MARIONETTE_OK, okListener));
|
||||
this.mm.addMessageListener(MARIONETTE_DONE, removeListeners(MARIONETTE_DONE, valListener));
|
||||
this.mm.addMessageListener(MARIONETTE_ERROR, removeListeners(MARIONETTE_ERROR, errListener));
|
||||
modal.addHandler(handleDialog);
|
||||
|
||||
// new style dispatches are arrays of arguments, old style dispatches
|
||||
|
Loading…
Reference in New Issue
Block a user