xpcom/threads/LazyIdleThread.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     2 /* vim: set ts=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/. */
     7 #ifndef mozilla_lazyidlethread_h__
     8 #define mozilla_lazyidlethread_h__
    10 #ifndef MOZILLA_INTERNAL_API
    11 #error "This header is only usable from within libxul (MOZILLA_INTERNAL_API)."
    12 #endif
    14 #include "nsIObserver.h"
    15 #include "nsIThreadInternal.h"
    16 #include "nsITimer.h"
    18 #include "mozilla/Mutex.h"
    19 #include "nsCOMPtr.h"
    20 #include "nsTArray.h"
    21 #include "nsString.h"
    22 #include "mozilla/Attributes.h"
    24 #define IDLE_THREAD_TOPIC "thread-shutting-down"
    26 namespace mozilla {
    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 MOZ_FINAL : public nsIThread,
    36                                  public nsITimerCallback,
    37                                  public nsIThreadObserver,
    38                                  public nsIObserver
    39 {
    40 public:
    41   NS_DECL_THREADSAFE_ISUPPORTS
    42   NS_DECL_NSIEVENTTARGET
    43   NS_DECL_NSITHREAD
    44   NS_DECL_NSITIMERCALLBACK
    45   NS_DECL_NSITHREADOBSERVER
    46   NS_DECL_NSIOBSERVER
    48   enum ShutdownMethod {
    49     AutomaticShutdown = 0,
    50     ManualShutdown
    51   };
    53   /**
    54    * Create a new LazyIdleThread that will destroy its thread after the given
    55    * number of milliseconds.
    56    */
    57   LazyIdleThread(uint32_t aIdleTimeoutMS,
    58                  const nsCSubstring& aName,
    59                  ShutdownMethod aShutdownMethod = AutomaticShutdown,
    60                  nsIObserver* aIdleObserver = nullptr);
    62   /**
    63    * Add an observer that will be notified when the thread is idle and about to
    64    * be shut down. The aSubject argument can be QueryInterface'd to an nsIThread
    65    * that can be used to post cleanup events. The aTopic argument will be
    66    * IDLE_THREAD_TOPIC, and aData will be null. The LazyIdleThread does not add
    67    * a reference to the observer to avoid circular references as it is assumed
    68    * to be the owner. It is the caller's responsibility to clear this observer
    69    * if the pointer becomes invalid.
    70    */
    71   void SetWeakIdleObserver(nsIObserver* aObserver);
    73   /**
    74    * Disable the idle timeout for this thread. No effect if the timeout is
    75    * already disabled.
    76    */
    77   void DisableIdleTimeout();
    79   /**
    80    * Enable the idle timeout. No effect if the timeout is already enabled.
    81    */
    82   void EnableIdleTimeout();
    84 private:
    85   /**
    86    * Calls Shutdown().
    87    */
    88   ~LazyIdleThread();
    90   /**
    91    * Called just before dispatching to mThread.
    92    */
    93   void PreDispatch();
    95   /**
    96    * Makes sure a valid thread lives in mThread.
    97    */
    98   nsresult EnsureThread();
   100   /**
   101    * Called on mThread to set up the thread observer.
   102    */
   103   void InitThread();
   105   /**
   106    * Called on mThread to clean up the thread observer.
   107    */
   108   void CleanupThread();
   110   /**
   111    * Called on the main thread when mThread believes itself to be idle. Sets up
   112    * the idle timer.
   113    */
   114   void ScheduleTimer();
   116   /**
   117    * Called when we are shutting down mThread.
   118    */
   119   nsresult ShutdownThread();
   121   /**
   122    * Deletes this object. Used to delay calling mThread->Shutdown() during the
   123    * final release (during a GC, for instance).
   124    */
   125   void SelfDestruct();
   127   /**
   128    * Returns true if events should be queued rather than immediately dispatched
   129    * to mThread. Currently only happens when the thread is shutting down.
   130    */
   131   bool UseRunnableQueue() {
   132     return !!mQueuedRunnables;
   133   }
   135   /**
   136    * Protects data that is accessed on both threads.
   137    */
   138   mozilla::Mutex mMutex;
   140   /**
   141    * Touched on both threads but set before mThread is created. Used to direct
   142    * timer events to the owning thread.
   143    */
   144   nsCOMPtr<nsIThread> mOwningThread;
   146   /**
   147    * Only accessed on the owning thread. Set by EnsureThread().
   148    */
   149   nsCOMPtr<nsIThread> mThread;
   151   /**
   152    * Protected by mMutex. Created when mThread has no pending events and fired
   153    * at mOwningThread. Any thread that dispatches to mThread will take ownership
   154    * of the timer and fire a separate cancel event to the owning thread.
   155    */
   156   nsCOMPtr<nsITimer> mIdleTimer;
   158   /**
   159    * Idle observer. Called when the thread is about to be shut down. Released
   160    * only when Shutdown() is called.
   161    */
   162   nsIObserver* mIdleObserver;
   164   /**
   165    * Temporary storage for events that happen to be dispatched while we're in
   166    * the process of shutting down our real thread.
   167    */
   168   nsTArray<nsCOMPtr<nsIRunnable> >* mQueuedRunnables;
   170   /**
   171    * The number of milliseconds a thread should be idle before dying.
   172    */
   173   const uint32_t mIdleTimeoutMS;
   175   /**
   176    * The number of events that are pending on mThread. A nonzero value means
   177    * that the thread cannot be cleaned up.
   178    */
   179   uint32_t mPendingEventCount;
   181   /**
   182    * The number of times that mThread has dispatched an idle notification. Any
   183    * timer that fires while this count is nonzero can safely be ignored as
   184    * another timer will be on the way.
   185    */
   186   uint32_t mIdleNotificationCount;
   188   /**
   189    * Whether or not the thread should automatically shutdown. If the owner
   190    * specified ManualShutdown at construction time then the owner should take
   191    * care to call Shutdown() manually when appropriate.
   192    */
   193   ShutdownMethod mShutdownMethod;
   195   /**
   196    * Only accessed on the owning thread. Set to true when Shutdown() has been
   197    * called and prevents EnsureThread() from recreating mThread.
   198    */
   199   bool mShutdown;
   201   /**
   202    * Set from CleanupThread and lasting until the thread has shut down. Prevents
   203    * further idle notifications during the shutdown process.
   204    */
   205   bool mThreadIsShuttingDown;
   207   /**
   208    * Whether or not the idle timeout is enabled.
   209    */
   210   bool mIdleTimeoutEnabled;
   212   /**
   213    * Name of the thread, set on the actual thread after it gets created.
   214    */
   215   nsCString mName;
   216 };
   218 } // namespace mozilla
   220 #endif // mozilla_lazyidlethread_h__

mercurial