dom/workers/Workers.h

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

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

mercurial