LCOV - code coverage report
Current view: top level - dom/workers - Workers.h (source / functions) Hit Total Coverage
Test: output.info Lines: 32 48 66.7 %
Date: 2017-07-14 16:53:18 Functions: 5 13 38.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : /* This Source Code Form is subject to the terms of the Mozilla Public
       4             :  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
       5             :  * You can obtain one at http://mozilla.org/MPL/2.0/. */
       6             : 
       7             : #ifndef mozilla_dom_workers_workers_h__
       8             : #define mozilla_dom_workers_workers_h__
       9             : 
      10             : #include "jsapi.h"
      11             : #include "mozilla/Attributes.h"
      12             : #include "mozilla/Mutex.h"
      13             : #include <stdint.h>
      14             : #include "nsAutoPtr.h"
      15             : #include "nsCOMPtr.h"
      16             : #include "nsDebug.h"
      17             : #include "nsString.h"
      18             : #include "nsTArray.h"
      19             : 
      20             : #include "nsILoadContext.h"
      21             : #include "nsIWeakReferenceUtils.h"
      22             : #include "nsIInterfaceRequestor.h"
      23             : #include "mozilla/dom/ChannelInfo.h"
      24             : #include "mozilla/net/ReferrerPolicy.h"
      25             : 
      26             : #define BEGIN_WORKERS_NAMESPACE \
      27             :   namespace mozilla { namespace dom { namespace workers {
      28             : #define END_WORKERS_NAMESPACE \
      29             :   } /* namespace workers */ } /* namespace dom */ } /* namespace mozilla */
      30             : #define USING_WORKERS_NAMESPACE \
      31             :   using namespace mozilla::dom::workers;
      32             : 
      33             : #define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown"
      34             : 
      35             : class nsIContentSecurityPolicy;
      36             : class nsIScriptContext;
      37             : class nsIGlobalObject;
      38             : class nsPIDOMWindowInner;
      39             : class nsIPrincipal;
      40             : class nsILoadGroup;
      41             : class nsITabChild;
      42             : class nsIChannel;
      43             : class nsIRunnable;
      44             : class nsIURI;
      45             : 
      46             : namespace mozilla {
      47             : namespace ipc {
      48             : class PrincipalInfo;
      49             : } // namespace ipc
      50             : 
      51             : namespace dom {
      52             : // If you change this, the corresponding list in nsIWorkerDebugger.idl needs to
      53             : // be updated too.
      54             : enum WorkerType
      55             : {
      56             :   WorkerTypeDedicated,
      57             :   WorkerTypeShared,
      58             :   WorkerTypeService
      59             : };
      60             : 
      61             : } // namespace dom
      62             : } // namespace mozilla
      63             : 
      64             : BEGIN_WORKERS_NAMESPACE
      65             : 
      66             : class WorkerPrivate;
      67             : 
      68             : struct PrivatizableBase
      69             : { };
      70             : 
      71             : #ifdef DEBUG
      72             : void
      73             : AssertIsOnMainThread();
      74             : #else
      75             : inline void
      76             : AssertIsOnMainThread()
      77             : { }
      78             : #endif
      79             : 
      80             : struct JSSettings
      81             : {
      82             :   enum {
      83             :     // All the GC parameters that we support.
      84             :     JSSettings_JSGC_MAX_BYTES = 0,
      85             :     JSSettings_JSGC_MAX_MALLOC_BYTES,
      86             :     JSSettings_JSGC_HIGH_FREQUENCY_TIME_LIMIT,
      87             :     JSSettings_JSGC_LOW_FREQUENCY_HEAP_GROWTH,
      88             :     JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN,
      89             :     JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,
      90             :     JSSettings_JSGC_HIGH_FREQUENCY_LOW_LIMIT,
      91             :     JSSettings_JSGC_HIGH_FREQUENCY_HIGH_LIMIT,
      92             :     JSSettings_JSGC_ALLOCATION_THRESHOLD,
      93             :     JSSettings_JSGC_SLICE_TIME_BUDGET,
      94             :     JSSettings_JSGC_DYNAMIC_HEAP_GROWTH,
      95             :     JSSettings_JSGC_DYNAMIC_MARK_SLICE,
      96             :     JSSettings_JSGC_REFRESH_FRAME_SLICES,
      97             :     // JSGC_MODE not supported
      98             : 
      99             :     // This must be last so that we get an accurate count.
     100             :     kGCSettingsArraySize
     101             :   };
     102             : 
     103             :   struct JSGCSetting
     104             :   {
     105             :     JSGCParamKey key;
     106             :     uint32_t value;
     107             : 
     108         130 :     JSGCSetting()
     109         130 :     : key(static_cast<JSGCParamKey>(-1)), value(0)
     110         130 :     { }
     111             : 
     112             :     bool
     113         103 :     IsSet() const
     114             :     {
     115         103 :       return key != static_cast<JSGCParamKey>(-1);
     116             :     }
     117             : 
     118             :     void
     119           0 :     Unset()
     120             :     {
     121           0 :       key = static_cast<JSGCParamKey>(-1);
     122           0 :       value = 0;
     123           0 :     }
     124             :   };
     125             : 
     126             :   // There are several settings that we know we need so it makes sense to
     127             :   // preallocate here.
     128             :   typedef JSGCSetting JSGCSettingsArray[kGCSettingsArraySize];
     129             : 
     130             :   // Settings that change based on chrome/content context.
     131             :   struct JSContentChromeSettings
     132             :   {
     133             :     JS::CompartmentOptions compartmentOptions;
     134             :     int32_t maxScriptRuntime;
     135             : 
     136          10 :     JSContentChromeSettings()
     137          10 :     : compartmentOptions(), maxScriptRuntime(0)
     138          10 :     { }
     139             :   };
     140             : 
     141             :   JSContentChromeSettings chrome;
     142             :   JSContentChromeSettings content;
     143             :   JSGCSettingsArray gcSettings;
     144             :   JS::ContextOptions contextOptions;
     145             : 
     146             : #ifdef JS_GC_ZEAL
     147             :   uint8_t gcZeal;
     148             :   uint32_t gcZealFrequency;
     149             : #endif
     150             : 
     151           5 :   JSSettings()
     152             : #ifdef JS_GC_ZEAL
     153           5 :   : gcZeal(0), gcZealFrequency(0)
     154             : #endif
     155             :   {
     156          70 :     for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
     157          65 :       new (gcSettings + index) JSGCSetting();
     158             :     }
     159           5 :   }
     160             : 
     161             :   bool
     162          15 :   ApplyGCSetting(JSGCParamKey aKey, uint32_t aValue)
     163             :   {
     164          15 :     JSSettings::JSGCSetting* firstEmptySetting = nullptr;
     165          15 :     JSSettings::JSGCSetting* foundSetting = nullptr;
     166             : 
     167         185 :     for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
     168         172 :       JSSettings::JSGCSetting& setting = gcSettings[index];
     169         172 :       if (setting.key == aKey) {
     170           2 :         foundSetting = &setting;
     171           2 :         break;
     172             :       }
     173         170 :       if (!firstEmptySetting && !setting.IsSet()) {
     174          13 :         firstEmptySetting = &setting;
     175             :       }
     176             :     }
     177             : 
     178          15 :     if (aValue) {
     179          13 :       if (!foundSetting) {
     180          11 :         foundSetting = firstEmptySetting;
     181          11 :         if (!foundSetting) {
     182           0 :           NS_ERROR("Not enough space for this value!");
     183           0 :           return false;
     184             :         }
     185             :       }
     186          13 :       foundSetting->key = aKey;
     187          13 :       foundSetting->value = aValue;
     188          13 :       return true;
     189             :     }
     190             : 
     191           2 :     if (foundSetting) {
     192           0 :       foundSetting->Unset();
     193           0 :       return true;
     194             :     }
     195             : 
     196           2 :     return false;
     197             :   }
     198             : };
     199             : 
     200             : enum WorkerPreference
     201             : {
     202             : #define WORKER_SIMPLE_PREF(name, getter, NAME) WORKERPREF_ ## NAME,
     203             : #define WORKER_PREF(name, callback)
     204             : #include "mozilla/dom/WorkerPrefs.h"
     205             : #undef WORKER_SIMPLE_PREF
     206             : #undef WORKER_PREF
     207             :   WORKERPREF_COUNT
     208             : };
     209             : 
     210             : // Implemented in WorkerPrivate.cpp
     211             : 
     212             : struct WorkerLoadInfo
     213             : {
     214             :   // All of these should be released in WorkerPrivateParent::ForgetMainThreadObjects.
     215             :   nsCOMPtr<nsIURI> mBaseURI;
     216             :   nsCOMPtr<nsIURI> mResolvedScriptURI;
     217             :   nsCOMPtr<nsIPrincipal> mPrincipal;
     218             :   nsCOMPtr<nsIScriptContext> mScriptContext;
     219             :   nsCOMPtr<nsPIDOMWindowInner> mWindow;
     220             :   nsCOMPtr<nsIContentSecurityPolicy> mCSP;
     221             :   nsCOMPtr<nsIChannel> mChannel;
     222             :   nsCOMPtr<nsILoadGroup> mLoadGroup;
     223             : 
     224             :   // mLoadFailedAsyncRunnable will execute on main thread if script loading
     225             :   // fails during script loading.  If script loading is never started due to
     226             :   // a synchronous error, then the runnable is never executed.  The runnable
     227             :   // is guaranteed to be released on the main thread.
     228             :   nsCOMPtr<nsIRunnable> mLoadFailedAsyncRunnable;
     229             : 
     230             :   class InterfaceRequestor final : public nsIInterfaceRequestor
     231             :   {
     232             :     NS_DECL_ISUPPORTS
     233             : 
     234             :   public:
     235             :     InterfaceRequestor(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
     236             :     void MaybeAddTabChild(nsILoadGroup* aLoadGroup);
     237             :     NS_IMETHOD GetInterface(const nsIID& aIID, void** aSink) override;
     238             : 
     239             :   private:
     240           0 :     ~InterfaceRequestor() { }
     241             : 
     242             :     already_AddRefed<nsITabChild> GetAnyLiveTabChild();
     243             : 
     244             :     nsCOMPtr<nsILoadContext> mLoadContext;
     245             :     nsCOMPtr<nsIInterfaceRequestor> mOuterRequestor;
     246             : 
     247             :     // Array of weak references to nsITabChild.  We do not want to keep TabChild
     248             :     // actors alive for long after their ActorDestroy() methods are called.
     249             :     nsTArray<nsWeakPtr> mTabChildList;
     250             :   };
     251             : 
     252             :   // Only set if we have a custom overriden load group
     253             :   RefPtr<InterfaceRequestor> mInterfaceRequestor;
     254             : 
     255             :   nsAutoPtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
     256             :   nsCString mDomain;
     257             :   nsString mOrigin; // Derived from mPrincipal; can be used on worker thread.
     258             : 
     259             :   nsString mServiceWorkerCacheName;
     260             : 
     261             :   ChannelInfo mChannelInfo;
     262             :   nsLoadFlags mLoadFlags;
     263             : 
     264             :   uint64_t mWindowID;
     265             :   uint64_t mServiceWorkerID;
     266             : 
     267             :   net::ReferrerPolicy mReferrerPolicy;
     268             :   bool mFromWindow;
     269             :   bool mEvalAllowed;
     270             :   bool mReportCSPViolations;
     271             :   bool mXHRParamsAllowed;
     272             :   bool mPrincipalIsSystem;
     273             :   bool mStorageAllowed;
     274             :   bool mServiceWorkersTestingInWindow;
     275             :   OriginAttributes mOriginAttributes;
     276             : 
     277             :   WorkerLoadInfo();
     278             :   ~WorkerLoadInfo();
     279             : 
     280             :   void StealFrom(WorkerLoadInfo& aOther);
     281             : 
     282             :   nsresult
     283             :   SetPrincipalOnMainThread(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
     284             : 
     285             :   nsresult
     286             :   GetPrincipalAndLoadGroupFromChannel(nsIChannel* aChannel,
     287             :                                       nsIPrincipal** aPrincipalOut,
     288             :                                       nsILoadGroup** aLoadGroupOut);
     289             : 
     290             :   nsresult
     291             :   SetPrincipalFromChannel(nsIChannel* aChannel);
     292             : 
     293             : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
     294             :   bool
     295             :   FinalChannelPrincipalIsValid(nsIChannel* aChannel);
     296             : 
     297             :   bool
     298             :   PrincipalIsValid() const;
     299             : 
     300             :   bool
     301             :   PrincipalURIMatchesScriptURL();
     302             : #endif
     303             : 
     304             :   bool
     305             :   ProxyReleaseMainThreadObjects(WorkerPrivate* aWorkerPrivate);
     306             : 
     307             :   bool
     308             :   ProxyReleaseMainThreadObjects(WorkerPrivate* aWorkerPrivate,
     309             :                                 nsCOMPtr<nsILoadGroup>& aLoadGroupToCancel);
     310             : };
     311             : 
     312             : // All of these are implemented in RuntimeService.cpp
     313             : 
     314             : void
     315             : CancelWorkersForWindow(nsPIDOMWindowInner* aWindow);
     316             : 
     317             : void
     318             : FreezeWorkersForWindow(nsPIDOMWindowInner* aWindow);
     319             : 
     320             : void
     321             : ThawWorkersForWindow(nsPIDOMWindowInner* aWindow);
     322             : 
     323             : void
     324             : SuspendWorkersForWindow(nsPIDOMWindowInner* aWindow);
     325             : 
     326             : void
     327             : ResumeWorkersForWindow(nsPIDOMWindowInner* aWindow);
     328             : 
     329             : // A class that can be used with WorkerCrossThreadDispatcher to run a
     330             : // bit of C++ code on the worker thread.
     331             : class WorkerTask
     332             : {
     333             : protected:
     334             :   WorkerTask()
     335             :   { }
     336             : 
     337             :   virtual ~WorkerTask()
     338             :   { }
     339             : 
     340             : public:
     341           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerTask)
     342             : 
     343             :   // The return value here has the same semantics as the return value
     344             :   // of WorkerRunnable::WorkerRun.
     345             :   virtual bool
     346             :   RunTask(JSContext* aCx) = 0;
     347             : };
     348             : 
     349             : class WorkerCrossThreadDispatcher
     350             : {
     351             :    friend class WorkerPrivate;
     352             : 
     353             :   // Must be acquired *before* the WorkerPrivate's mutex, when they're both
     354             :   // held.
     355             :   Mutex mMutex;
     356             :   WorkerPrivate* mWorkerPrivate;
     357             : 
     358             : private:
     359             :   // Only created by WorkerPrivate.
     360             :   explicit WorkerCrossThreadDispatcher(WorkerPrivate* aWorkerPrivate);
     361             : 
     362             :   // Only called by WorkerPrivate.
     363             :   void
     364           0 :   Forget()
     365             :   {
     366           0 :     MutexAutoLock lock(mMutex);
     367           0 :     mWorkerPrivate = nullptr;
     368           0 :   }
     369             : 
     370           0 :   ~WorkerCrossThreadDispatcher() {}
     371             : 
     372             : public:
     373           0 :   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerCrossThreadDispatcher)
     374             : 
     375             :   // Generically useful function for running a bit of C++ code on the worker
     376             :   // thread.
     377             :   bool
     378             :   PostTask(WorkerTask* aTask);
     379             : };
     380             : 
     381             : WorkerCrossThreadDispatcher*
     382             : GetWorkerCrossThreadDispatcher(JSContext* aCx, const JS::Value& aWorker);
     383             : 
     384             : // Random unique constant to facilitate JSPrincipal debugging
     385             : const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2;
     386             : 
     387             : bool
     388             : IsWorkerGlobal(JSObject* global);
     389             : 
     390             : bool
     391             : IsDebuggerGlobal(JSObject* global);
     392             : 
     393             : bool
     394             : IsDebuggerSandbox(JSObject* object);
     395             : 
     396             : END_WORKERS_NAMESPACE
     397             : 
     398             : #endif // mozilla_dom_workers_workers_h__

Generated by: LCOV version 1.13