dom/workers/Workers.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
     4  * You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #ifndef mozilla_dom_workers_workers_h__
     7 #define mozilla_dom_workers_workers_h__
     9 #include "jsapi.h"
    10 #include "mozilla/Attributes.h"
    11 #include "mozilla/Mutex.h"
    12 #include <stdint.h>
    13 #include "nsAutoPtr.h"
    14 #include "nsCOMPtr.h"
    15 #include "nsDebug.h"
    16 #include "nsString.h"
    18 #define BEGIN_WORKERS_NAMESPACE \
    19   namespace mozilla { namespace dom { namespace workers {
    20 #define END_WORKERS_NAMESPACE \
    21   } /* namespace workers */ } /* namespace dom */ } /* namespace mozilla */
    22 #define USING_WORKERS_NAMESPACE \
    23   using namespace mozilla::dom::workers;
    25 #define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown"
    27 class nsIScriptContext;
    28 class nsPIDOMWindow;
    30 BEGIN_WORKERS_NAMESPACE
    32 class WorkerPrivate;
    34 struct PrivatizableBase
    35 { };
    37 #ifdef DEBUG
    38 void
    39 AssertIsOnMainThread();
    40 #else
    41 inline void
    42 AssertIsOnMainThread()
    43 { }
    44 #endif
    46 struct JSSettings
    47 {
    48   enum {
    49     // All the GC parameters that we support.
    50     JSSettings_JSGC_MAX_BYTES = 0,
    51     JSSettings_JSGC_MAX_MALLOC_BYTES,
    52     JSSettings_JSGC_HIGH_FREQUENCY_TIME_LIMIT,
    53     JSSettings_JSGC_LOW_FREQUENCY_HEAP_GROWTH,
    54     JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN,
    55     JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX,
    56     JSSettings_JSGC_HIGH_FREQUENCY_LOW_LIMIT,
    57     JSSettings_JSGC_HIGH_FREQUENCY_HIGH_LIMIT,
    58     JSSettings_JSGC_ALLOCATION_THRESHOLD,
    59     JSSettings_JSGC_SLICE_TIME_BUDGET,
    60     JSSettings_JSGC_DYNAMIC_HEAP_GROWTH,
    61     JSSettings_JSGC_DYNAMIC_MARK_SLICE,
    62     // JSGC_MODE not supported
    64     // This must be last so that we get an accurate count.
    65     kGCSettingsArraySize
    66   };
    68   struct JSGCSetting
    69   {
    70     JSGCParamKey key;
    71     uint32_t value;
    73     JSGCSetting()
    74     : key(static_cast<JSGCParamKey>(-1)), value(0)
    75     { }
    77     bool
    78     IsSet() const
    79     {
    80       return key != static_cast<JSGCParamKey>(-1);
    81     }
    83     void
    84     Unset()
    85     {
    86       key = static_cast<JSGCParamKey>(-1);
    87       value = 0;
    88     }
    89   };
    91   // There are several settings that we know we need so it makes sense to
    92   // preallocate here.
    93   typedef JSGCSetting JSGCSettingsArray[kGCSettingsArraySize];
    95   // Settings that change based on chrome/content context.
    96   struct JSContentChromeSettings
    97   {
    98     JS::ContextOptions contextOptions;
    99     JS::CompartmentOptions compartmentOptions;
   100     int32_t maxScriptRuntime;
   102     JSContentChromeSettings()
   103     : contextOptions(), compartmentOptions(), maxScriptRuntime(0)
   104     { }
   105   };
   107   JSContentChromeSettings chrome;
   108   JSContentChromeSettings content;
   109   JSGCSettingsArray gcSettings;
   110   JS::RuntimeOptions runtimeOptions;
   112 #ifdef JS_GC_ZEAL
   113   uint8_t gcZeal;
   114   uint32_t gcZealFrequency;
   115 #endif
   117   JSSettings()
   118 #ifdef JS_GC_ZEAL
   119   : gcZeal(0), gcZealFrequency(0)
   120 #endif
   121   {
   122     for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
   123       new (gcSettings + index) JSGCSetting();
   124     }
   125   }
   127   bool
   128   ApplyGCSetting(JSGCParamKey aKey, uint32_t aValue)
   129   {
   130     JSSettings::JSGCSetting* firstEmptySetting = nullptr;
   131     JSSettings::JSGCSetting* foundSetting = nullptr;
   133     for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) {
   134       JSSettings::JSGCSetting& setting = gcSettings[index];
   135       if (setting.key == aKey) {
   136         foundSetting = &setting;
   137         break;
   138       }
   139       if (!firstEmptySetting && !setting.IsSet()) {
   140         firstEmptySetting = &setting;
   141       }
   142     }
   144     if (aValue) {
   145       if (!foundSetting) {
   146         foundSetting = firstEmptySetting;
   147         if (!foundSetting) {
   148           NS_ERROR("Not enough space for this value!");
   149           return false;
   150         }
   151       }
   152       foundSetting->key = aKey;
   153       foundSetting->value = aValue;
   154       return true;
   155     }
   157     if (foundSetting) {
   158       foundSetting->Unset();
   159       return true;
   160     }
   162     return false;
   163   }
   164 };
   166 enum WorkerPreference
   167 {
   168   WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled
   169   WORKERPREF_COUNT
   170 };
   172 // All of these are implemented in RuntimeService.cpp
   173 bool
   174 ResolveWorkerClasses(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
   175                      JS::MutableHandle<JSObject*> aObjp);
   177 void
   178 CancelWorkersForWindow(nsPIDOMWindow* aWindow);
   180 void
   181 SuspendWorkersForWindow(nsPIDOMWindow* aWindow);
   183 void
   184 ResumeWorkersForWindow(nsPIDOMWindow* aWindow);
   186 class WorkerTask
   187 {
   188 protected:
   189   WorkerTask()
   190   { }
   192   virtual ~WorkerTask()
   193   { }
   195 public:
   196   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerTask)
   198   virtual bool
   199   RunTask(JSContext* aCx) = 0;
   200 };
   202 class WorkerCrossThreadDispatcher
   203 {
   204    friend class WorkerPrivate;
   206   // Must be acquired *before* the WorkerPrivate's mutex, when they're both
   207   // held.
   208   Mutex mMutex;
   209   WorkerPrivate* mWorkerPrivate;
   211 private:
   212   // Only created by WorkerPrivate.
   213   WorkerCrossThreadDispatcher(WorkerPrivate* aWorkerPrivate);
   215   // Only called by WorkerPrivate.
   216   void
   217   Forget()
   218   {
   219     MutexAutoLock lock(mMutex);
   220     mWorkerPrivate = nullptr;
   221   }
   223 public:
   224   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerCrossThreadDispatcher)
   226   // Generically useful function for running a bit of C++ code on the worker
   227   // thread.
   228   bool
   229   PostTask(WorkerTask* aTask);
   230 };
   232 WorkerCrossThreadDispatcher*
   233 GetWorkerCrossThreadDispatcher(JSContext* aCx, jsval aWorker);
   235 // Random unique constant to facilitate JSPrincipal debugging
   236 const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2;
   238 namespace exceptions {
   240 // Implemented in Exceptions.cpp
   241 void
   242 ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult);
   244 } // namespace exceptions
   246 // Throws the JSMSG_GETTER_ONLY exception.  This shouldn't be used going
   247 // forward -- getter-only properties should just use JS_PSG for the setter
   248 // (implying no setter at all), which will not throw when set in non-strict
   249 // code but will in strict code.  Old code should use this only for temporary
   250 // compatibility reasons.
   251 extern bool
   252 GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp);
   254 END_WORKERS_NAMESPACE
   256 #endif // mozilla_dom_workers_workers_h__

mercurial