Bug 1243549 - SessionFile.wipe() now waits until SessionFile has been properly initialized. r=mconley

While investigating bug 1243549, we encountered several instances of the following error message during each startup:

*************************
A coding exception was thrown and uncaught in a Task.

Full message: TypeError: this.Paths is null
Full stack: Agent.wipe@resource:///modules/sessionstore/SessionWorker.js:296:7
worker.dispatch@resource:///modules/sessionstore/SessionWorker.js:21:24
anonymous/AbstractWorker.prototype.handleMessage@resource://gre/modules/workers/PromiseWorker.js:122:16
@resource:///modules/sessionstore/SessionWorker.js:30:41

*************************

These messages can be explained as follows:

* If sanitization has failed during shutdown, it attempts again to
  sanitize during startup. This happens more often than it used to,
  because of 1/ startup bug fixes in bug 1089695; 2/ new shutdown bugs
  most likely also added by or around bug 1089695.

* Sanitization during startup doesn't wait until Session Restore has
  properly started to sanitize the session. So sanitization of Session
  Restore file fails. This has probably always been the case, except
  we never noticed.

* For some reason I do not understand, it attempts to sanitize several
  times.

* I suspect that this can cause problems during startup, as
  sanitization and Session Restore race to use/remove the files of
  Session Restore.

This patch makes sure that SessionFile.wipe() waits until
initialization of SessionFile is complete before proceeding.
This commit is contained in:
David Rajchenbach-Teller 2016-02-02 12:56:11 +01:00
parent b4dbb62bea
commit 259ea7a423

View File

@ -39,6 +39,8 @@ Cu.import("resource://gre/modules/Preferences.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "console",
"resource://gre/modules/Console.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "PromiseUtils",
"resource://gre/modules/PromiseUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "RunState",
"resource:///modules/sessionstore/RunState.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "TelemetryStopwatch",
@ -179,6 +181,10 @@ var SessionFileInternal = {
// Used for error-reporting.
_hasWriteEverSucceeded: false,
// Resolved once initialization is complete.
// The promise never rejects.
_deferredInitialized: PromiseUtils.defer(),
// The ID of the latest version of Gecko for which we have an upgrade backup
// or |undefined| if no upgrade backup was ever written.
get latestUpgradeBackupID() {
@ -255,12 +261,14 @@ var SessionFileInternal = {
// Initialize the worker to let it handle backups and also
// as a workaround for bug 964531.
SessionWorker.post("init", [result.origin, this.Paths, {
let initialized = SessionWorker.post("init", [result.origin, this.Paths, {
maxUpgradeBackups: Preferences.get(PREF_MAX_UPGRADE_BACKUPS, 3),
maxSerializeBack: Preferences.get(PREF_MAX_SERIALIZE_BACK, 10),
maxSerializeForward: Preferences.get(PREF_MAX_SERIALIZE_FWD, -1)
}]);
initialized.catch(Promise.reject).then(() => this._deferredInitialized.resolve());
return result;
}),
@ -281,7 +289,7 @@ var SessionFileInternal = {
!sessionStartup.isAutomaticRestoreEnabled();
let options = {isFinalWrite, performShutdownCleanup};
let promise = SessionWorker.post("write", [aData, options]);
let promise = this._deferredInitialized.promise.then(() => SessionWorker.post("write", [aData, options]));
// Wait until the write is done.
promise = promise.then(msg => {
@ -328,7 +336,7 @@ var SessionFileInternal = {
},
wipe: function () {
return SessionWorker.post("wipe");
return this._deferredInitialized.promise.then(() => SessionWorker.post("wipe"));
},
_recordTelemetry: function(telemetry) {