Bug 1358907 Part 2 Wait for database load before shutting down r=mossop

Make sure the XPI database is fully loaded before running the
XPIDatabase.shutdown() logic.  This race has been present for a long
time but it suddenly became much more common when loading of the XPI
database was deferred until after startup.

MozReview-Commit-ID: 1llKuH3It19

--HG--
extra : rebase_source : de18515e0c38193d70953a49803fadb43be9286c
This commit is contained in:
Andrew Swan 2017-06-30 10:09:59 -07:00
Родитель bad78dd7d7
Коммит 453ee8a579
2 изменённых файлов: 36 добавлений и 22 удалений

Просмотреть файл

@ -658,7 +658,7 @@ this.XPIDatabase = {
* flush after the database is flushed and
* all cleanup is done
*/
shutdown() {
async shutdown() {
logger.debug("shutdown");
if (this.initialized) {
// If our last database I/O had an error, try one last time to save.
@ -676,17 +676,25 @@ this.XPIDatabase = {
"XPIDB_saves_late", this._deferredSave.dirty ? 1 : 0);
}
// Return a promise that any pending writes of the DB are complete and we
// are finished cleaning up
let flushPromise = this.flush();
flushPromise.catch(error => {
// If we're shutting down while still loading, finish loading
// before everything else!
if (this._dbPromise) {
await this._dbPromise;
}
// Await and pending DB writes and finish cleaning up.
try {
await this.flush();
} catch (error) {
logger.error("Flush of XPI database failed", error);
AddonManagerPrivate.recordSimpleMeasure("XPIDB_shutdownFlush_failed", 1);
// If our last attempt to read or write the DB failed, force a new
// extensions.ini to be written to disk on the next startup
Services.prefs.setBoolPref(PREF_PENDING_OPERATIONS, true);
})
.then(count => {
throw error;
}
// Clear out the cached addons data loaded from JSON
delete this.addonDB;
delete this._dbPromise;
@ -694,10 +702,7 @@ this.XPIDatabase = {
delete this._deferredSave;
// re-enable the schema version setter
delete this._schemaVersionSet;
});
return flushPromise;
}
return Promise.resolve(0);
},
/**

Просмотреть файл

@ -255,6 +255,15 @@ function run_test_1() {
gExtensionsJSON.create(AM_Ci.nsIFile.DIRECTORY_TYPE, FileUtils.PERMS_DIRECTORY);
startupManager(false);
// Load the database.
awaitPromise(new Promise(resolve => {
Services.obs.addObserver(function listener() {
Services.obs.removeObserver(listener, "xpi-database-loaded");
resolve();
}, "xpi-database-loaded");
Services.obs.notifyObservers(null, "sessionstore-windows-restored");
}));
// Accessing the add-ons should open and recover the database
AddonManager.getAddonsByIDs(["addon1@tests.mozilla.org",
"addon2@tests.mozilla.org",