LCOV - code coverage report
Current view: top level - dom/workers - WorkerPrivate.h (source / functions) Hit Total Coverage
Test: output.info Lines: 69 137 50.4 %
Date: 2018-08-07 16:35:00 Functions: 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_dom_workers_workerprivate_h__
       8             : #define mozilla_dom_workers_workerprivate_h__
       9             : 
      10             : #include "mozilla/dom/WorkerCommon.h"
      11             : #include "mozilla/CondVar.h"
      12             : #include "mozilla/DOMEventTargetHelper.h"
      13             : #include "mozilla/RelativeTimeline.h"
      14             : #include "nsIContentSecurityPolicy.h"
      15             : #include "nsIEventTarget.h"
      16             : #include "nsTObserverArray.h"
      17             : 
      18             : #include "mozilla/dom/Worker.h"
      19             : #include "mozilla/dom/WorkerHolder.h"
      20             : #include "mozilla/dom/WorkerLoadInfo.h"
      21             : #include "mozilla/dom/workerinternals/JSSettings.h"
      22             : #include "mozilla/dom/workerinternals/Queue.h"
      23             : #include "mozilla/PerformanceCounter.h"
      24             : 
      25             : class nsIConsoleReportCollector;
      26             : class nsIThreadInternal;
      27             : 
      28             : namespace mozilla {
      29             : namespace dom {
      30             : 
      31             : // If you change this, the corresponding list in nsIWorkerDebugger.idl needs
      32             : // to be updated too.
      33             : enum WorkerType
      34             : {
      35             :   WorkerTypeDedicated,
      36             :   WorkerTypeShared,
      37             :   WorkerTypeService
      38             : };
      39             : 
      40             : class ClientInfo;
      41             : class ClientSource;
      42             : class Function;
      43             : class MessagePort;
      44             : class MessagePortIdentifier;
      45             : class PerformanceStorage;
      46             : class SharedWorker;
      47             : class WorkerControlRunnable;
      48             : class WorkerDebugger;
      49             : class WorkerDebuggerGlobalScope;
      50             : class WorkerErrorReport;
      51             : class WorkerEventTarget;
      52             : class WorkerGlobalScope;
      53             : class WorkerRunnable;
      54             : class WorkerThread;
      55             : 
      56             : // SharedMutex is a small wrapper around an (internal) reference-counted Mutex
      57             : // object. It exists to avoid changing a lot of code to use Mutex* instead of
      58             : // Mutex&.
      59             : class SharedMutex
      60             : {
      61             :   typedef mozilla::Mutex Mutex;
      62             : 
      63             :   class RefCountedMutex final : public Mutex
      64             :   {
      65             :   public:
      66             :     explicit RefCountedMutex(const char* aName)
      67             :     : Mutex(aName)
      68             :     { }
      69             : 
      70             :     NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMutex)
      71             : 
      72             :   private:
      73             :     ~RefCountedMutex()
      74             :     { }
      75             :   };
      76             : 
      77             :   RefPtr<RefCountedMutex> mMutex;
      78             : 
      79             : public:
      80             :   explicit SharedMutex(const char* aName)
      81             :   : mMutex(new RefCountedMutex(aName))
      82             :   { }
      83             : 
      84             :   SharedMutex(SharedMutex& aOther)
      85             :   : mMutex(aOther.mMutex)
      86             :   { }
      87             : 
      88             :   operator Mutex&()
      89             :   {
      90           2 :     return *mMutex;
      91             :   }
      92             : 
      93             :   operator const Mutex&() const
      94             :   {
      95             :     return *mMutex;
      96             :   }
      97             : 
      98             :   void
      99             :   AssertCurrentThreadOwns() const
     100             :   {
     101             :     mMutex->AssertCurrentThreadOwns();
     102             :   }
     103             : };
     104             : 
     105             : class WorkerPrivate
     106             :   : public RelativeTimeline
     107             : {
     108             : public:
     109             :   struct LocationInfo
     110             :   {
     111             :     nsCString mHref;
     112             :     nsCString mProtocol;
     113             :     nsCString mHost;
     114             :     nsCString mHostname;
     115             :     nsCString mPort;
     116             :     nsCString mPathname;
     117             :     nsCString mSearch;
     118             :     nsCString mHash;
     119             :     nsString mOrigin;
     120             :   };
     121             : 
     122           2 :   NS_INLINE_DECL_REFCOUNTING(WorkerPrivate)
     123             : 
     124             :   static already_AddRefed<WorkerPrivate>
     125             :   Constructor(JSContext* aCx, const nsAString& aScriptURL, bool aIsChromeWorker,
     126             :               WorkerType aWorkerType, const nsAString& aWorkerName,
     127             :               const nsACString& aServiceWorkerScope,
     128             :               WorkerLoadInfo* aLoadInfo, ErrorResult& aRv);
     129             : 
     130             :   enum LoadGroupBehavior
     131             :   {
     132             :     InheritLoadGroup,
     133             :     OverrideLoadGroup
     134             :   };
     135             : 
     136             :   static nsresult
     137             :   GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
     138             :               WorkerPrivate* aParent,
     139             :               const nsAString& aScriptURL, bool aIsChromeWorker,
     140             :               LoadGroupBehavior aLoadGroupBehavior, WorkerType aWorkerType,
     141             :               WorkerLoadInfo* aLoadInfo);
     142             : 
     143             :   void
     144             :   Traverse(nsCycleCollectionTraversalCallback& aCb);
     145             : 
     146             :   void
     147             :   ClearSelfAndParentEventTargetRef()
     148             :   {
     149             :     AssertIsOnParentThread();
     150             :     MOZ_ASSERT(mSelfRef);
     151             :     mParentEventTargetRef = nullptr;
     152             :     mSelfRef = nullptr;
     153             :   }
     154             : 
     155             :   // May be called on any thread...
     156             :   bool
     157             :   Start();
     158             : 
     159             :   // Called on the parent thread.
     160             :   bool
     161             :   Notify(WorkerStatus aStatus);
     162             : 
     163             :   bool
     164           0 :   Cancel()
     165             :   {
     166           0 :     return Notify(Canceling);
     167             :   }
     168             : 
     169             :   bool
     170           0 :   Kill()
     171             :   {
     172           0 :     return Notify(Killing);
     173             :   }
     174             : 
     175             :   bool
     176           0 :   Terminate()
     177             :   {
     178           0 :     return Notify(Terminating);
     179             :   }
     180             : 
     181             :   bool
     182             :   Close();
     183             : 
     184             :   // The passed principal must be the Worker principal in case of a
     185             :   // ServiceWorker and the loading principal for any other type.
     186             :   static void
     187             :   OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo,
     188             :                             nsIPrincipal* aPrincipal);
     189             : 
     190             :   bool
     191             :   IsDebuggerRegistered()
     192             :   {
     193           0 :     AssertIsOnMainThread();
     194             : 
     195             :     // No need to lock here since this is only ever modified by the same thread.
     196           0 :     return mDebuggerRegistered;
     197             :   }
     198             : 
     199             :   void
     200           6 :   SetIsDebuggerRegistered(bool aDebuggerRegistered)
     201             :   {
     202           6 :     AssertIsOnMainThread();
     203             : 
     204          18 :     MutexAutoLock lock(mMutex);
     205             : 
     206           6 :     MOZ_ASSERT(mDebuggerRegistered != aDebuggerRegistered);
     207           6 :     mDebuggerRegistered = aDebuggerRegistered;
     208             : 
     209          12 :     mCondVar.Notify();
     210           6 :   }
     211             : 
     212             :   void
     213           0 :   WaitForIsDebuggerRegistered(bool aDebuggerRegistered)
     214             :   {
     215           0 :     AssertIsOnParentThread();
     216             : 
     217           0 :     MOZ_ASSERT(!NS_IsMainThread());
     218             : 
     219           0 :     MutexAutoLock lock(mMutex);
     220             : 
     221           0 :     while (mDebuggerRegistered != aDebuggerRegistered) {
     222           0 :       mCondVar.Wait();
     223             :     }
     224           0 :   }
     225             : 
     226             :   WorkerDebugger*
     227           0 :   Debugger() const
     228             :   {
     229           0 :     AssertIsOnMainThread();
     230             : 
     231           0 :     MOZ_ASSERT(mDebugger);
     232           0 :     return mDebugger;
     233             :   }
     234             : 
     235             :   void
     236           6 :   SetDebugger(WorkerDebugger* aDebugger)
     237             :   {
     238           6 :     AssertIsOnMainThread();
     239             : 
     240           6 :     MOZ_ASSERT(mDebugger != aDebugger);
     241           6 :     mDebugger = aDebugger;
     242           6 :   }
     243             : 
     244             :   JS::UniqueChars
     245           6 :   AdoptDefaultLocale()
     246             :   {
     247          12 :     MOZ_ASSERT(mDefaultLocale,
     248             :                "the default locale must have been successfully set for anyone "
     249             :                "to be trying to adopt it");
     250          12 :     return std::move(mDefaultLocale);
     251             :   }
     252             : 
     253             :   void
     254             :   DoRunLoop(JSContext* aCx);
     255             : 
     256             :   bool
     257             :   InterruptCallback(JSContext* aCx);
     258             : 
     259             :   bool
     260             :   IsOnCurrentThread();
     261             : 
     262             :   void
     263             :   CloseInternal();
     264             : 
     265             :   bool
     266             :   FreezeInternal();
     267             : 
     268             :   bool
     269             :   ThawInternal();
     270             : 
     271             :   void
     272             :   TraverseTimeouts(nsCycleCollectionTraversalCallback& aCallback);
     273             : 
     274             :   void
     275             :   UnlinkTimeouts();
     276             : 
     277             :   bool
     278             :   ModifyBusyCountFromWorker(bool aIncrease);
     279             : 
     280             :   bool
     281             :   AddChildWorker(WorkerPrivate* aChildWorker);
     282             : 
     283             :   void
     284             :   RemoveChildWorker(WorkerPrivate* aChildWorker);
     285             : 
     286             :   void
     287             :   PostMessageToParent(JSContext* aCx,
     288             :                       JS::Handle<JS::Value> aMessage,
     289             :                       const Sequence<JSObject*>& aTransferable,
     290             :                       ErrorResult& aRv);
     291             : 
     292             :   void
     293             :   PostMessageToParentMessagePort(JSContext* aCx,
     294             :                                  JS::Handle<JS::Value> aMessage,
     295             :                                  const Sequence<JSObject*>& aTransferable,
     296             :                                  ErrorResult& aRv);
     297             : 
     298             :   void
     299             :   EnterDebuggerEventLoop();
     300             : 
     301             :   void
     302             :   LeaveDebuggerEventLoop();
     303             : 
     304             :   void
     305             :   PostMessageToDebugger(const nsAString& aMessage);
     306             : 
     307             :   void
     308             :   SetDebuggerImmediate(Function& aHandler, ErrorResult& aRv);
     309             : 
     310             :   void
     311             :   ReportErrorToDebugger(const nsAString& aFilename, uint32_t aLineno,
     312             :                         const nsAString& aMessage);
     313             : 
     314             :   bool
     315             :   NotifyInternal(WorkerStatus aStatus);
     316             : 
     317             :   void
     318             :   ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
     319             :               JSErrorReport* aReport);
     320             : 
     321             :   static void
     322             :   ReportErrorToConsole(const char* aMessage);
     323             : 
     324             :   int32_t
     325             :   SetTimeout(JSContext* aCx, nsIScriptTimeoutHandler* aHandler,
     326             :              int32_t aTimeout, bool aIsInterval,
     327             :              ErrorResult& aRv);
     328             : 
     329             :   void
     330             :   ClearTimeout(int32_t aId);
     331             : 
     332             :   bool
     333             :   RunExpiredTimeouts(JSContext* aCx);
     334             : 
     335             :   bool
     336             :   RescheduleTimeoutTimer(JSContext* aCx);
     337             : 
     338             :   void
     339             :   UpdateContextOptionsInternal(JSContext* aCx, const JS::ContextOptions& aContextOptions);
     340             : 
     341             :   void
     342             :   UpdateLanguagesInternal(const nsTArray<nsString>& aLanguages);
     343             : 
     344             :   void
     345             :   UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
     346             : 
     347             :   enum WorkerRanOrNot {
     348             :     WorkerNeverRan = 0,
     349             :     WorkerRan
     350             :   };
     351             : 
     352             :   void
     353             :   ScheduleDeletion(WorkerRanOrNot aRanOrNot);
     354             : 
     355             :   bool
     356             :   CollectRuntimeStats(JS::RuntimeStats* aRtStats, bool aAnonymize);
     357             : 
     358             : #ifdef JS_GC_ZEAL
     359             :   void
     360             :   UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
     361             : #endif
     362             : 
     363             :   void
     364             :   GarbageCollectInternal(JSContext* aCx, bool aShrinking,
     365             :                          bool aCollectChildren);
     366             : 
     367             :   void
     368             :   CycleCollectInternal(bool aCollectChildren);
     369             : 
     370             :   void
     371             :   OfflineStatusChangeEventInternal(bool aIsOffline);
     372             : 
     373             :   void
     374             :   MemoryPressureInternal();
     375             : 
     376             :   void
     377             :   SetFetchHandlerWasAdded()
     378             :   {
     379             :     MOZ_ASSERT(IsServiceWorker());
     380             :     AssertIsOnWorkerThread();
     381             :     mFetchHandlerWasAdded = true;
     382             :   }
     383             : 
     384             :   bool
     385             :   FetchHandlerWasAdded() const
     386             :   {
     387             :     MOZ_ASSERT(IsServiceWorker());
     388             :     AssertIsOnWorkerThread();
     389             :     return mFetchHandlerWasAdded;
     390             :   }
     391             : 
     392             :   JSContext*
     393             :   GetJSContext() const
     394             :   {
     395           2 :     AssertIsOnWorkerThread();
     396           2 :     return mJSContext;
     397             :   }
     398             : 
     399             :   WorkerGlobalScope*
     400             :   GlobalScope() const
     401             :   {
     402           2 :     AssertIsOnWorkerThread();
     403           2 :     return mScope;
     404             :   }
     405             : 
     406             :   WorkerDebuggerGlobalScope*
     407             :   DebuggerGlobalScope() const
     408             :   {
     409           0 :     AssertIsOnWorkerThread();
     410           0 :     return mDebuggerScope;
     411             :   }
     412             : 
     413             :   void
     414             :   SetThread(WorkerThread* aThread);
     415             : 
     416             :   bool
     417             :   IsOnWorkerThread() const;
     418             : 
     419             :   void
     420             :   AssertIsOnWorkerThread() const
     421             : #ifdef DEBUG
     422             :   ;
     423             : #else
     424             :   { }
     425             : #endif
     426             : 
     427             :   // This may block!
     428             :   void
     429             :   BeginCTypesCall();
     430             : 
     431             :   // This may block!
     432             :   void
     433             :   EndCTypesCall();
     434             : 
     435             :   void
     436             :   BeginCTypesCallback()
     437             :   {
     438             :     // If a callback is beginning then we need to do the exact same thing as
     439             :     // when a ctypes call ends.
     440           0 :     EndCTypesCall();
     441             :   }
     442             : 
     443             :   void
     444             :   EndCTypesCallback()
     445             :   {
     446             :     // If a callback is ending then we need to do the exact same thing as
     447             :     // when a ctypes call begins.
     448           0 :     BeginCTypesCall();
     449             :   }
     450             : 
     451             :   bool
     452             :   ConnectMessagePort(JSContext* aCx, MessagePortIdentifier& aIdentifier);
     453             : 
     454             :   WorkerGlobalScope*
     455             :   GetOrCreateGlobalScope(JSContext* aCx);
     456             : 
     457             :   WorkerDebuggerGlobalScope*
     458             :   CreateDebuggerGlobalScope(JSContext* aCx);
     459             : 
     460             :   bool
     461             :   RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
     462             : 
     463             :   bool
     464             :   RegisterDebuggerBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
     465             : 
     466             :   bool
     467             :   OnLine() const
     468             :   {
     469             :     AssertIsOnWorkerThread();
     470             :     return mOnLine;
     471             :   }
     472             : 
     473             :   void
     474             :   StopSyncLoop(nsIEventTarget* aSyncLoopTarget, bool aResult);
     475             : 
     476             :   bool
     477             :   AllPendingRunnablesShouldBeCanceled() const
     478             :   {
     479             :     return mCancelAllPendingRunnables;
     480             :   }
     481             : 
     482             :   void
     483             :   ClearMainEventQueue(WorkerRanOrNot aRanOrNot);
     484             : 
     485             :   void
     486             :   ClearDebuggerEventQueue();
     487             : 
     488             :   void
     489             :   OnProcessNextEvent();
     490             : 
     491             :   void
     492             :   AfterProcessNextEvent();
     493             : 
     494             :   void
     495             :   AssertValidSyncLoop(nsIEventTarget* aSyncLoopTarget)
     496             : #ifdef DEBUG
     497             :   ;
     498             : #else
     499             :   { }
     500             : #endif
     501             : 
     502             :   void
     503             :   SetWorkerScriptExecutedSuccessfully()
     504             :   {
     505             :     AssertIsOnWorkerThread();
     506             :     // Should only be called once!
     507             :     MOZ_ASSERT(!mWorkerScriptExecutedSuccessfully);
     508             :     mWorkerScriptExecutedSuccessfully = true;
     509             :   }
     510             : 
     511             :   // Only valid after CompileScriptRunnable has finished running!
     512             :   bool
     513             :   WorkerScriptExecutedSuccessfully() const
     514             :   {
     515             :     AssertIsOnWorkerThread();
     516             :     return mWorkerScriptExecutedSuccessfully;
     517             :   }
     518             : 
     519             :   // Get the event target to use when dispatching to the main thread
     520             :   // from this Worker thread.  This may be the main thread itself or
     521             :   // a ThrottledEventQueue to the main thread.
     522             :   nsIEventTarget*
     523             :   MainThreadEventTarget();
     524             : 
     525             :   nsresult
     526             :   DispatchToMainThread(nsIRunnable* aRunnable,
     527             :                        uint32_t aFlags = NS_DISPATCH_NORMAL);
     528             : 
     529             :   nsresult
     530             :   DispatchToMainThread(already_AddRefed<nsIRunnable> aRunnable,
     531             :                        uint32_t aFlags = NS_DISPATCH_NORMAL);
     532             : 
     533             :   // Get an event target that will dispatch runnables as control runnables on
     534             :   // the worker thread.  Implement nsICancelableRunnable if you wish to take
     535             :   // action on cancelation.
     536             :   nsISerialEventTarget*
     537             :   ControlEventTarget();
     538             : 
     539             :   // Get an event target that will attempt to dispatch a normal WorkerRunnable,
     540             :   // but if that fails will then fall back to a control runnable.
     541             :   nsISerialEventTarget*
     542             :   HybridEventTarget();
     543             : 
     544             :   void
     545             :   DumpCrashInformation(nsACString& aString);
     546             : 
     547             :   bool
     548             :   EnsureClientSource();
     549             : 
     550             :   void
     551             :   EnsurePerformanceStorage();
     552             : 
     553             :   void
     554             :   EnsurePerformanceCounter();
     555             : 
     556             :   Maybe<ClientInfo>
     557             :   GetClientInfo() const;
     558             : 
     559             :   const ClientState
     560             :   GetClientState() const;
     561             : 
     562             :   const Maybe<ServiceWorkerDescriptor>
     563             :   GetController();
     564             : 
     565             :   void
     566             :   Control(const ServiceWorkerDescriptor& aServiceWorker);
     567             : 
     568             :   void
     569             :   ExecutionReady();
     570             : 
     571             :   PerformanceStorage*
     572             :   GetPerformanceStorage();
     573             : 
     574             :   PerformanceCounter*
     575             :   GetPerformanceCounter();
     576             : 
     577             :   bool
     578           2 :   IsAcceptingEvents()
     579             :   {
     580           2 :     AssertIsOnParentThread();
     581             : 
     582           2 :     MutexAutoLock lock(mMutex);
     583           2 :     return mParentStatus < Terminating;
     584             :   }
     585             : 
     586             :   WorkerStatus
     587           2 :   ParentStatusProtected()
     588             :   {
     589           2 :     AssertIsOnParentThread();
     590           2 :     MutexAutoLock lock(mMutex);
     591           2 :     return mParentStatus;
     592             :   }
     593             : 
     594             :   WorkerStatus
     595             :   ParentStatus() const
     596             :   {
     597             :     mMutex.AssertCurrentThreadOwns();
     598             :     return mParentStatus;
     599             :   }
     600             : 
     601             :   Worker*
     602           2 :   ParentEventTargetRef() const
     603             :   {
     604           2 :     MOZ_DIAGNOSTIC_ASSERT(mParentEventTargetRef);
     605           2 :     return mParentEventTargetRef;
     606             :   }
     607             : 
     608             :   void
     609           6 :   SetParentEventTargetRef(Worker* aParentEventTargetRef)
     610             :   {
     611           6 :     MOZ_DIAGNOSTIC_ASSERT(aParentEventTargetRef);
     612          12 :     MOZ_DIAGNOSTIC_ASSERT(!mParentEventTargetRef);
     613          12 :     mParentEventTargetRef = aParentEventTargetRef;
     614           6 :   }
     615             : 
     616             :   bool
     617             :   ModifyBusyCount(bool aIncrease);
     618             : 
     619             :   // This method is used by RuntimeService to know what is going wrong the
     620             :   // shutting down.
     621             :   uint32_t
     622             :   BusyCount()
     623             :   {
     624           0 :     return mBusyCount;
     625             :   }
     626             : 
     627             :   // Check whether this worker is a secure context.  For use from the parent
     628             :   // thread only; the canonical "is secure context" boolean is stored on the
     629             :   // compartment of the worker global.  The only reason we don't
     630             :   // AssertIsOnParentThread() here is so we can assert that this value matches
     631             :   // the one on the compartment, which has to be done from the worker thread.
     632             :   bool IsSecureContext() const
     633             :   {
     634             :     return mIsSecureContext;
     635             :   }
     636             : 
     637             :   // Check whether we're running in automation.
     638             :   bool IsInAutomation() const
     639             :   {
     640             :     return mIsInAutomation;
     641             :   }
     642             : 
     643             :   TimeStamp CreationTimeStamp() const
     644             :   {
     645             :     return mCreationTimeStamp;
     646             :   }
     647             : 
     648             :   DOMHighResTimeStamp CreationTime() const
     649             :   {
     650             :     return mCreationTimeHighRes;
     651             :   }
     652             : 
     653             :   DOMHighResTimeStamp TimeStampToDOMHighRes(const TimeStamp& aTimeStamp) const
     654             :   {
     655             :     MOZ_ASSERT(!aTimeStamp.IsNull());
     656             :     TimeDuration duration = aTimeStamp - mCreationTimeStamp;
     657             :     return duration.ToMilliseconds();
     658             :   }
     659             : 
     660             :   LocationInfo&
     661             :   GetLocationInfo()
     662             :   {
     663             :     return mLocationInfo;
     664             :   }
     665             : 
     666             :   void
     667           2 :   CopyJSSettings(workerinternals::JSSettings& aSettings)
     668             :   {
     669           2 :     mozilla::MutexAutoLock lock(mMutex);
     670           2 :     aSettings = mJSSettings;
     671           2 :   }
     672             : 
     673             :   void
     674             :   CopyJSRealmOptions(JS::RealmOptions& aOptions)
     675             :   {
     676             :     mozilla::MutexAutoLock lock(mMutex);
     677             :     aOptions = IsChromeWorker() ? mJSSettings.chrome.realmOptions
     678             :                                 : mJSSettings.content.realmOptions;
     679             :   }
     680             : 
     681             :   // The ability to be a chrome worker is orthogonal to the type of
     682             :   // worker [Dedicated|Shared|Service].
     683             :   bool
     684             :   IsChromeWorker() const
     685             :   {
     686             :     return mIsChromeWorker;
     687             :   }
     688             : 
     689             :   WorkerPrivate*
     690             :   GetParent() const
     691             :   {
     692             :     return mParent;
     693             :   }
     694             : 
     695             :   bool
     696             :   IsFrozen() const
     697             :   {
     698           2 :     AssertIsOnParentThread();
     699           2 :     return mParentFrozen;
     700             :   }
     701             : 
     702             :   bool
     703           2 :   IsParentWindowPaused() const
     704             :   {
     705           2 :     AssertIsOnParentThread();
     706           2 :     return mParentWindowPausedDepth > 0;
     707             :   }
     708             : 
     709             :   // When we debug a worker, we want to disconnect the window and the worker
     710             :   // communication. This happens calling this method.
     711             :   // Note: this method doesn't suspend the worker! Use Freeze/Thaw instead.
     712             :   void
     713             :   ParentWindowPaused();
     714             : 
     715             :   void
     716             :   ParentWindowResumed();
     717             : 
     718             :   const nsString&
     719             :   ScriptURL() const
     720             :   {
     721           0 :     return mScriptURL;
     722             :   }
     723             : 
     724             :   const nsString&
     725             :   WorkerName() const
     726             :   {
     727             :     return mWorkerName;
     728             :   }
     729             : 
     730             :   WorkerType
     731             :   Type() const
     732             :   {
     733             :     return mWorkerType;
     734             :   }
     735             : 
     736             :   bool
     737             :   IsDedicatedWorker() const
     738             :   {
     739             :     return mWorkerType == WorkerTypeDedicated;
     740             :   }
     741             : 
     742             :   bool
     743             :   IsSharedWorker() const
     744             :   {
     745             :     return mWorkerType == WorkerTypeShared;
     746             :   }
     747             : 
     748             :   bool
     749             :   IsServiceWorker() const
     750             :   {
     751             :     return mWorkerType == WorkerTypeService;
     752             :   }
     753             : 
     754             :   nsContentPolicyType
     755             :   ContentPolicyType() const
     756             :   {
     757          42 :     return ContentPolicyType(mWorkerType);
     758             :   }
     759             : 
     760             :   static nsContentPolicyType
     761           2 :   ContentPolicyType(WorkerType aWorkerType)
     762             :   {
     763           2 :     switch (aWorkerType) {
     764             :     case WorkerTypeDedicated:
     765             :       return nsIContentPolicy::TYPE_INTERNAL_WORKER;
     766             :     case WorkerTypeShared:
     767           0 :       return nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
     768             :     case WorkerTypeService:
     769           0 :       return nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER;
     770             :     default:
     771           0 :       MOZ_ASSERT_UNREACHABLE("Invalid worker type");
     772             :       return nsIContentPolicy::TYPE_INVALID;
     773             :     }
     774             :   }
     775             : 
     776             :   nsIScriptContext*
     777             :   GetScriptContext() const
     778             :   {
     779             :     AssertIsOnMainThread();
     780             :     return mLoadInfo.mScriptContext;
     781             :   }
     782             : 
     783             :   const nsCString&
     784             :   Domain() const
     785             :   {
     786           6 :     return mLoadInfo.mDomain;
     787             :   }
     788             : 
     789             :   bool
     790             :   IsFromWindow() const
     791             :   {
     792             :     return mLoadInfo.mFromWindow;
     793             :   }
     794             : 
     795             :   nsLoadFlags
     796             :   GetLoadFlags() const
     797             :   {
     798             :     return mLoadInfo.mLoadFlags;
     799             :   }
     800             : 
     801             :   uint64_t
     802             :   WindowID() const
     803             :   {
     804             :     return mLoadInfo.mWindowID;
     805             :   }
     806             : 
     807             :   uint64_t
     808           0 :   ServiceWorkerID() const
     809             :   {
     810           0 :     return GetServiceWorkerDescriptor().Id();
     811             :   }
     812             : 
     813             :   const nsCString&
     814           0 :   ServiceWorkerScope() const
     815             :   {
     816           0 :     return GetServiceWorkerDescriptor().Scope();
     817             :   }
     818             : 
     819             :   nsIURI*
     820             :   GetBaseURI() const
     821             :   {
     822           2 :     AssertIsOnMainThread();
     823           2 :     return mLoadInfo.mBaseURI;
     824             :   }
     825             : 
     826             :   void
     827             :   SetBaseURI(nsIURI* aBaseURI);
     828             : 
     829             :   nsIURI*
     830             :   GetResolvedScriptURI() const
     831             :   {
     832           0 :     AssertIsOnMainThread();
     833           0 :     return mLoadInfo.mResolvedScriptURI;
     834             :   }
     835             : 
     836             :   const nsString&
     837           0 :   ServiceWorkerCacheName() const
     838             :   {
     839           0 :     MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
     840           0 :     AssertIsOnMainThread();
     841           0 :     return mLoadInfo.mServiceWorkerCacheName;
     842             :   }
     843             : 
     844             :   const ServiceWorkerDescriptor&
     845           0 :   GetServiceWorkerDescriptor() const
     846             :   {
     847           0 :     MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
     848           0 :     MOZ_DIAGNOSTIC_ASSERT(mLoadInfo.mServiceWorkerDescriptor.isSome());
     849           0 :     return mLoadInfo.mServiceWorkerDescriptor.ref();
     850             :   }
     851             : 
     852             :   const ServiceWorkerRegistrationDescriptor&
     853             :   GetServiceWorkerRegistrationDescriptor() const
     854             :   {
     855             :     MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
     856             :     MOZ_DIAGNOSTIC_ASSERT(mLoadInfo.mServiceWorkerRegistrationDescriptor.isSome());
     857             :     return mLoadInfo.mServiceWorkerRegistrationDescriptor.ref();
     858             :   }
     859             : 
     860             :   void
     861             :   UpdateServiceWorkerState(ServiceWorkerState aState)
     862             :   {
     863             :     MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
     864             :     MOZ_DIAGNOSTIC_ASSERT(mLoadInfo.mServiceWorkerDescriptor.isSome());
     865             :     return mLoadInfo.mServiceWorkerDescriptor.ref().SetState(aState);
     866             :   }
     867             : 
     868             :   const Maybe<ServiceWorkerDescriptor>&
     869             :   GetParentController() const
     870             :   {
     871           0 :     return mLoadInfo.mParentController;
     872             :   }
     873             : 
     874             :   const ChannelInfo&
     875             :   GetChannelInfo() const
     876             :   {
     877             :     return mLoadInfo.mChannelInfo;
     878             :   }
     879             : 
     880             :   void
     881             :   SetChannelInfo(const ChannelInfo& aChannelInfo)
     882             :   {
     883             :     AssertIsOnMainThread();
     884             :     MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized());
     885             :     MOZ_ASSERT(aChannelInfo.IsInitialized());
     886             :     mLoadInfo.mChannelInfo = aChannelInfo;
     887             :   }
     888             : 
     889             :   void
     890             :   InitChannelInfo(nsIChannel* aChannel)
     891             :   {
     892           6 :     mLoadInfo.mChannelInfo.InitFromChannel(aChannel);
     893             :   }
     894             : 
     895             :   void
     896             :   InitChannelInfo(const ChannelInfo& aChannelInfo)
     897             :   {
     898           0 :     mLoadInfo.mChannelInfo = aChannelInfo;
     899             :   }
     900             : 
     901             :   nsIPrincipal*
     902             :   GetPrincipal() const
     903             :   {
     904           2 :     AssertIsOnMainThread();
     905           2 :     return mLoadInfo.mPrincipal;
     906             :   }
     907             : 
     908             :   nsIPrincipal*
     909             :   GetLoadingPrincipal() const
     910             :   {
     911           6 :     AssertIsOnMainThread();
     912          12 :     return mLoadInfo.mLoadingPrincipal;
     913             :   }
     914             : 
     915             :   const nsAString& Origin() const
     916             :   {
     917             :     return mLoadInfo.mOrigin;
     918             :   }
     919             : 
     920             :   nsILoadGroup*
     921             :   GetLoadGroup() const
     922             :   {
     923           2 :     AssertIsOnMainThread();
     924           2 :     return mLoadInfo.mLoadGroup;
     925             :   }
     926             : 
     927             :   // This method allows the principal to be retrieved off the main thread.
     928             :   // Principals are main-thread objects so the caller must ensure that all
     929             :   // access occurs on the main thread.
     930             :   nsIPrincipal*
     931             :   GetPrincipalDontAssertMainThread() const
     932             :   {
     933           0 :       return mLoadInfo.mPrincipal;
     934             :   }
     935             : 
     936             :   bool
     937             :   UsesSystemPrincipal() const
     938             :   {
     939             :     return mLoadInfo.mPrincipalIsSystem;
     940             :   }
     941             : 
     942             :   const mozilla::ipc::PrincipalInfo&
     943             :   GetPrincipalInfo() const
     944             :   {
     945             :     return *mLoadInfo.mPrincipalInfo;
     946             :   }
     947             : 
     948             :   already_AddRefed<nsIChannel>
     949           6 :   ForgetWorkerChannel()
     950             :   {
     951           6 :     AssertIsOnMainThread();
     952           6 :     return mLoadInfo.mChannel.forget();
     953             :   }
     954             : 
     955             :   nsPIDOMWindowInner*
     956             :   GetWindow()
     957             :   {
     958           2 :     AssertIsOnMainThread();
     959           2 :     return mLoadInfo.mWindow;
     960             :   }
     961             : 
     962             :   nsIContentSecurityPolicy*
     963             :   GetCSP() const
     964             :   {
     965           6 :     AssertIsOnMainThread();
     966          12 :     return mLoadInfo.mCSP;
     967             :   }
     968             : 
     969             :   void
     970             :   SetCSP(nsIContentSecurityPolicy* aCSP);
     971             : 
     972             :   nsresult
     973             :   SetCSPFromHeaderValues(const nsACString& aCSPHeaderValue,
     974             :                          const nsACString& aCSPReportOnlyHeaderValue);
     975             : 
     976             :   void
     977             :   SetReferrerPolicyFromHeaderValue(const nsACString& aReferrerPolicyHeaderValue);
     978             : 
     979             :   net::ReferrerPolicy
     980             :   GetReferrerPolicy() const
     981             :   {
     982             :     return mLoadInfo.mReferrerPolicy;
     983             :   }
     984             : 
     985             :   void
     986             :   SetReferrerPolicy(net::ReferrerPolicy aReferrerPolicy)
     987             :   {
     988             :     mLoadInfo.mReferrerPolicy = aReferrerPolicy;
     989             :   }
     990             : 
     991             :   bool
     992             :   IsEvalAllowed() const
     993             :   {
     994             :     return mLoadInfo.mEvalAllowed;
     995             :   }
     996             : 
     997             :   void
     998             :   SetEvalAllowed(bool aEvalAllowed)
     999             :   {
    1000           0 :     mLoadInfo.mEvalAllowed = aEvalAllowed;
    1001             :   }
    1002             : 
    1003             :   bool
    1004             :   GetReportCSPViolations() const
    1005             :   {
    1006             :     return mLoadInfo.mReportCSPViolations;
    1007             :   }
    1008             : 
    1009             :   void
    1010             :   SetReportCSPViolations(bool aReport)
    1011             :   {
    1012             :     mLoadInfo.mReportCSPViolations = aReport;
    1013             :   }
    1014             : 
    1015             :   bool
    1016             :   XHRParamsAllowed() const
    1017             :   {
    1018             :     return mLoadInfo.mXHRParamsAllowed;
    1019             :   }
    1020             : 
    1021             :   void
    1022             :   SetXHRParamsAllowed(bool aAllowed)
    1023             :   {
    1024           0 :     mLoadInfo.mXHRParamsAllowed = aAllowed;
    1025             :   }
    1026             : 
    1027             :   bool
    1028             :   IsStorageAllowed() const
    1029             :   {
    1030             :     return mLoadInfo.mStorageAllowed;
    1031             :   }
    1032             : 
    1033             :   const OriginAttributes&
    1034             :   GetOriginAttributes() const
    1035             :   {
    1036             :     return mLoadInfo.mOriginAttributes;
    1037             :   }
    1038             : 
    1039             :   // Determine if the SW testing per-window flag is set by devtools
    1040             :   bool
    1041             :   ServiceWorkersTestingInWindow() const
    1042             :   {
    1043             :     return mLoadInfo.mServiceWorkersTestingInWindow;
    1044             :   }
    1045             : 
    1046             :   // Determine if the worker is currently loading its top level script.
    1047             :   bool
    1048             :   IsLoadingWorkerScript() const
    1049             :   {
    1050             :     return mLoadingWorkerScript;
    1051             :   }
    1052             : 
    1053             :   // Called by ScriptLoader to track when this worker is loading its
    1054             :   // top level script.
    1055             :   void
    1056             :   SetLoadingWorkerScript(bool aLoadingWorkerScript)
    1057             :   {
    1058             :     // any thread
    1059          20 :     mLoadingWorkerScript = aLoadingWorkerScript;
    1060             :   }
    1061             : 
    1062             :   void
    1063           0 :   QueueRunnable(nsIRunnable* aRunnable)
    1064             :   {
    1065           0 :     AssertIsOnParentThread();
    1066           0 :     mQueuedRunnables.AppendElement(aRunnable);
    1067           0 :   }
    1068             : 
    1069             :   bool
    1070             :   RegisterSharedWorker(SharedWorker* aSharedWorker, MessagePort* aPort);
    1071             : 
    1072             :   void
    1073             :   BroadcastErrorToSharedWorkers(JSContext* aCx,
    1074             :                                 const WorkerErrorReport* aReport,
    1075             :                                 bool aIsErrorEvent);
    1076             : 
    1077             :   void
    1078             :   GetAllSharedWorkers(nsTArray<RefPtr<SharedWorker>>& aSharedWorkers);
    1079             : 
    1080             :   void
    1081             :   CloseSharedWorkersForWindow(nsPIDOMWindowInner* aWindow);
    1082             : 
    1083             :   void
    1084             :   CloseAllSharedWorkers();
    1085             : 
    1086             :   void
    1087             :   FlushReportsToSharedWorkers(nsIConsoleReportCollector* aReporter);
    1088             : 
    1089             :   // We can assume that an nsPIDOMWindow will be available for Freeze, Thaw
    1090             :   // as these are only used for globals going in and out of the bfcache.
    1091             :   //
    1092             :   // XXXbz: This is a bald-faced lie given the uses in RegisterSharedWorker and
    1093             :   // CloseSharedWorkersForWindow, which pass null for aWindow to Thaw and Freeze
    1094             :   // respectively.  See bug 1251722.
    1095             :   bool
    1096             :   Freeze(nsPIDOMWindowInner* aWindow);
    1097             : 
    1098             :   bool
    1099             :   Thaw(nsPIDOMWindowInner* aWindow);
    1100             : 
    1101             :   void
    1102             :   EnableDebugger();
    1103             : 
    1104             :   void
    1105             :   DisableDebugger();
    1106             : 
    1107             :   already_AddRefed<WorkerRunnable>
    1108             :   MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunnable> aRunnable);
    1109             : 
    1110             :   bool
    1111             :   ProxyReleaseMainThreadObjects();
    1112             : 
    1113             :   void
    1114             :   GarbageCollect(bool aShrinking);
    1115             : 
    1116             :   void
    1117             :   CycleCollect(bool aDummy);
    1118             : 
    1119             :   nsresult
    1120             :   SetPrincipalOnMainThread(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
    1121             : 
    1122             :   nsresult
    1123             :   SetPrincipalFromChannel(nsIChannel* aChannel);
    1124             : 
    1125             :   bool
    1126             :   FinalChannelPrincipalIsValid(nsIChannel* aChannel);
    1127             : 
    1128             : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
    1129             :   bool
    1130             :   PrincipalURIMatchesScriptURL();
    1131             : #endif
    1132             : 
    1133             :   void
    1134             :   UpdateOverridenLoadGroup(nsILoadGroup* aBaseLoadGroup);
    1135             : 
    1136             :   void
    1137             :   WorkerScriptLoaded();
    1138             : 
    1139             :   nsIDocument* GetDocument() const;
    1140             : 
    1141             :   void
    1142             :   MemoryPressure(bool aDummy);
    1143             : 
    1144             :   void
    1145             :   UpdateContextOptions(const JS::ContextOptions& aContextOptions);
    1146             : 
    1147             :   void
    1148             :   UpdateLanguages(const nsTArray<nsString>& aLanguages);
    1149             : 
    1150             :   void
    1151             :   UpdateJSWorkerMemoryParameter(JSGCParamKey key, uint32_t value);
    1152             : 
    1153             : #ifdef JS_GC_ZEAL
    1154             :   void
    1155             :   UpdateGCZeal(uint8_t aGCZeal, uint32_t aFrequency);
    1156             : #endif
    1157             : 
    1158             :   void
    1159             :   OfflineStatusChangeEvent(bool aIsOffline);
    1160             : 
    1161             :   nsresult
    1162             :   Dispatch(already_AddRefed<WorkerRunnable> aRunnable,
    1163             :            nsIEventTarget* aSyncLoopTarget = nullptr);
    1164             : 
    1165             :   nsresult
    1166             :   DispatchControlRunnable(already_AddRefed<WorkerControlRunnable> aWorkerControlRunnable);
    1167             : 
    1168             :   nsresult
    1169             :   DispatchDebuggerRunnable(already_AddRefed<WorkerRunnable> aDebuggerRunnable);
    1170             : 
    1171             : #ifdef DEBUG
    1172             :   void
    1173             :   AssertIsOnParentThread() const;
    1174             : 
    1175             :   void
    1176             :   AssertInnerWindowIsCorrect() const;
    1177             : #else
    1178             :   void
    1179             :   AssertIsOnParentThread() const
    1180             :   { }
    1181             : 
    1182             :   void
    1183             :   AssertInnerWindowIsCorrect() const
    1184             :   { }
    1185             : #endif
    1186             : 
    1187             : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
    1188             :   bool
    1189             :   PrincipalIsValid() const;
    1190             : #endif
    1191             : 
    1192             :   void
    1193             :   StartCancelingTimer();
    1194             : 
    1195             : private:
    1196             :   WorkerPrivate(WorkerPrivate* aParent,
    1197             :                 const nsAString& aScriptURL, bool aIsChromeWorker,
    1198             :                 WorkerType aWorkerType, const nsAString& aWorkerName,
    1199             :                 const nsACString& aServiceWorkerScope,
    1200             :                 WorkerLoadInfo& aLoadInfo);
    1201             : 
    1202             :   ~WorkerPrivate();
    1203             : 
    1204             :   bool
    1205             :   MayContinueRunning()
    1206             :   {
    1207             :     AssertIsOnWorkerThread();
    1208             : 
    1209             :     WorkerStatus status;
    1210             :     {
    1211             :       MutexAutoLock lock(mMutex);
    1212             :       status = mStatus;
    1213             :     }
    1214             : 
    1215             :     if (status < Terminating) {
    1216             :       return true;
    1217             :     }
    1218             : 
    1219             :     return false;
    1220             :   }
    1221             : 
    1222             :   void
    1223             :   CancelAllTimeouts();
    1224             : 
    1225             :   enum class ProcessAllControlRunnablesResult
    1226             :   {
    1227             :     // We did not process anything.
    1228             :     Nothing,
    1229             :     // We did process something, states may have changed, but we can keep
    1230             :     // executing script.
    1231             :     MayContinue,
    1232             :     // We did process something, and should not continue executing script.
    1233             :     Abort
    1234             :   };
    1235             : 
    1236             :   ProcessAllControlRunnablesResult
    1237             :   ProcessAllControlRunnables()
    1238             :   {
    1239             :     MutexAutoLock lock(mMutex);
    1240             :     return ProcessAllControlRunnablesLocked();
    1241             :   }
    1242             : 
    1243             :   ProcessAllControlRunnablesResult
    1244             :   ProcessAllControlRunnablesLocked();
    1245             : 
    1246             :   void
    1247             :   EnableMemoryReporter();
    1248             : 
    1249             :   void
    1250             :   DisableMemoryReporter();
    1251             : 
    1252             :   void
    1253             :   WaitForWorkerEvents();
    1254             : 
    1255             :   // If the worker shutdown status is equal or greater then aFailStatus, this
    1256             :   // operation will fail and nullptr will be returned. See WorkerHolder.h for
    1257             :   // more information about the correct value to use.
    1258             :   already_AddRefed<nsIEventTarget>
    1259             :   CreateNewSyncLoop(WorkerStatus aFailStatus);
    1260             : 
    1261             :   bool
    1262             :   RunCurrentSyncLoop();
    1263             : 
    1264             :   bool
    1265             :   DestroySyncLoop(uint32_t aLoopIndex);
    1266             : 
    1267             :   void
    1268             :   InitializeGCTimers();
    1269             : 
    1270             :   enum GCTimerMode
    1271             :   {
    1272             :     PeriodicTimer = 0,
    1273             :     IdleTimer,
    1274             :     NoTimer
    1275             :   };
    1276             : 
    1277             :   void
    1278             :   SetGCTimerMode(GCTimerMode aMode);
    1279             : 
    1280             :   void
    1281             :   ShutdownGCTimers();
    1282             : 
    1283             :   bool
    1284             :   AddHolder(WorkerHolder* aHolder, WorkerStatus aFailStatus);
    1285             : 
    1286             :   void
    1287             :   RemoveHolder(WorkerHolder* aHolder);
    1288             : 
    1289             :   void
    1290             :   NotifyHolders(WorkerStatus aStatus);
    1291             : 
    1292             :   bool
    1293             :   HasActiveHolders()
    1294             :   {
    1295             :     return !(mChildWorkers.IsEmpty() && mTimeouts.IsEmpty() &&
    1296             :              mHolders.IsEmpty());
    1297             :   }
    1298             : 
    1299             :   class EventTarget;
    1300             :   friend class EventTarget;
    1301             :   friend class mozilla::dom::WorkerHolder;
    1302             :   friend class AutoSyncLoopHolder;
    1303             : 
    1304             :   struct TimeoutInfo;
    1305             : 
    1306             :   class MemoryReporter;
    1307             :   friend class MemoryReporter;
    1308             : 
    1309             :   friend class mozilla::dom::WorkerThread;
    1310             : 
    1311             :   SharedMutex mMutex;
    1312             :   mozilla::CondVar mCondVar;
    1313             : 
    1314             :   WorkerPrivate* mParent;
    1315             : 
    1316             :   nsString mScriptURL;
    1317             : 
    1318             :   // This is the worker name for shared workers and dedicated workers.
    1319             :   nsString mWorkerName;
    1320             : 
    1321             :   WorkerType mWorkerType;
    1322             : 
    1323             :   // The worker is owned by its thread, which is represented here.  This is set
    1324             :   // in Constructor() and emptied by WorkerFinishedRunnable, and conditionally
    1325             :   // traversed by the cycle collector if the busy count is zero.
    1326             :   //
    1327             :   // There are 4 ways a worker can be terminated:
    1328             :   // 1. GC/CC - When the worker is in idle state (busycount == 0), it allows to
    1329             :   //    traverse the 'hidden' mParentEventTargetRef pointer. This is the exposed
    1330             :   //    Worker webidl object. Doing this, CC will be able to detect a cycle and
    1331             :   //    Unlink is called. In Unlink, Worker calls Terminate().
    1332             :   // 2. Worker::Terminate() is called - the shutdown procedure starts
    1333             :   //    immediately.
    1334             :   // 3. WorkerScope::Close() is called - Similar to point 2.
    1335             :   // 4. xpcom-shutdown notification - We call Kill().
    1336             :   RefPtr<Worker> mParentEventTargetRef;
    1337             :   RefPtr<WorkerPrivate> mSelfRef;
    1338             : 
    1339             :   // The lifetime of these objects within LoadInfo is managed explicitly;
    1340             :   // they do not need to be cycle collected.
    1341             :   WorkerLoadInfo mLoadInfo;
    1342             :   LocationInfo mLocationInfo;
    1343             : 
    1344             :   // Protected by mMutex.
    1345             :   workerinternals::JSSettings mJSSettings;
    1346             : 
    1347             :   WorkerDebugger* mDebugger;
    1348             : 
    1349             :   workerinternals::Queue<WorkerControlRunnable*, 4> mControlQueue;
    1350             :   workerinternals::Queue<WorkerRunnable*, 4> mDebuggerQueue;
    1351             : 
    1352             :   // Touched on multiple threads, protected with mMutex.
    1353             :   JSContext* mJSContext;
    1354             :   RefPtr<WorkerThread> mThread;
    1355             :   PRThread* mPRThread;
    1356             : 
    1357             :   // Things touched on worker thread only.
    1358             :   RefPtr<WorkerGlobalScope> mScope;
    1359             :   RefPtr<WorkerDebuggerGlobalScope> mDebuggerScope;
    1360             :   nsTArray<WorkerPrivate*> mChildWorkers;
    1361             :   nsTObserverArray<WorkerHolder*> mHolders;
    1362             :   nsTArray<nsAutoPtr<TimeoutInfo>> mTimeouts;
    1363             :   RefPtr<ThrottledEventQueue> mMainThreadThrottledEventQueue;
    1364             :   nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
    1365             :   RefPtr<WorkerEventTarget> mWorkerControlEventTarget;
    1366             :   RefPtr<WorkerEventTarget> mWorkerHybridEventTarget;
    1367             : 
    1368             :   struct SyncLoopInfo
    1369             :   {
    1370             :     explicit SyncLoopInfo(EventTarget* aEventTarget);
    1371             : 
    1372             :     RefPtr<EventTarget> mEventTarget;
    1373             :     bool mCompleted;
    1374             :     bool mResult;
    1375             : #ifdef DEBUG
    1376             :     bool mHasRun;
    1377             : #endif
    1378             :   };
    1379             : 
    1380             :   // This is only modified on the worker thread, but in DEBUG builds
    1381             :   // AssertValidSyncLoop function iterates it on other threads. Therefore
    1382             :   // modifications are done with mMutex held *only* in DEBUG builds.
    1383             :   nsTArray<nsAutoPtr<SyncLoopInfo>> mSyncLoopStack;
    1384             : 
    1385             :   nsCOMPtr<nsITimer> mTimer;
    1386             :   nsCOMPtr<nsITimerCallback> mTimerRunnable;
    1387             : 
    1388             :   nsCOMPtr<nsITimer> mCancelingTimer;
    1389             : 
    1390             :   nsCOMPtr<nsITimer> mGCTimer;
    1391             : 
    1392             :   RefPtr<MemoryReporter> mMemoryReporter;
    1393             : 
    1394             :   // fired on the main thread if the worker script fails to load
    1395             :   nsCOMPtr<nsIRunnable> mLoadFailedRunnable;
    1396             : 
    1397             :   RefPtr<PerformanceStorage> mPerformanceStorage;
    1398             : 
    1399             :   // Only used for top level workers.
    1400             :   nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
    1401             : 
    1402             :   // Protected by mMutex.
    1403             :   nsTArray<RefPtr<WorkerRunnable>> mPreStartRunnables;
    1404             : 
    1405             :   // Only touched on the parent thread (currently this is always the main
    1406             :   // thread as SharedWorkers are always top-level).
    1407             :   nsTArray<RefPtr<SharedWorker>> mSharedWorkers;
    1408             : 
    1409             :   JS::UniqueChars mDefaultLocale; // nulled during worker JSContext init
    1410             :   TimeStamp mKillTime;
    1411             :   WorkerStatus mParentStatus;
    1412             :   WorkerStatus mStatus;
    1413             :   UniquePtr<ClientSource> mClientSource;
    1414             : 
    1415             :   // This is touched on parent thread only, but it can be read on a different
    1416             :   // thread before crashing because hanging.
    1417             :   Atomic<uint64_t> mBusyCount;
    1418             : 
    1419             :   Atomic<bool> mLoadingWorkerScript;
    1420             : 
    1421             :   TimeStamp mCreationTimeStamp;
    1422             :   DOMHighResTimeStamp mCreationTimeHighRes;
    1423             : 
    1424             :   // Things touched on worker thread only.
    1425             :   uint32_t mNumHoldersPreventingShutdownStart;
    1426             :   uint32_t mDebuggerEventLoopLevel;
    1427             : 
    1428             :   uint32_t mErrorHandlerRecursionCount;
    1429             :   uint32_t mNextTimeoutId;
    1430             : 
    1431             :   // SharedWorkers may have multiple windows paused, so this must be
    1432             :   // a count instead of just a boolean.
    1433             :   uint32_t mParentWindowPausedDepth;
    1434             : 
    1435             :   bool mFrozen;
    1436             :   bool mTimerRunning;
    1437             :   bool mRunningExpiredTimeouts;
    1438             :   bool mPendingEventQueueClearing;
    1439             :   bool mCancelAllPendingRunnables;
    1440             :   bool mPeriodicGCTimerRunning;
    1441             :   bool mIdleGCTimerRunning;
    1442             :   bool mWorkerScriptExecutedSuccessfully;
    1443             :   bool mFetchHandlerWasAdded;
    1444             :   bool mOnLine;
    1445             :   bool mMainThreadObjectsForgotten;
    1446             :   bool mIsChromeWorker;
    1447             :   bool mParentFrozen;
    1448             : 
    1449             :   // mIsSecureContext is set once in our constructor; after that it can be read
    1450             :   // from various threads.  We could make this const if we were OK with setting
    1451             :   // it in the initializer list via calling some function that takes all sorts
    1452             :   // of state (loadinfo, worker type, parent).
    1453             :   //
    1454             :   // It's a bit unfortunate that we have to have an out-of-band boolean for
    1455             :   // this, but we need access to this state from the parent thread, and we can't
    1456             :   // use our global object's secure state there.
    1457             :   bool mIsSecureContext;
    1458             : 
    1459             :   bool mDebuggerRegistered;
    1460             : 
    1461             :   // mIsInAutomation is true when we're running in test automation.
    1462             :   // We expose some extra testing functions in that case.
    1463             :   bool mIsInAutomation;
    1464             : 
    1465             :   // This pointer will be null if dom.performance.enable_scheduler_timing is
    1466             :   // false (default value)
    1467             :   RefPtr<mozilla::PerformanceCounter> mPerformanceCounter;
    1468             : };
    1469             : 
    1470             : class AutoSyncLoopHolder
    1471             : {
    1472             :   WorkerPrivate* mWorkerPrivate;
    1473             :   nsCOMPtr<nsIEventTarget> mTarget;
    1474             :   uint32_t mIndex;
    1475             : 
    1476             : public:
    1477             :   // See CreateNewSyncLoop() for more information about the correct value to use
    1478             :   // for aFailStatus.
    1479           0 :   AutoSyncLoopHolder(WorkerPrivate* aWorkerPrivate, WorkerStatus aFailStatus)
    1480           0 :   : mWorkerPrivate(aWorkerPrivate)
    1481           0 :   , mTarget(aWorkerPrivate->CreateNewSyncLoop(aFailStatus))
    1482           0 :   , mIndex(aWorkerPrivate->mSyncLoopStack.Length() - 1)
    1483             :   {
    1484           0 :     aWorkerPrivate->AssertIsOnWorkerThread();
    1485           0 :   }
    1486             : 
    1487           0 :   ~AutoSyncLoopHolder()
    1488           0 :   {
    1489           0 :     if (mWorkerPrivate && mTarget) {
    1490           0 :       mWorkerPrivate->AssertIsOnWorkerThread();
    1491           0 :       mWorkerPrivate->StopSyncLoop(mTarget, false);
    1492           0 :       mWorkerPrivate->DestroySyncLoop(mIndex);
    1493             :     }
    1494           0 :   }
    1495             : 
    1496             :   bool
    1497           0 :   Run()
    1498             :   {
    1499           0 :     WorkerPrivate* workerPrivate = mWorkerPrivate;
    1500           0 :     mWorkerPrivate = nullptr;
    1501             : 
    1502           0 :     workerPrivate->AssertIsOnWorkerThread();
    1503             : 
    1504           2 :     return workerPrivate->RunCurrentSyncLoop();
    1505             :   }
    1506             : 
    1507             :   nsIEventTarget*
    1508             :   GetEventTarget() const
    1509             :   {
    1510             :     // This can be null if CreateNewSyncLoop() fails.
    1511           2 :     return mTarget;
    1512             :   }
    1513             : };
    1514             : 
    1515             : } // dom namespace
    1516             : } // mozilla namespace
    1517             : 
    1518             : #endif /* mozilla_dom_workers_workerprivate_h__ */

Generated by: LCOV version 1.13-14-ga5dd952