1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/dom/workers/Workers.h Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,256 @@ 1.4 +/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this file, 1.7 + * You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#ifndef mozilla_dom_workers_workers_h__ 1.10 +#define mozilla_dom_workers_workers_h__ 1.11 + 1.12 +#include "jsapi.h" 1.13 +#include "mozilla/Attributes.h" 1.14 +#include "mozilla/Mutex.h" 1.15 +#include <stdint.h> 1.16 +#include "nsAutoPtr.h" 1.17 +#include "nsCOMPtr.h" 1.18 +#include "nsDebug.h" 1.19 +#include "nsString.h" 1.20 + 1.21 +#define BEGIN_WORKERS_NAMESPACE \ 1.22 + namespace mozilla { namespace dom { namespace workers { 1.23 +#define END_WORKERS_NAMESPACE \ 1.24 + } /* namespace workers */ } /* namespace dom */ } /* namespace mozilla */ 1.25 +#define USING_WORKERS_NAMESPACE \ 1.26 + using namespace mozilla::dom::workers; 1.27 + 1.28 +#define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown" 1.29 + 1.30 +class nsIScriptContext; 1.31 +class nsPIDOMWindow; 1.32 + 1.33 +BEGIN_WORKERS_NAMESPACE 1.34 + 1.35 +class WorkerPrivate; 1.36 + 1.37 +struct PrivatizableBase 1.38 +{ }; 1.39 + 1.40 +#ifdef DEBUG 1.41 +void 1.42 +AssertIsOnMainThread(); 1.43 +#else 1.44 +inline void 1.45 +AssertIsOnMainThread() 1.46 +{ } 1.47 +#endif 1.48 + 1.49 +struct JSSettings 1.50 +{ 1.51 + enum { 1.52 + // All the GC parameters that we support. 1.53 + JSSettings_JSGC_MAX_BYTES = 0, 1.54 + JSSettings_JSGC_MAX_MALLOC_BYTES, 1.55 + JSSettings_JSGC_HIGH_FREQUENCY_TIME_LIMIT, 1.56 + JSSettings_JSGC_LOW_FREQUENCY_HEAP_GROWTH, 1.57 + JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, 1.58 + JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, 1.59 + JSSettings_JSGC_HIGH_FREQUENCY_LOW_LIMIT, 1.60 + JSSettings_JSGC_HIGH_FREQUENCY_HIGH_LIMIT, 1.61 + JSSettings_JSGC_ALLOCATION_THRESHOLD, 1.62 + JSSettings_JSGC_SLICE_TIME_BUDGET, 1.63 + JSSettings_JSGC_DYNAMIC_HEAP_GROWTH, 1.64 + JSSettings_JSGC_DYNAMIC_MARK_SLICE, 1.65 + // JSGC_MODE not supported 1.66 + 1.67 + // This must be last so that we get an accurate count. 1.68 + kGCSettingsArraySize 1.69 + }; 1.70 + 1.71 + struct JSGCSetting 1.72 + { 1.73 + JSGCParamKey key; 1.74 + uint32_t value; 1.75 + 1.76 + JSGCSetting() 1.77 + : key(static_cast<JSGCParamKey>(-1)), value(0) 1.78 + { } 1.79 + 1.80 + bool 1.81 + IsSet() const 1.82 + { 1.83 + return key != static_cast<JSGCParamKey>(-1); 1.84 + } 1.85 + 1.86 + void 1.87 + Unset() 1.88 + { 1.89 + key = static_cast<JSGCParamKey>(-1); 1.90 + value = 0; 1.91 + } 1.92 + }; 1.93 + 1.94 + // There are several settings that we know we need so it makes sense to 1.95 + // preallocate here. 1.96 + typedef JSGCSetting JSGCSettingsArray[kGCSettingsArraySize]; 1.97 + 1.98 + // Settings that change based on chrome/content context. 1.99 + struct JSContentChromeSettings 1.100 + { 1.101 + JS::ContextOptions contextOptions; 1.102 + JS::CompartmentOptions compartmentOptions; 1.103 + int32_t maxScriptRuntime; 1.104 + 1.105 + JSContentChromeSettings() 1.106 + : contextOptions(), compartmentOptions(), maxScriptRuntime(0) 1.107 + { } 1.108 + }; 1.109 + 1.110 + JSContentChromeSettings chrome; 1.111 + JSContentChromeSettings content; 1.112 + JSGCSettingsArray gcSettings; 1.113 + JS::RuntimeOptions runtimeOptions; 1.114 + 1.115 +#ifdef JS_GC_ZEAL 1.116 + uint8_t gcZeal; 1.117 + uint32_t gcZealFrequency; 1.118 +#endif 1.119 + 1.120 + JSSettings() 1.121 +#ifdef JS_GC_ZEAL 1.122 + : gcZeal(0), gcZealFrequency(0) 1.123 +#endif 1.124 + { 1.125 + for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) { 1.126 + new (gcSettings + index) JSGCSetting(); 1.127 + } 1.128 + } 1.129 + 1.130 + bool 1.131 + ApplyGCSetting(JSGCParamKey aKey, uint32_t aValue) 1.132 + { 1.133 + JSSettings::JSGCSetting* firstEmptySetting = nullptr; 1.134 + JSSettings::JSGCSetting* foundSetting = nullptr; 1.135 + 1.136 + for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) { 1.137 + JSSettings::JSGCSetting& setting = gcSettings[index]; 1.138 + if (setting.key == aKey) { 1.139 + foundSetting = &setting; 1.140 + break; 1.141 + } 1.142 + if (!firstEmptySetting && !setting.IsSet()) { 1.143 + firstEmptySetting = &setting; 1.144 + } 1.145 + } 1.146 + 1.147 + if (aValue) { 1.148 + if (!foundSetting) { 1.149 + foundSetting = firstEmptySetting; 1.150 + if (!foundSetting) { 1.151 + NS_ERROR("Not enough space for this value!"); 1.152 + return false; 1.153 + } 1.154 + } 1.155 + foundSetting->key = aKey; 1.156 + foundSetting->value = aValue; 1.157 + return true; 1.158 + } 1.159 + 1.160 + if (foundSetting) { 1.161 + foundSetting->Unset(); 1.162 + return true; 1.163 + } 1.164 + 1.165 + return false; 1.166 + } 1.167 +}; 1.168 + 1.169 +enum WorkerPreference 1.170 +{ 1.171 + WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled 1.172 + WORKERPREF_COUNT 1.173 +}; 1.174 + 1.175 +// All of these are implemented in RuntimeService.cpp 1.176 +bool 1.177 +ResolveWorkerClasses(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId, 1.178 + JS::MutableHandle<JSObject*> aObjp); 1.179 + 1.180 +void 1.181 +CancelWorkersForWindow(nsPIDOMWindow* aWindow); 1.182 + 1.183 +void 1.184 +SuspendWorkersForWindow(nsPIDOMWindow* aWindow); 1.185 + 1.186 +void 1.187 +ResumeWorkersForWindow(nsPIDOMWindow* aWindow); 1.188 + 1.189 +class WorkerTask 1.190 +{ 1.191 +protected: 1.192 + WorkerTask() 1.193 + { } 1.194 + 1.195 + virtual ~WorkerTask() 1.196 + { } 1.197 + 1.198 +public: 1.199 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerTask) 1.200 + 1.201 + virtual bool 1.202 + RunTask(JSContext* aCx) = 0; 1.203 +}; 1.204 + 1.205 +class WorkerCrossThreadDispatcher 1.206 +{ 1.207 + friend class WorkerPrivate; 1.208 + 1.209 + // Must be acquired *before* the WorkerPrivate's mutex, when they're both 1.210 + // held. 1.211 + Mutex mMutex; 1.212 + WorkerPrivate* mWorkerPrivate; 1.213 + 1.214 +private: 1.215 + // Only created by WorkerPrivate. 1.216 + WorkerCrossThreadDispatcher(WorkerPrivate* aWorkerPrivate); 1.217 + 1.218 + // Only called by WorkerPrivate. 1.219 + void 1.220 + Forget() 1.221 + { 1.222 + MutexAutoLock lock(mMutex); 1.223 + mWorkerPrivate = nullptr; 1.224 + } 1.225 + 1.226 +public: 1.227 + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerCrossThreadDispatcher) 1.228 + 1.229 + // Generically useful function for running a bit of C++ code on the worker 1.230 + // thread. 1.231 + bool 1.232 + PostTask(WorkerTask* aTask); 1.233 +}; 1.234 + 1.235 +WorkerCrossThreadDispatcher* 1.236 +GetWorkerCrossThreadDispatcher(JSContext* aCx, jsval aWorker); 1.237 + 1.238 +// Random unique constant to facilitate JSPrincipal debugging 1.239 +const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2; 1.240 + 1.241 +namespace exceptions { 1.242 + 1.243 +// Implemented in Exceptions.cpp 1.244 +void 1.245 +ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult); 1.246 + 1.247 +} // namespace exceptions 1.248 + 1.249 +// Throws the JSMSG_GETTER_ONLY exception. This shouldn't be used going 1.250 +// forward -- getter-only properties should just use JS_PSG for the setter 1.251 +// (implying no setter at all), which will not throw when set in non-strict 1.252 +// code but will in strict code. Old code should use this only for temporary 1.253 +// compatibility reasons. 1.254 +extern bool 1.255 +GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp); 1.256 + 1.257 +END_WORKERS_NAMESPACE 1.258 + 1.259 +#endif // mozilla_dom_workers_workers_h__