LCOV - code coverage report
Current view: top level - xpcom/threads - LazyIdleThread.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 2 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 1 0.0 %
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_lazyidlethread_h__
       8             : #define mozilla_lazyidlethread_h__
       9             : 
      10             : #ifndef MOZILLA_INTERNAL_API
      11             : #error "This header is only usable from within libxul (MOZILLA_INTERNAL_API)."
      12             : #endif
      13             : 
      14             : #include "nsIObserver.h"
      15             : #include "nsIThreadInternal.h"
      16             : #include "nsITimer.h"
      17             : 
      18             : #include "mozilla/Mutex.h"
      19             : #include "nsCOMPtr.h"
      20             : #include "nsTArray.h"
      21             : #include "nsString.h"
      22             : #include "mozilla/Attributes.h"
      23             : 
      24             : #define IDLE_THREAD_TOPIC "thread-shutting-down"
      25             : 
      26             : namespace mozilla {
      27             : 
      28             : /**
      29             :  * This class provides a basic event target that creates its thread lazily and
      30             :  * destroys its thread after a period of inactivity. It may be created on any
      31             :  * thread but it may only be used from the thread on which it is created. If it
      32             :  * is created on the main thread then it will automatically join its thread on
      33             :  * XPCOM shutdown using the Observer Service.
      34             :  */
      35             : class LazyIdleThread final
      36             :   : public nsIThread
      37             :   , public nsITimerCallback
      38             :   , public nsIThreadObserver
      39             :   , public nsIObserver
      40             : {
      41             : public:
      42             :   NS_DECL_THREADSAFE_ISUPPORTS
      43             :   NS_DECL_NSIEVENTTARGET_FULL
      44             :   NS_DECL_NSITHREAD
      45             :   NS_DECL_NSITIMERCALLBACK
      46             :   NS_DECL_NSITHREADOBSERVER
      47             :   NS_DECL_NSIOBSERVER
      48             : 
      49             :   enum ShutdownMethod
      50             :   {
      51             :     AutomaticShutdown = 0,
      52             :     ManualShutdown
      53             :   };
      54             : 
      55             :   /**
      56             :    * Create a new LazyIdleThread that will destroy its thread after the given
      57             :    * number of milliseconds.
      58             :    */
      59             :   LazyIdleThread(uint32_t aIdleTimeoutMS,
      60             :                  const nsACString& aName,
      61             :                  ShutdownMethod aShutdownMethod = AutomaticShutdown,
      62             :                  nsIObserver* aIdleObserver = nullptr);
      63             : 
      64             :   /**
      65             :    * Add an observer that will be notified when the thread is idle and about to
      66             :    * be shut down. The aSubject argument can be QueryInterface'd to an nsIThread
      67             :    * that can be used to post cleanup events. The aTopic argument will be
      68             :    * IDLE_THREAD_TOPIC, and aData will be null. The LazyIdleThread does not add
      69             :    * a reference to the observer to avoid circular references as it is assumed
      70             :    * to be the owner. It is the caller's responsibility to clear this observer
      71             :    * if the pointer becomes invalid.
      72             :    */
      73             :   void SetWeakIdleObserver(nsIObserver* aObserver);
      74             : 
      75             :   /**
      76             :    * Disable the idle timeout for this thread. No effect if the timeout is
      77             :    * already disabled.
      78             :    */
      79             :   void DisableIdleTimeout();
      80             : 
      81             :   /**
      82             :    * Enable the idle timeout. No effect if the timeout is already enabled.
      83             :    */
      84             :   void EnableIdleTimeout();
      85             : 
      86             : private:
      87             :   /**
      88             :    * Calls Shutdown().
      89             :    */
      90             :   ~LazyIdleThread();
      91             : 
      92             :   /**
      93             :    * Called just before dispatching to mThread.
      94             :    */
      95             :   void PreDispatch();
      96             : 
      97             :   /**
      98             :    * Makes sure a valid thread lives in mThread.
      99             :    */
     100             :   nsresult EnsureThread();
     101             : 
     102             :   /**
     103             :    * Called on mThread to set up the thread observer.
     104             :    */
     105             :   void InitThread();
     106             : 
     107             :   /**
     108             :    * Called on mThread to clean up the thread observer.
     109             :    */
     110             :   void CleanupThread();
     111             : 
     112             :   /**
     113             :    * Called on the main thread when mThread believes itself to be idle. Sets up
     114             :    * the idle timer.
     115             :    */
     116             :   void ScheduleTimer();
     117             : 
     118             :   /**
     119             :    * Called when we are shutting down mThread.
     120             :    */
     121             :   nsresult ShutdownThread();
     122             : 
     123             :   /**
     124             :    * Deletes this object. Used to delay calling mThread->Shutdown() during the
     125             :    * final release (during a GC, for instance).
     126             :    */
     127             :   void SelfDestruct();
     128             : 
     129             :   /**
     130             :    * Returns true if events should be queued rather than immediately dispatched
     131             :    * to mThread. Currently only happens when the thread is shutting down.
     132             :    */
     133           0 :   bool UseRunnableQueue()
     134             :   {
     135           0 :     return !!mQueuedRunnables;
     136             :   }
     137             : 
     138             :   /**
     139             :    * Protects data that is accessed on both threads.
     140             :    */
     141             :   mozilla::Mutex mMutex;
     142             : 
     143             :   /**
     144             :    * Touched on both threads but set before mThread is created. Used to direct
     145             :    * timer events to the owning thread.
     146             :    */
     147             :   nsCOMPtr<nsISerialEventTarget> mOwningEventTarget;
     148             : 
     149             :   /**
     150             :    * Only accessed on the owning thread. Set by EnsureThread().
     151             :    */
     152             :   nsCOMPtr<nsIThread> mThread;
     153             : 
     154             :   /**
     155             :    * Protected by mMutex. Created when mThread has no pending events and fired
     156             :    * at mOwningThread. Any thread that dispatches to mThread will take ownership
     157             :    * of the timer and fire a separate cancel event to the owning thread.
     158             :    */
     159             :   nsCOMPtr<nsITimer> mIdleTimer;
     160             : 
     161             :   /**
     162             :    * Idle observer. Called when the thread is about to be shut down. Released
     163             :    * only when Shutdown() is called.
     164             :    */
     165             :   nsIObserver* MOZ_UNSAFE_REF("See the documentation for SetWeakIdleObserver for "
     166             :                               "how the owner of LazyIdleThread should manage the "
     167             :                               "lifetime information of this field") mIdleObserver;
     168             : 
     169             :   /**
     170             :    * Temporary storage for events that happen to be dispatched while we're in
     171             :    * the process of shutting down our real thread.
     172             :    */
     173             :   nsTArray<nsCOMPtr<nsIRunnable>>* mQueuedRunnables;
     174             : 
     175             :   /**
     176             :    * The number of milliseconds a thread should be idle before dying.
     177             :    */
     178             :   const uint32_t mIdleTimeoutMS;
     179             : 
     180             :   /**
     181             :    * The number of events that are pending on mThread. A nonzero value means
     182             :    * that the thread cannot be cleaned up.
     183             :    */
     184             :   uint32_t mPendingEventCount;
     185             : 
     186             :   /**
     187             :    * The number of times that mThread has dispatched an idle notification. Any
     188             :    * timer that fires while this count is nonzero can safely be ignored as
     189             :    * another timer will be on the way.
     190             :    */
     191             :   uint32_t mIdleNotificationCount;
     192             : 
     193             :   /**
     194             :    * Whether or not the thread should automatically shutdown. If the owner
     195             :    * specified ManualShutdown at construction time then the owner should take
     196             :    * care to call Shutdown() manually when appropriate.
     197             :    */
     198             :   ShutdownMethod mShutdownMethod;
     199             : 
     200             :   /**
     201             :    * Only accessed on the owning thread. Set to true when Shutdown() has been
     202             :    * called and prevents EnsureThread() from recreating mThread.
     203             :    */
     204             :   bool mShutdown;
     205             : 
     206             :   /**
     207             :    * Set from CleanupThread and lasting until the thread has shut down. Prevents
     208             :    * further idle notifications during the shutdown process.
     209             :    */
     210             :   bool mThreadIsShuttingDown;
     211             : 
     212             :   /**
     213             :    * Whether or not the idle timeout is enabled.
     214             :    */
     215             :   bool mIdleTimeoutEnabled;
     216             : 
     217             :   /**
     218             :    * Name of the thread, set on the actual thread after it gets created.
     219             :    */
     220             :   nsCString mName;
     221             : };
     222             : 
     223             : } // namespace mozilla
     224             : 
     225             : #endif // mozilla_lazyidlethread_h__

Generated by: LCOV version 1.13