LCOV - code coverage report
Current view: top level - dom/base - TimeoutManager.h (source / functions) Hit Total Coverage
Test: output.info Lines: 25 34 73.5 %
Date: 2017-07-14 16:53:18 Functions: 13 23 56.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       5             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_dom_TimeoutManager_h__
       8             : #define mozilla_dom_TimeoutManager_h__
       9             : 
      10             : #include "mozilla/dom/Timeout.h"
      11             : #include "nsTArray.h"
      12             : 
      13             : class nsIEventTarget;
      14             : class nsITimeoutHandler;
      15             : class nsGlobalWindow;
      16             : 
      17             : namespace mozilla {
      18             : namespace dom {
      19             : 
      20             : class OrderedTimeoutIterator;
      21             : class TimeoutExecutor;
      22             : 
      23             : // This class manages the timeouts in a Window's setTimeout/setInterval pool.
      24             : class TimeoutManager final
      25             : {
      26             : public:
      27             :   explicit TimeoutManager(nsGlobalWindow& aWindow);
      28             :   ~TimeoutManager();
      29             :   TimeoutManager(const TimeoutManager& rhs) = delete;
      30             :   void operator=(const TimeoutManager& rhs) = delete;
      31             : 
      32             :   bool IsRunningTimeout() const;
      33             : 
      34           8 :   static uint32_t GetNestingLevel() { return sNestingLevel; }
      35          16 :   static void SetNestingLevel(uint32_t aLevel) { sNestingLevel = aLevel; }
      36             : 
      37           0 :   bool HasTimeouts() const
      38             :   {
      39           0 :     return !mNormalTimeouts.IsEmpty() ||
      40           0 :            !mTrackingTimeouts.IsEmpty();
      41             :   }
      42             : 
      43             :   nsresult SetTimeout(nsITimeoutHandler* aHandler,
      44             :                       int32_t interval, bool aIsInterval,
      45             :                       mozilla::dom::Timeout::Reason aReason,
      46             :                       int32_t* aReturn);
      47             :   void ClearTimeout(int32_t aTimerId,
      48             :                     mozilla::dom::Timeout::Reason aReason);
      49             : 
      50             :   // The timeout implementation functions.
      51             :   void RunTimeout(const TimeStamp& aNow, const TimeStamp& aTargetDeadline);
      52             : 
      53             :   void ClearAllTimeouts();
      54             :   uint32_t GetTimeoutId(mozilla::dom::Timeout::Reason aReason);
      55             : 
      56             :   TimeDuration CalculateDelay(Timeout* aTimeout) const;
      57             : 
      58             :   // aTimeout is the timeout that we're about to start running.  This function
      59             :   // returns the current timeout.
      60             :   mozilla::dom::Timeout* BeginRunningTimeout(mozilla::dom::Timeout* aTimeout);
      61             :   // aTimeout is the last running timeout.
      62             :   void EndRunningTimeout(mozilla::dom::Timeout* aTimeout);
      63             : 
      64             :   void UnmarkGrayTimers();
      65             : 
      66             :   // These four methods are intended to be called from the corresponding methods
      67             :   // on nsGlobalWindow.
      68             :   void Suspend();
      69             :   void Resume();
      70             :   void Freeze();
      71             :   void Thaw();
      72             : 
      73             :   // This should be called by nsGlobalWindow when the window might have moved
      74             :   // to the background or foreground.
      75             :   void UpdateBackgroundState();
      76             : 
      77             :   // Initialize TimeoutManager before the first time it is accessed.
      78             :   static void Initialize();
      79             : 
      80             :   // Exposed only for testing
      81             :   bool IsTimeoutTracking(uint32_t aTimeoutId);
      82             : 
      83             :   // The document finished loading
      84             :   void OnDocumentLoaded();
      85             :   void StartThrottlingTimeouts();
      86             : 
      87             :   // Run some code for each Timeout in our list.  Note that this function
      88             :   // doesn't guarantee that Timeouts are iterated in any particular order.
      89             :   template <class Callable>
      90           4 :   void ForEachUnorderedTimeout(Callable c)
      91             :   {
      92           4 :     mNormalTimeouts.ForEach(c);
      93           4 :     mTrackingTimeouts.ForEach(c);
      94           4 :   }
      95             : 
      96             :   // Run some code for each Timeout in our list, but let the callback cancel the
      97             :   // iteration by returning true.  Note that this function doesn't guarantee
      98             :   // that Timeouts are iterated in any particular order.
      99             :   template <class Callable>
     100           2 :   void ForEachUnorderedTimeoutAbortable(Callable c)
     101             :   {
     102           2 :     if (!mNormalTimeouts.ForEachAbortable(c)) {
     103           0 :       mTrackingTimeouts.ForEachAbortable(c);
     104             :     }
     105           2 :   }
     106             : 
     107             :   void BeginSyncOperation();
     108             :   void EndSyncOperation();
     109             : 
     110             :   nsIEventTarget*
     111             :   EventTarget();
     112             : 
     113             :   static const uint32_t InvalidFiringId;
     114             : 
     115             : private:
     116             :   void MaybeStartThrottleTimeout();
     117             : 
     118             :   // Return true if |aTimeout| needs to be reinserted into the timeout list.
     119             :   bool RescheduleTimeout(mozilla::dom::Timeout* aTimeout,
     120             :                          const TimeStamp& aLastCallbackTime,
     121             :                          const TimeStamp& aCurrentNow);
     122             : 
     123             :   bool IsBackground() const;
     124             : 
     125             :   bool IsActive() const;
     126             : 
     127             :   uint32_t
     128             :   CreateFiringId();
     129             : 
     130             :   void
     131             :   DestroyFiringId(uint32_t aFiringId);
     132             : 
     133             :   bool
     134             :   IsValidFiringId(uint32_t aFiringId) const;
     135             : 
     136             :   bool
     137             :   IsInvalidFiringId(uint32_t aFiringId) const;
     138             : 
     139             :   TimeDuration
     140             :   MinSchedulingDelay() const;
     141             : 
     142             :   nsresult MaybeSchedule(const TimeStamp& aWhen,
     143           0 :                          const TimeStamp& aNow = TimeStamp::Now());
     144             : 
     145             :   void RecordExecution(Timeout* aRunningTimeout,
     146             :                        Timeout* aTimeout);
     147             : 
     148             :   void UpdateBudget(const TimeStamp& aNow,
     149             :                     const TimeDuration& aDuration = TimeDuration());
     150             : 
     151             : private:
     152           0 :   struct Timeouts {
     153          14 :     explicit Timeouts(const TimeoutManager& aManager)
     154          14 :       : mManager(aManager)
     155             :     {
     156          14 :     }
     157             : 
     158             :     // Insert aTimeout into the list, before all timeouts that would
     159             :     // fire after it, but no earlier than the last Timeout with a
     160             :     // valid FiringId.
     161             :     enum class SortBy
     162             :     {
     163             :       TimeRemaining,
     164             :       TimeWhen
     165             :     };
     166             :     void Insert(mozilla::dom::Timeout* aTimeout, SortBy aSortBy);
     167             : 
     168             :     const Timeout* GetFirst() const { return mTimeoutList.getFirst(); }
     169          10 :     Timeout* GetFirst() { return mTimeoutList.getFirst(); }
     170             :     const Timeout* GetLast() const { return mTimeoutList.getLast(); }
     171          13 :     Timeout* GetLast() { return mTimeoutList.getLast(); }
     172           0 :     bool IsEmpty() const { return mTimeoutList.isEmpty(); }
     173           4 :     void InsertFront(Timeout* aTimeout) { mTimeoutList.insertFront(aTimeout); }
     174           6 :     void Clear() { mTimeoutList.clear(); }
     175             : 
     176             :     template <class Callable>
     177           8 :     void ForEach(Callable c)
     178             :     {
     179          14 :       for (Timeout* timeout = GetFirst();
     180             :            timeout;
     181           6 :            timeout = timeout->getNext()) {
     182           6 :         c(timeout);
     183             :       }
     184           8 :     }
     185             : 
     186             :     // Returns true when a callback aborts iteration.
     187             :     template <class Callable>
     188           2 :     bool ForEachAbortable(Callable c)
     189             :     {
     190           2 :       for (Timeout* timeout = GetFirst();
     191             :            timeout;
     192           0 :            timeout = timeout->getNext()) {
     193           2 :         if (c(timeout)) {
     194           2 :           return true;
     195             :         }
     196             :       }
     197           0 :       return false;
     198             :     }
     199             : 
     200             :     friend class OrderedTimeoutIterator;
     201             : 
     202             :   private:
     203             :     // The TimeoutManager that owns this Timeouts structure.  This is
     204             :     // mainly used to call state inspecting methods like IsValidFiringId().
     205             :     const TimeoutManager&     mManager;
     206             : 
     207             :     typedef mozilla::LinkedList<RefPtr<Timeout>> TimeoutList;
     208             : 
     209             :     // mTimeoutList is generally sorted by mWhen, but new values are always
     210             :     // inserted after any Timeouts with a valid FiringId.
     211             :     TimeoutList               mTimeoutList;
     212             :   };
     213             : 
     214             :   friend class OrderedTimeoutIterator;
     215             : 
     216             :   // Each nsGlobalWindow object has a TimeoutManager member.  This reference
     217             :   // points to that holder object.
     218             :   nsGlobalWindow&             mWindow;
     219             :   // The executor is specific to the nsGlobalWindow/TimeoutManager, but it
     220             :   // can live past the destruction of the window if its scheduled.  Therefore
     221             :   // it must be a separate ref-counted object.
     222             :   RefPtr<TimeoutExecutor>     mExecutor;
     223             :   // The list of timeouts coming from non-tracking scripts.
     224             :   Timeouts                    mNormalTimeouts;
     225             :   // The list of timeouts coming from scripts on the tracking protection list.
     226             :   Timeouts                    mTrackingTimeouts;
     227             :   uint32_t                    mTimeoutIdCounter;
     228             :   uint32_t                    mNextFiringId;
     229             :   AutoTArray<uint32_t, 2>     mFiringIdStack;
     230             :   mozilla::dom::Timeout*      mRunningTimeout;
     231             : 
     232             :    // The current idle request callback timeout handle
     233             :   uint32_t                    mIdleCallbackTimeoutCounter;
     234             : 
     235             :   nsCOMPtr<nsITimer>          mThrottleTimeoutsTimer;
     236             :   mozilla::TimeStamp          mLastBudgetUpdate;
     237             :   mozilla::TimeDuration       mExecutionBudget;
     238             : 
     239             :   bool                        mThrottleTimeouts;
     240             :   bool                        mThrottleTrackingTimeouts;
     241             :   bool                        mBudgetThrottleTimeouts;
     242             : 
     243             :   static uint32_t             sNestingLevel;
     244             : };
     245             : 
     246             : }
     247             : }
     248             : 
     249             : #endif

Generated by: LCOV version 1.13