--- a/browser/components/sessionstore/SessionFile.jsm
+++ b/browser/components/sessionstore/SessionFile.jsm
@@ -34,16 +34,18 @@ Cu.import("resource://gre/modules/Servic
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource://gre/modules/Promise.jsm");
Cu.import("resource://gre/modules/AsyncShutdown.jsm");
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",
"resource://gre/modules/TelemetryStopwatch.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "Task",
"resource://gre/modules/Task.jsm");
XPCOMUtils.defineLazyServiceGetter(this, "Telemetry",
"@mozilla.org/base/telemetry;1", "nsITelemetry");
@@ -174,16 +176,20 @@ var SessionFileInternal = {
return order;
},
}),
// `true` once `write` has succeeded at last once.
// 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() {
try {
return Services.prefs.getCharPref(PREF_UPGRADE_BACKUP);
} catch (ex) {
return undefined;
}
@@ -250,22 +256,24 @@ var SessionFileInternal = {
parsed: null
};
}
result.noFilesFound = noFilesFound;
// 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;
}),
write: function (aData) {
if (RunState.isClosed) {
return Promise.reject(new Error("SessionFile is closed"));
}
@@ -276,17 +284,17 @@ var SessionFileInternal = {
isFinalWrite = true;
RunState.setClosed();
}
let performShutdownCleanup = isFinalWrite &&
!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 => {
// Record how long the write took.
this._recordTelemetry(msg.telemetry);
this._hasWriteEverSucceeded = true;
if (msg.result.upgradeBackup) {
// We have just completed a backup-on-upgrade, store the information
@@ -323,17 +331,17 @@ var SessionFileInternal = {
if (isFinalWrite) {
Services.obs.notifyObservers(null, "sessionstore-final-state-write-complete", "");
}
});
},
wipe: function () {
- return SessionWorker.post("wipe");
+ return this._deferredInitialized.promise.then(() => SessionWorker.post("wipe"));
},
_recordTelemetry: function(telemetry) {
for (let id of Object.keys(telemetry)){
let value = telemetry[id];
let samples = [];
if (Array.isArray(value)) {
samples.push(...value);