Bug 1458119: Part 1: Use idleDispatch to be independent from a content window. r=mikedeboer
When using content.requestIdleCallback(), the idle callback may not be
run by the time the content goes away, resulting in a missed send.
ChromeUtils.idleDispatch does not have this issue.
MozReview-Commit-ID: DdGMr6j80sZ
--- a/browser/components/sessionstore/content/content-sessionStore.js
+++ b/browser/components/sessionstore/content/content-sessionStore.js
@@ -729,20 +729,20 @@ var MessageQueue = {
/**
* Whether or not sending batched messages on a timer is disabled. This should
* only be used for debugging or testing. If you need to access this value,
* you should probably use the timeoutDisabled getter.
*/
_timeoutDisabled: false,
/**
- * The idle callback ID referencing an active idle callback. When no idle
- * callback is pending, this is null.
- * */
- _idleCallbackID: null,
+ * True if there is already a send pending idle dispatch, set to prevent
+ * scheduling more than one. If false there may or may not be one scheduled.
+ */
+ _idleScheduled: false,
/**
* True if batched messages are not being fired on a timer. This should only
* ever be true when debugging or during tests.
*/
get timeoutDisabled() {
return this._timeoutDisabled;
},
@@ -777,20 +777,17 @@ var MessageQueue = {
Services.prefs.removeObserver(PREF_INTERVAL, this);
this.cleanupTimers();
},
/**
* Cleanup pending idle callback and timer.
*/
cleanupTimers() {
- if (this._idleCallbackID) {
- content.cancelIdleCallback(this._idleCallbackID);
- this._idleCallbackID = null;
- }
+ this._idleScheduled = false;
if (this._timeout) {
clearTimeout(this._timeout);
this._timeout = null;
}
},
observe(subject, topic, data) {
if (topic == "nsPref:changed") {
@@ -832,36 +829,36 @@ var MessageQueue = {
},
/**
* Sends queued data when the remaining idle time is enough or waiting too
* long; otherwise, request an idle time again. If the |deadline| is not
* given, this function is going to schedule the first request.
*
* @param deadline (object)
- * An IdleDeadline object passed by requestIdleCallback().
+ * An IdleDeadline object passed by idleDispatch().
*/
sendWhenIdle(deadline) {
if (!content) {
// The frameloader is being torn down. Nothing more to do.
return;
}
if (deadline) {
if (deadline.didTimeout || deadline.timeRemaining() > MessageQueue.NEEDED_IDLE_PERIOD_MS) {
MessageQueue.send();
return;
}
- } else if (MessageQueue._idleCallbackID) {
+ } else if (MessageQueue._idleScheduled) {
// Bail out if there's a pending run.
return;
}
- MessageQueue._idleCallbackID =
- content.requestIdleCallback(MessageQueue.sendWhenIdle, {timeout: MessageQueue._timeoutWaitIdlePeriodMs});
- },
+ ChromeUtils.idleDispatch(MessageQueue.sendWhenIdle, {timeout: MessageQueue._timeoutWaitIdlePeriodMs});
+ MessageQueue._idleScheduled = true;
+ },
/**
* Sends queued data to the chrome process.
*
* @param options (object)
* {flushID: 123} to specify that this is a flush
* {isFinal: true} to signal this is the final message sent on unload
*/