mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 852847 - Part 4: Fix a child-process shutdown leak around nested event loops. r=smaug
This also fixes a non-shutdown leak which occurs if you remove an <iframe mozbrowser> from the DOM while it's processing an alert().
This commit is contained in:
parent
71ea5cad0e
commit
3894d095f8
@ -103,6 +103,8 @@ BrowserElementChild.prototype = {
|
||||
// Counter of contextmenu events fired
|
||||
this._ctxCounter = 0;
|
||||
|
||||
this._shuttingDown = false;
|
||||
|
||||
addEventListener('DOMTitleChanged',
|
||||
this._titleChangedHandler.bind(this),
|
||||
/* useCapture = */ true,
|
||||
@ -113,6 +115,16 @@ BrowserElementChild.prototype = {
|
||||
/* useCapture = */ true,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
// This listens to unload events from our message manager, but /not/ from
|
||||
// the |content| window. That's because the window's unload event doesn't
|
||||
// bubble, and we're not using a capturing listener. If we'd used
|
||||
// useCapture == true, we /would/ hear unload events from the window, which
|
||||
// is not what we want!
|
||||
addEventListener('unload',
|
||||
this._unloadHandler.bind(this),
|
||||
/* useCapture = */ false,
|
||||
/* wantsUntrusted = */ false);
|
||||
|
||||
// Registers a MozAfterPaint handler for the very first paint.
|
||||
this._addMozAfterPaintHandler(function () {
|
||||
sendAsyncMsg('firstpaint');
|
||||
@ -185,6 +197,10 @@ BrowserElementChild.prototype = {
|
||||
Services.obs.addObserver(this,
|
||||
'ask-parent-to-rollback-fullscreen',
|
||||
/* ownsWeak = */ true);
|
||||
|
||||
Services.obs.addObserver(this,
|
||||
'xpcom-shutdown',
|
||||
/* ownsWeak = */ true);
|
||||
},
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
@ -201,9 +217,20 @@ BrowserElementChild.prototype = {
|
||||
case 'ask-parent-to-rollback-fullscreen':
|
||||
sendAsyncMsg('rollback-fullscreen');
|
||||
break;
|
||||
case 'xpcom-shutdown':
|
||||
this._shuttingDown = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Called when our TabChildGlobal starts to die. This is not called when the
|
||||
* page inside |content| unloads.
|
||||
*/
|
||||
_unloadHandler: function() {
|
||||
this._shuttingDown = true;
|
||||
},
|
||||
|
||||
_tryGetInnerWindowID: function(win) {
|
||||
let utils = win.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
@ -275,9 +302,10 @@ BrowserElementChild.prototype = {
|
||||
|
||||
let thread = Services.tm.currentThread;
|
||||
debug("Nested event loop - begin");
|
||||
while (win.modalDepth == origModalDepth) {
|
||||
while (win.modalDepth == origModalDepth && !this._shuttingDown) {
|
||||
// Bail out of the loop if the inner window changed; that means the
|
||||
// window navigated.
|
||||
// window navigated. Bail out when we're shutting down because otherwise
|
||||
// we'll leak our window.
|
||||
if (this._tryGetInnerWindowID(win) !== innerWindowID) {
|
||||
debug("_waitForResult: Inner window ID changed " +
|
||||
"while in nested event loop.");
|
||||
|
Loading…
Reference in New Issue
Block a user