DXR is a code search and navigation tool aimed at making sense of large projects. It supports full-text and regex searches as well as structural queries.

Mercurial (409f3966645a)

VCS Links

Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
 * You can obtain one at http://mozilla.org/MPL/2.0/. */

"use strict";

var EXPORTED_SYMBOLS = ["SchedulePressure"];

ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
ChromeUtils.defineModuleGetter(this, "TelemetryStopwatch",
  "resource://gre/modules/TelemetryStopwatch.jsm");
XPCOMUtils.defineLazyPreferenceGetter(this, "SCHEDULE_PRESSURE_ENABLED",
  "browser.schedulePressure.enabled", true);
XPCOMUtils.defineLazyPreferenceGetter(this, "TIMEOUT_AMOUNT",
  "browser.schedulePressure.timeoutMs", 300);

/**
 * The SchedulePressure object provides the ability to alter
 * the behavior of a program based on the idle activity of the
 * host machine.
 */
var SchedulePressure = {
  _idleCallbackWeakMap: new WeakMap(),
  _setTimeoutWeakMap: new WeakMap(),
  _telemetryCallbackWeakMap: new WeakMap(),

  _createTimeoutFn(window, callbackFn) {
    return () => {
      if (window.closed) {
        TelemetryStopwatch.cancel("FX_SCHEDULE_PRESSURE_IDLE_SAMPLE_MS", window);
        this._telemetryCallbackWeakMap.delete(window);
        return;
      }
      let nextCallbackId = window.requestIdleCallback(callbackFn, {timeout: TIMEOUT_AMOUNT});
      this._idleCallbackWeakMap.set(window, nextCallbackId);

      // Don't create another timeout-less idle callback if the first
      // one hasn't completed yet.
      if (!this._telemetryCallbackWeakMap.has(window) &&
          TelemetryStopwatch.start("FX_SCHEDULE_PRESSURE_IDLE_SAMPLE_MS", window)) {
        let telemetryCallbackId = window.requestIdleCallback(() => {
          TelemetryStopwatch.finish("FX_SCHEDULE_PRESSURE_IDLE_SAMPLE_MS", window);
          this._telemetryCallbackWeakMap.delete(window);
        });
        this._telemetryCallbackWeakMap.set(window, telemetryCallbackId);
      }
    };
  },

  /**
   * Starts an interval timeout that periodically waits for
   * an idle callback. If the idle callback fails to get called
   * within the timeout specified by TIMEOUT_AMOUNT, the
   * highPressureFn callback will get called. Otherwise the
   * lowPressureFn callback will get called.
   *
   * @param  window
   *         The DOM window of the requestee.
   * @param  options
   *           highPressureFn
   *           A function that will be called when the idle callback
   *           fails to be called within the time specified by TIMEOUT_AMOUNT.
   *           Returning an object with property of `continueMonitoring` set
   *           to `false` will prevent further monitoring.
   *           lowPressureFn
   *           A function that will be called when the idle callback
   *           gets called within the time specified by TIMEOUT_AMOUNT.
   *           Returning an object with property of `continueMonitoring` set
   *           to `false` will prevent further monitoring.
   */
  startMonitoring(window, {highPressureFn, lowPressureFn}) {
    if (!SCHEDULE_PRESSURE_ENABLED ||
        this._setTimeoutWeakMap.has(window) ||
        this._idleCallbackWeakMap.has(window)) {
      return;
    }

    let callbackFn = idleDeadline => {
      if (window.closed) {
        return;
      }

      let result;
      if (idleDeadline.didTimeout) {
        try {
          result = highPressureFn();
        } catch (ex) {}
      } else {
        try {
          result = lowPressureFn();
        } catch (ex) {}
      }

      if (result && !result.continueMonitoring) {
        return;
      }

      this._setTimeoutWeakMap.set(window,
        window.setTimeout(this._createTimeoutFn(window, callbackFn), TIMEOUT_AMOUNT));
    };

    this._setTimeoutWeakMap.set(window,
      window.setTimeout(this._createTimeoutFn(window, callbackFn), TIMEOUT_AMOUNT));
  },

  /**
   * Stops the interval timeout that periodically waits for
   * an idle callback.
   *
   * @param  window
   *         The DOM window of the requestee.
   */
  stopMonitoring(window) {
    function removeFromMapAndCancelTimeout(map, cancelFn) {
      if (map.has(window)) {
        cancelFn(map.get(window));
        map.delete(window);
      }
    }

    TelemetryStopwatch.cancel("FX_SCHEDULE_PRESSURE_IDLE_SAMPLE_MS", window);
    removeFromMapAndCancelTimeout(this._setTimeoutWeakMap, window.clearTimeout);
    removeFromMapAndCancelTimeout(this._idleCallbackWeakMap, window.cancelIdleCallback);
    removeFromMapAndCancelTimeout(this._telemetryCallbackWeakMap, window.cancelIdleCallback);
  },
};