Bug 1057386 - Provide an API to let the shutdown leak detector wait until resources are properly destroyed r=adw

This commit is contained in:
Tim Taubert 2014-08-31 12:13:08 +02:00
parent f20cb9b88b
commit 3f1bbb16fd
2 changed files with 27 additions and 10 deletions

View File

@ -87,21 +87,30 @@ this.ContentSearch = {
// { controller, previousFormHistoryResult }. See _onMessageGetSuggestions. // { controller, previousFormHistoryResult }. See _onMessageGetSuggestions.
_suggestionMap: new WeakMap(), _suggestionMap: new WeakMap(),
// Resolved when we finish shutting down.
_destroyedPromise: null,
init: function () { init: function () {
Cc["@mozilla.org/globalmessagemanager;1"]. Cc["@mozilla.org/globalmessagemanager;1"].
getService(Ci.nsIMessageListenerManager). getService(Ci.nsIMessageListenerManager).
addMessageListener(INBOUND_MESSAGE, this); addMessageListener(INBOUND_MESSAGE, this);
Services.obs.addObserver(this, "browser-search-engine-modified", false); Services.obs.addObserver(this, "browser-search-engine-modified", false);
Services.obs.addObserver(this, "shutdown-leaks-before-check", false);
}, },
destroy: function () { destroy: function () {
if (this._destroyedPromise) {
return this._destroyedPromise;
}
Cc["@mozilla.org/globalmessagemanager;1"]. Cc["@mozilla.org/globalmessagemanager;1"].
getService(Ci.nsIMessageListenerManager). getService(Ci.nsIMessageListenerManager).
removeMessageListener(INBOUND_MESSAGE, this); removeMessageListener(INBOUND_MESSAGE, this);
Services.obs.removeObserver(this, "browser-search-engine-modified"); Services.obs.removeObserver(this, "browser-search-engine-modified");
Services.obs.removeObserver(this, "shutdown-leaks-before-check");
this._eventQueue.length = 0; this._eventQueue.length = 0;
return Promise.resolve(this._currentEventPromise); return this._destroyedPromise = Promise.resolve(this._currentEventPromise);
}, },
/** /**
@ -148,6 +157,10 @@ this.ContentSearch = {
}); });
this._processEventQueue(); this._processEventQueue();
break; break;
case "shutdown-leaks-before-check":
subj.wrappedJSObject.client.addBlocker(
"ContentSearch: Wait until the service is destroyed", () => this.destroy());
break;
} }
}, },

View File

@ -458,7 +458,6 @@ Tester.prototype = {
// is invoked to start the tests. // is invoked to start the tests.
this.waitForWindowsState((function () { this.waitForWindowsState((function () {
if (this.done) { if (this.done) {
let promise = Promise.resolve();
// Uninitialize a few things explicitly so that they can clean up // Uninitialize a few things explicitly so that they can clean up
// frames and browser intentionally kept alive until shutdown to // frames and browser intentionally kept alive until shutdown to
@ -489,15 +488,8 @@ Tester.prototype = {
SocialFlyout.unload(); SocialFlyout.unload();
SocialShare.uninit(); SocialShare.uninit();
TabView.uninit(); TabView.uninit();
// Destroying ContentSearch is asynchronous.
promise = ContentSearch.destroy();
} }
// Simulate memory pressure so that we're forced to free more resources
// and thus get rid of more false leaks like already terminated workers.
Services.obs.notifyObservers(null, "memory-pressure", "heap-minimize");
// Schedule GC and CC runs before finishing in order to detect // Schedule GC and CC runs before finishing in order to detect
// DOM windows leaked by our tests or the tested code. Note that we // DOM windows leaked by our tests or the tested code. Note that we
// use a shrinking GC so that the JS engine will discard JIT code and // use a shrinking GC so that the JS engine will discard JIT code and
@ -527,7 +519,19 @@ Tester.prototype = {
} }
}; };
promise.then(() => { let {AsyncShutdown} =
Cu.import("resource://gre/modules/AsyncShutdown.jsm", {});
let barrier = new AsyncShutdown.Barrier(
"ShutdownLeaks: Wait for cleanup to be finished before checking for leaks");
Services.obs.notifyObservers({wrappedJSObject: barrier},
"shutdown-leaks-before-check", null);
barrier.wait().then(() => {
// Simulate memory pressure so that we're forced to free more resources
// and thus get rid of more false leaks like already terminated workers.
Services.obs.notifyObservers(null, "memory-pressure", "heap-minimize");
checkForLeakedGlobalWindows(aResults => { checkForLeakedGlobalWindows(aResults => {
if (aResults.length == 0) { if (aResults.length == 0) {
this.finish(); this.finish();