Bug 1459298 - Stop spinning event loop when window closes; r=esawin

If our window closes while we're spinning the event loop, stop spinning
as soon as possible so we can continue with cleaning up the window.

MozReview-Commit-ID: ByS0c6R0cM8

--HG--
extra : rebase_source : 6d32f1e8c6d6119eaaacb6a3ef5d9319c884e642
This commit is contained in:
Jim Chen 2018-05-07 10:05:56 -04:00
parent 6802d07a28
commit a2a7ef293f
6 changed files with 34 additions and 24 deletions

View File

@ -39,8 +39,8 @@ class GeckoViewNavigationContent extends GeckoViewContentModule {
addEventListener("click", ErrorPageEventHandler, true);
}
return LoadURIDelegate.load(this.eventDispatcher, aUri, aWhere, aFlags,
aTriggeringPrincipal);
return LoadURIDelegate.load(content, this.eventDispatcher,
aUri, aWhere, aFlags);
}
}

View File

@ -55,7 +55,7 @@ GeckoViewPermission.prototype = {
perms.push(PERM_RECORD_AUDIO);
}
let dispatcher = GeckoViewUtils.getActiveDispatcher();
let [dispatcher] = GeckoViewUtils.getActiveDispatcherAndWindow();
let callback = _ => {
Services.obs.notifyObservers(aCallback, "getUserMedia:got-device-permission");
};

View File

@ -344,7 +344,8 @@ function PromptDelegate(aDomWin) {
}
if (!this._dispatcher) {
this._dispatcher = GeckoViewUtils.getActiveDispatcher();
[this._dispatcher, this._domWin] =
GeckoViewUtils.getActiveDispatcherAndWindow();
}
}
@ -392,14 +393,15 @@ PromptDelegate.prototype = {
*/
_showPrompt: function(aMsg) {
let result = undefined;
if (!this._changeModalState(/* aEntering */ true)) {
if (!this._domWin || !this._changeModalState(/* aEntering */ true)) {
return;
}
try {
this.asyncShowPrompt(aMsg, res => result = res);
// Spin this thread while we wait for a result
Services.tm.spinEventLoopUntil(() => result !== undefined);
Services.tm.spinEventLoopUntil(() =>
this._domWin.closed || result !== undefined);
} finally {
this._changeModalState(/* aEntering */ false);
}

View File

@ -139,14 +139,15 @@ class GeckoViewNavigation extends GeckoViewModule {
nextTabParentId: aNextTabParentId
});
}).then(window => {
browser = (window && window.browser);
browser = (window && window.browser) || null;
}, () => {
browser = null;
});
// Wait indefinitely for app to respond with a browser or null
Services.tm.spinEventLoopUntil(() => browser !== undefined);
return browser;
Services.tm.spinEventLoopUntil(() =>
this.window.closed || browser !== undefined);
return browser || null;
}
// nsIBrowserDOMWindow.
@ -154,8 +155,8 @@ class GeckoViewNavigation extends GeckoViewModule {
debug `createContentWindow: uri=${aUri && aUri.spec}
where=${aWhere} flags=${aFlags}`;
if (LoadURIDelegate.load(this.eventDispatcher, aUri, aWhere, aFlags,
aTriggeringPrincipal)) {
if (LoadURIDelegate.load(this.window, this.eventDispatcher,
aUri, aWhere, aFlags)) {
// The app has handled the load, abort open-window handling.
Components.returnCode = Cr.NS_ERROR_ABORT;
return null;
@ -179,7 +180,8 @@ class GeckoViewNavigation extends GeckoViewModule {
nextTabParentId=${aNextTabParentId}
name=${aName}`;
if (LoadURIDelegate.load(this.eventDispatcher, aUri, aWhere, aFlags, null)) {
if (LoadURIDelegate.load(this.window, this.eventDispatcher,
aUri, aWhere, aFlags)) {
// The app has handled the load, abort open-window handling.
Components.returnCode = Cr.NS_ERROR_ABORT;
return null;
@ -199,8 +201,8 @@ class GeckoViewNavigation extends GeckoViewModule {
debug `handleOpenUri: uri=${aUri && aUri.spec}
where=${aWhere} flags=${aFlags}`;
if (LoadURIDelegate.load(this.eventDispatcher, aUri, aWhere, aFlags,
aTriggeringPrincipal)) {
if (LoadURIDelegate.load(this.window, this.eventDispatcher,
aUri, aWhere, aFlags)) {
return null;
}

View File

@ -289,21 +289,22 @@ var GeckoViewUtils = {
return null;
},
getActiveDispatcher: function() {
let dispatcher = this.getDispatcherForWindow(Services.focus.activeWindow);
getActiveDispatcherAndWindow: function() {
let win = Services.focus.activeWindow;
let dispatcher = this.getDispatcherForWindow(win);
if (dispatcher) {
return dispatcher;
return [dispatcher, win];
}
let iter = Services.wm.getEnumerator(/* windowType */ null);
while (iter.hasMoreElements()) {
dispatcher = this.getDispatcherForWindow(
iter.getNext().QueryInterface(Ci.nsIDOMWindow));
win = iter.getNext().QueryInterface(Ci.nsIDOMWindow);
dispatcher = this.getDispatcherForWindow(win);
if (dispatcher) {
return dispatcher;
return [dispatcher, win];
}
}
return null;
return [null, null];
},
/**

View File

@ -15,7 +15,11 @@ XPCOMUtils.defineLazyModuleGetters(this, {
var LoadURIDelegate = {
// Delegate URI loading to the app.
// Return whether the loading has been handled.
load: function(aEventDispatcher, aUri, aWhere, aFlags, aTriggeringPrincipal) {
load: function(aWindow, aEventDispatcher, aUri, aWhere, aFlags) {
if (!aWindow) {
return false;
}
const message = {
type: "GeckoView:OnLoadRequest",
uri: aUri ? aUri.displaySpec : "",
@ -31,8 +35,9 @@ var LoadURIDelegate = {
// treat as unhandled.
handled = false;
});
Services.tm.spinEventLoopUntil(() => handled !== undefined);
Services.tm.spinEventLoopUntil(() =>
aWindow.closed || handled !== undefined);
return handled;
return handled || false;
}
};