Bug 1458119: Part 1: Use idleDispatch to be independent from a content window. r=mikedeboer draft
authorAdam Gashlin <agashlin@mozilla.com>
Sun, 27 May 2018 11:21:49 -0700
changeset 803170 8886a199416e5a526faf6a0895a71fdc9752d555
parent 802711 9900cebb1f9000bd05731ba67736b7c51f7eb812
child 803171 b820681ff367151c431a53739dd79a19ba1519af
child 804232 b98904ebf9f02b69e5e435a2600a50e2e5d055b2
child 804867 465f0c88c9d581fa6805c01c98c819a4a111da64
child 805316 b73663c5dfd212bb713f3699bd1163eaaa7f3a36
push id112035
push userbmo:agashlin@mozilla.com
push dateFri, 01 Jun 2018 23:46:59 +0000
reviewersmikedeboer
bugs1458119
milestone62.0a1
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
browser/components/sessionstore/content/content-sessionStore.js
--- 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
    */