LCOV - code coverage report
Current view: top level - xpcom/threads - AbstractThread.h (source / functions) Hit Total Coverage
Test: output.info Lines: 3 9 33.3 %
Date: 2017-07-14 16:53:18 Functions: 3 9 33.3 %
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             : #if !defined(AbstractThread_h_)
       8             : #define AbstractThread_h_
       9             : 
      10             : #include "mozilla/RefPtr.h"
      11             : #include "mozilla/ThreadLocal.h"
      12             : #include "nscore.h"
      13             : #include "nsIRunnable.h"
      14             : #include "nsISerialEventTarget.h"
      15             : #include "nsISupportsImpl.h"
      16             : #include "nsIThread.h"
      17             : 
      18             : namespace mozilla {
      19             : 
      20             : class TaskQueue;
      21             : class TaskDispatcher;
      22             : 
      23             : /*
      24             :  * NOTE: PLEASE AVOID USE OF AbstractThread OUTSIDE MEDIA CODE WHEN POSSIBLE.
      25             :  * The nsISerialEventTarget interface should be preferred. AbstractThread
      26             :  * has unusual "tail dispatch" semantics that usually are not needed outside
      27             :  * of media code.
      28             :  *
      29             :  * We often want to run tasks on a target that guarantees that events will never
      30             :  * run in parallel. There are various target types that achieve this - namely
      31             :  * nsIThread and TaskQueue. Note that nsIThreadPool (which implements
      32             :  * nsIEventTarget) does not have this property, so we do not want to use
      33             :  * nsIEventTarget for this purpose. This class encapsulates the specifics of
      34             :  * the structures we might use here and provides a consistent interface.
      35             :  *
      36             :  * At present, the supported AbstractThread implementations are TaskQueue,
      37             :  * AbstractThread::MainThread() and DocGroup::AbstractThreadFor().
      38             :  * If you add support for another thread that is not the MainThread, you'll need
      39             :  * to figure out how to make it unique such that comparing AbstractThread
      40             :  * pointers is equivalent to comparing nsIThread pointers.
      41             :  */
      42             : class AbstractThread : public nsISerialEventTarget
      43             : {
      44             : public:
      45             :   // Returns the AbstractThread that the caller is currently running in, or null
      46             :   // if the caller is not running in an AbstractThread.
      47          12 :   static AbstractThread* GetCurrent() { return sCurrentThreadTLS.get(); }
      48             : 
      49           8 :   AbstractThread(bool aSupportsTailDispatch) : mSupportsTailDispatch(aSupportsTailDispatch) {}
      50             : 
      51             :   // Returns an AbstractThread wrapper of a nsIThread.
      52             :   static already_AddRefed<AbstractThread>
      53             :   CreateXPCOMThreadWrapper(nsIThread* aThread, bool aRequireTailDispatch);
      54             : 
      55             :   // Returns an AbstractThread wrapper of a non-nsIThread EventTarget on the main thread.
      56             :   static already_AddRefed<AbstractThread>
      57             :   CreateEventTargetWrapper(nsIEventTarget* aEventTarget, bool aRequireTailDispatch);
      58             : 
      59             :   NS_DECL_THREADSAFE_ISUPPORTS
      60             : 
      61             :   // We don't use NS_DECL_NSIEVENTTARGET so that we can remove the default
      62             :   // |flags| parameter from Dispatch. Otherwise, a single-argument Dispatch call
      63             :   // would be ambiguous.
      64             :   NS_IMETHOD_(bool) IsOnCurrentThreadInfallible(void) override;
      65             :   NS_IMETHOD IsOnCurrentThread(bool *_retval) override;
      66             :   NS_IMETHOD Dispatch(already_AddRefed<nsIRunnable> event, uint32_t flags) override;
      67             :   NS_IMETHOD DispatchFromScript(nsIRunnable *event, uint32_t flags) override;
      68             :   NS_IMETHOD DelayedDispatch(already_AddRefed<nsIRunnable> event, uint32_t delay) override;
      69             : 
      70             :   enum DispatchFailureHandling { AssertDispatchSuccess, DontAssertDispatchSuccess };
      71             :   enum DispatchReason { NormalDispatch, TailDispatch };
      72             :   virtual void Dispatch(already_AddRefed<nsIRunnable> aRunnable,
      73             :                         DispatchFailureHandling aHandling = AssertDispatchSuccess,
      74             :                         DispatchReason aReason = NormalDispatch) = 0;
      75             : 
      76             :   virtual bool IsCurrentThreadIn() = 0;
      77             : 
      78             :   // Returns a TaskDispatcher that will dispatch its tasks when the currently-
      79             :   // running tasks pops off the stack.
      80             :   //
      81             :   // May only be called when running within the it is invoked up, and only on
      82             :   // threads which support it.
      83             :   virtual TaskDispatcher& TailDispatcher() = 0;
      84             : 
      85             :   // Returns true if we have tail tasks scheduled, or if this isn't known.
      86             :   // Returns false if we definitely don't have any tail tasks.
      87           0 :   virtual bool MightHaveTailTasks() { return true; }
      88             : 
      89             :   // Helper functions for methods on the tail TasklDispatcher. These check
      90             :   // HasTailTasks to avoid allocating a TailDispatcher if it isn't
      91             :   // needed.
      92             :   void TailDispatchTasksFor(AbstractThread* aThread);
      93             :   bool HasTailTasksFor(AbstractThread* aThread);
      94             : 
      95             :   // Returns true if this supports the tail dispatcher.
      96           8 :   bool SupportsTailDispatch() const { return mSupportsTailDispatch; }
      97             : 
      98             :   // Returns true if this thread requires all dispatches originating from
      99             :   // aThread go through the tail dispatcher.
     100             :   bool RequiresTailDispatch(AbstractThread* aThread) const;
     101             :   bool RequiresTailDispatchFromCurrentThread() const;
     102             : 
     103           0 :   virtual TaskQueue* AsTaskQueue() { MOZ_CRASH("Not a task queue!"); }
     104           0 :   virtual nsIEventTarget* AsEventTarget() { MOZ_CRASH("Not an event target!"); }
     105             : 
     106             :   // Returns the non-DocGroup version of AbstractThread on the main thread.
     107             :   // A DocGroup-versioned one is available in DispatcherTrait::AbstractThreadFor().
     108             :   // Note: DispatcherTrait::AbstractThreadFor() SHALL be used when possible.
     109             :   static AbstractThread* MainThread();
     110             : 
     111             :   // Must be called exactly once during startup.
     112             :   static void InitTLS();
     113             :   static void InitMainThread();
     114             : 
     115             :   void DispatchStateChange(already_AddRefed<nsIRunnable> aRunnable);
     116             : 
     117             :   static void DispatchDirectTask(already_AddRefed<nsIRunnable> aRunnable);
     118             : 
     119             :   // Create a runnable that will run |aRunnable| and drain the direct tasks
     120             :   // generated by it.
     121             :   virtual already_AddRefed<nsIRunnable>
     122           0 :   CreateDirectTaskDrainer(already_AddRefed<nsIRunnable> aRunnable)
     123             :   {
     124           0 :     MOZ_CRASH("Not support!");
     125             :   }
     126             : 
     127             : protected:
     128           0 :   virtual ~AbstractThread() {}
     129             :   static MOZ_THREAD_LOCAL(AbstractThread*) sCurrentThreadTLS;
     130             : 
     131             :   // True if we want to require that every task dispatched from tasks running in
     132             :   // this queue go through our queue's tail dispatcher.
     133             :   const bool mSupportsTailDispatch;
     134             : };
     135             : 
     136             : } // namespace mozilla
     137             : 
     138             : #endif

Generated by: LCOV version 1.13