mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 965137 - Synchronously write session on application-background. r=mfinkle
This commit is contained in:
parent
e1357d14ef
commit
d65b69f986
@ -43,6 +43,7 @@ SessionStore.prototype = {
|
|||||||
_lastSaveTime: 0,
|
_lastSaveTime: 0,
|
||||||
_interval: 10000,
|
_interval: 10000,
|
||||||
_maxTabsUndo: 1,
|
_maxTabsUndo: 1,
|
||||||
|
_pendingWrite: 0,
|
||||||
|
|
||||||
init: function ss_init() {
|
init: function ss_init() {
|
||||||
// Get file references
|
// Get file references
|
||||||
@ -77,6 +78,7 @@ SessionStore.prototype = {
|
|||||||
observerService.addObserver(this, "domwindowclosed", true);
|
observerService.addObserver(this, "domwindowclosed", true);
|
||||||
observerService.addObserver(this, "browser:purge-session-history", true);
|
observerService.addObserver(this, "browser:purge-session-history", true);
|
||||||
observerService.addObserver(this, "Session:Restore", true);
|
observerService.addObserver(this, "Session:Restore", true);
|
||||||
|
observerService.addObserver(this, "application-background", true);
|
||||||
break;
|
break;
|
||||||
case "final-ui-startup":
|
case "final-ui-startup":
|
||||||
observerService.removeObserver(this, "final-ui-startup");
|
observerService.removeObserver(this, "final-ui-startup");
|
||||||
@ -102,7 +104,7 @@ SessionStore.prototype = {
|
|||||||
|
|
||||||
if (this._loadState == STATE_RUNNING) {
|
if (this._loadState == STATE_RUNNING) {
|
||||||
// Save the purged state immediately
|
// Save the purged state immediately
|
||||||
this.saveStateNow();
|
this.saveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
Services.obs.notifyObservers(null, "sessionstore-state-purge-complete", "");
|
Services.obs.notifyObservers(null, "sessionstore-state-purge-complete", "");
|
||||||
@ -110,7 +112,9 @@ SessionStore.prototype = {
|
|||||||
case "timer-callback":
|
case "timer-callback":
|
||||||
// Timer call back for delayed saving
|
// Timer call back for delayed saving
|
||||||
this._saveTimer = null;
|
this._saveTimer = null;
|
||||||
this.saveState();
|
if (this._pendingWrite) {
|
||||||
|
this.saveState();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case "Session:Restore": {
|
case "Session:Restore": {
|
||||||
if (aData) {
|
if (aData) {
|
||||||
@ -143,6 +147,13 @@ SessionStore.prototype = {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case "application-background":
|
||||||
|
// We receive this notification when Android's onPause callback is
|
||||||
|
// executed. After onPause, the application may be terminated at any
|
||||||
|
// point without notice; therefore, we must synchronously write out any
|
||||||
|
// pending save state to ensure that this data does not get lost.
|
||||||
|
this.flushPendingState();
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -306,7 +317,7 @@ SessionStore.prototype = {
|
|||||||
|
|
||||||
delete aBrowser.__SS_data;
|
delete aBrowser.__SS_data;
|
||||||
this._collectTabData(aWindow, aBrowser, data);
|
this._collectTabData(aWindow, aBrowser, data);
|
||||||
this.saveStateNow();
|
this.saveState();
|
||||||
}
|
}
|
||||||
|
|
||||||
this._updateCrashReportURL(aWindow);
|
this._updateCrashReportURL(aWindow);
|
||||||
@ -342,6 +353,7 @@ SessionStore.prototype = {
|
|||||||
// If we have to wait, set a timer, otherwise saveState directly
|
// If we have to wait, set a timer, otherwise saveState directly
|
||||||
let delay = Math.max(minimalDelay, 2000);
|
let delay = Math.max(minimalDelay, 2000);
|
||||||
if (delay > 0) {
|
if (delay > 0) {
|
||||||
|
this._pendingWrite++;
|
||||||
this._saveTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
this._saveTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
|
||||||
this._saveTimer.init(this, delay, Ci.nsITimer.TYPE_ONE_SHOT);
|
this._saveTimer.init(this, delay, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||||
} else {
|
} else {
|
||||||
@ -350,16 +362,25 @@ SessionStore.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
saveStateNow: function ss_saveStateNow() {
|
saveState: function ss_saveState() {
|
||||||
|
this._pendingWrite++;
|
||||||
|
this._saveState(true);
|
||||||
|
},
|
||||||
|
|
||||||
|
// Immediately and synchronously writes any pending state to disk.
|
||||||
|
flushPendingState: function ss_flushPendingState() {
|
||||||
|
if (this._pendingWrite) {
|
||||||
|
this._saveState(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_saveState: function ss_saveState(aAsync) {
|
||||||
// Kill any queued timer and save immediately
|
// Kill any queued timer and save immediately
|
||||||
if (this._saveTimer) {
|
if (this._saveTimer) {
|
||||||
this._saveTimer.cancel();
|
this._saveTimer.cancel();
|
||||||
this._saveTimer = null;
|
this._saveTimer = null;
|
||||||
}
|
}
|
||||||
this.saveState();
|
|
||||||
},
|
|
||||||
|
|
||||||
saveState: function ss_saveState() {
|
|
||||||
let data = this._getCurrentState();
|
let data = this._getCurrentState();
|
||||||
let normalData = { windows: [] };
|
let normalData = { windows: [] };
|
||||||
let privateData = { windows: [] };
|
let privateData = { windows: [] };
|
||||||
@ -388,7 +409,7 @@ SessionStore.prototype = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write only non-private data to disk
|
// Write only non-private data to disk
|
||||||
this._writeFile(this._sessionFile, JSON.stringify(normalData));
|
this._writeFile(this._sessionFile, JSON.stringify(normalData), aAsync);
|
||||||
|
|
||||||
// If we have private data, send it to Java; otherwise, send null to
|
// If we have private data, send it to Java; otherwise, send null to
|
||||||
// indicate that there is no private data
|
// indicate that there is no private data
|
||||||
@ -464,7 +485,7 @@ SessionStore.prototype = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_writeFile: function ss_writeFile(aFile, aData) {
|
_writeFile: function ss_writeFile(aFile, aData, aAsync) {
|
||||||
let stateString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
let stateString = Cc["@mozilla.org/supports-string;1"].createInstance(Ci.nsISupportsString);
|
||||||
stateString.data = aData;
|
stateString.data = aData;
|
||||||
Services.obs.notifyObservers(stateString, "sessionstore-state-write", "");
|
Services.obs.notifyObservers(stateString, "sessionstore-state-write", "");
|
||||||
@ -473,11 +494,28 @@ SessionStore.prototype = {
|
|||||||
if (!stateString.data)
|
if (!stateString.data)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Asynchronously copy the data to the file.
|
if (aAsync) {
|
||||||
let array = new TextEncoder().encode(aData);
|
let array = new TextEncoder().encode(aData);
|
||||||
OS.File.writeAtomic(aFile.path, array, { tmpPath: aFile.path + ".tmp" }).then(function onSuccess() {
|
let pendingWrite = this._pendingWrite;
|
||||||
Services.obs.notifyObservers(null, "sessionstore-state-write-complete", "");
|
OS.File.writeAtomic(aFile.path, array, { tmpPath: aFile.path + ".tmp" }).then(function onSuccess() {
|
||||||
});
|
// Make sure this._pendingWrite is the same value it was before we
|
||||||
|
// fired off the async write. If the count is different, another write
|
||||||
|
// is pending, so we shouldn't reset this._pendingWrite yet.
|
||||||
|
if (pendingWrite === this._pendingWrite)
|
||||||
|
this._pendingWrite = 0;
|
||||||
|
Services.obs.notifyObservers(null, "sessionstore-state-write-complete", "");
|
||||||
|
}.bind(this));
|
||||||
|
} else {
|
||||||
|
this._pendingWrite = 0;
|
||||||
|
let foStream = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||||
|
createInstance(Ci.nsIFileOutputStream);
|
||||||
|
foStream.init(aFile, 0x02 | 0x08 | 0x20, 0666, 0);
|
||||||
|
let converter = Cc["@mozilla.org/intl/converter-output-stream;1"].
|
||||||
|
createInstance(Ci.nsIConverterOutputStream);
|
||||||
|
converter.init(foStream, "UTF-8", 0, 0);
|
||||||
|
converter.writeString(aData);
|
||||||
|
converter.close();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_updateCrashReportURL: function ss_updateCrashReportURL(aWindow) {
|
_updateCrashReportURL: function ss_updateCrashReportURL(aWindow) {
|
||||||
|
Loading…
Reference in New Issue
Block a user