michael@0: /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_dom_workers_workers_h__ michael@0: #define mozilla_dom_workers_workers_h__ michael@0: michael@0: #include "jsapi.h" michael@0: #include "mozilla/Attributes.h" michael@0: #include "mozilla/Mutex.h" michael@0: #include michael@0: #include "nsAutoPtr.h" michael@0: #include "nsCOMPtr.h" michael@0: #include "nsDebug.h" michael@0: #include "nsString.h" michael@0: michael@0: #define BEGIN_WORKERS_NAMESPACE \ michael@0: namespace mozilla { namespace dom { namespace workers { michael@0: #define END_WORKERS_NAMESPACE \ michael@0: } /* namespace workers */ } /* namespace dom */ } /* namespace mozilla */ michael@0: #define USING_WORKERS_NAMESPACE \ michael@0: using namespace mozilla::dom::workers; michael@0: michael@0: #define WORKERS_SHUTDOWN_TOPIC "web-workers-shutdown" michael@0: michael@0: class nsIScriptContext; michael@0: class nsPIDOMWindow; michael@0: michael@0: BEGIN_WORKERS_NAMESPACE michael@0: michael@0: class WorkerPrivate; michael@0: michael@0: struct PrivatizableBase michael@0: { }; michael@0: michael@0: #ifdef DEBUG michael@0: void michael@0: AssertIsOnMainThread(); michael@0: #else michael@0: inline void michael@0: AssertIsOnMainThread() michael@0: { } michael@0: #endif michael@0: michael@0: struct JSSettings michael@0: { michael@0: enum { michael@0: // All the GC parameters that we support. michael@0: JSSettings_JSGC_MAX_BYTES = 0, michael@0: JSSettings_JSGC_MAX_MALLOC_BYTES, michael@0: JSSettings_JSGC_HIGH_FREQUENCY_TIME_LIMIT, michael@0: JSSettings_JSGC_LOW_FREQUENCY_HEAP_GROWTH, michael@0: JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MIN, michael@0: JSSettings_JSGC_HIGH_FREQUENCY_HEAP_GROWTH_MAX, michael@0: JSSettings_JSGC_HIGH_FREQUENCY_LOW_LIMIT, michael@0: JSSettings_JSGC_HIGH_FREQUENCY_HIGH_LIMIT, michael@0: JSSettings_JSGC_ALLOCATION_THRESHOLD, michael@0: JSSettings_JSGC_SLICE_TIME_BUDGET, michael@0: JSSettings_JSGC_DYNAMIC_HEAP_GROWTH, michael@0: JSSettings_JSGC_DYNAMIC_MARK_SLICE, michael@0: // JSGC_MODE not supported michael@0: michael@0: // This must be last so that we get an accurate count. michael@0: kGCSettingsArraySize michael@0: }; michael@0: michael@0: struct JSGCSetting michael@0: { michael@0: JSGCParamKey key; michael@0: uint32_t value; michael@0: michael@0: JSGCSetting() michael@0: : key(static_cast(-1)), value(0) michael@0: { } michael@0: michael@0: bool michael@0: IsSet() const michael@0: { michael@0: return key != static_cast(-1); michael@0: } michael@0: michael@0: void michael@0: Unset() michael@0: { michael@0: key = static_cast(-1); michael@0: value = 0; michael@0: } michael@0: }; michael@0: michael@0: // There are several settings that we know we need so it makes sense to michael@0: // preallocate here. michael@0: typedef JSGCSetting JSGCSettingsArray[kGCSettingsArraySize]; michael@0: michael@0: // Settings that change based on chrome/content context. michael@0: struct JSContentChromeSettings michael@0: { michael@0: JS::ContextOptions contextOptions; michael@0: JS::CompartmentOptions compartmentOptions; michael@0: int32_t maxScriptRuntime; michael@0: michael@0: JSContentChromeSettings() michael@0: : contextOptions(), compartmentOptions(), maxScriptRuntime(0) michael@0: { } michael@0: }; michael@0: michael@0: JSContentChromeSettings chrome; michael@0: JSContentChromeSettings content; michael@0: JSGCSettingsArray gcSettings; michael@0: JS::RuntimeOptions runtimeOptions; michael@0: michael@0: #ifdef JS_GC_ZEAL michael@0: uint8_t gcZeal; michael@0: uint32_t gcZealFrequency; michael@0: #endif michael@0: michael@0: JSSettings() michael@0: #ifdef JS_GC_ZEAL michael@0: : gcZeal(0), gcZealFrequency(0) michael@0: #endif michael@0: { michael@0: for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) { michael@0: new (gcSettings + index) JSGCSetting(); michael@0: } michael@0: } michael@0: michael@0: bool michael@0: ApplyGCSetting(JSGCParamKey aKey, uint32_t aValue) michael@0: { michael@0: JSSettings::JSGCSetting* firstEmptySetting = nullptr; michael@0: JSSettings::JSGCSetting* foundSetting = nullptr; michael@0: michael@0: for (uint32_t index = 0; index < ArrayLength(gcSettings); index++) { michael@0: JSSettings::JSGCSetting& setting = gcSettings[index]; michael@0: if (setting.key == aKey) { michael@0: foundSetting = &setting; michael@0: break; michael@0: } michael@0: if (!firstEmptySetting && !setting.IsSet()) { michael@0: firstEmptySetting = &setting; michael@0: } michael@0: } michael@0: michael@0: if (aValue) { michael@0: if (!foundSetting) { michael@0: foundSetting = firstEmptySetting; michael@0: if (!foundSetting) { michael@0: NS_ERROR("Not enough space for this value!"); michael@0: return false; michael@0: } michael@0: } michael@0: foundSetting->key = aKey; michael@0: foundSetting->value = aValue; michael@0: return true; michael@0: } michael@0: michael@0: if (foundSetting) { michael@0: foundSetting->Unset(); michael@0: return true; michael@0: } michael@0: michael@0: return false; michael@0: } michael@0: }; michael@0: michael@0: enum WorkerPreference michael@0: { michael@0: WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled michael@0: WORKERPREF_COUNT michael@0: }; michael@0: michael@0: // All of these are implemented in RuntimeService.cpp michael@0: bool michael@0: ResolveWorkerClasses(JSContext* aCx, JS::Handle aObj, JS::Handle aId, michael@0: JS::MutableHandle aObjp); michael@0: michael@0: void michael@0: CancelWorkersForWindow(nsPIDOMWindow* aWindow); michael@0: michael@0: void michael@0: SuspendWorkersForWindow(nsPIDOMWindow* aWindow); michael@0: michael@0: void michael@0: ResumeWorkersForWindow(nsPIDOMWindow* aWindow); michael@0: michael@0: class WorkerTask michael@0: { michael@0: protected: michael@0: WorkerTask() michael@0: { } michael@0: michael@0: virtual ~WorkerTask() michael@0: { } michael@0: michael@0: public: michael@0: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerTask) michael@0: michael@0: virtual bool michael@0: RunTask(JSContext* aCx) = 0; michael@0: }; michael@0: michael@0: class WorkerCrossThreadDispatcher michael@0: { michael@0: friend class WorkerPrivate; michael@0: michael@0: // Must be acquired *before* the WorkerPrivate's mutex, when they're both michael@0: // held. michael@0: Mutex mMutex; michael@0: WorkerPrivate* mWorkerPrivate; michael@0: michael@0: private: michael@0: // Only created by WorkerPrivate. michael@0: WorkerCrossThreadDispatcher(WorkerPrivate* aWorkerPrivate); michael@0: michael@0: // Only called by WorkerPrivate. michael@0: void michael@0: Forget() michael@0: { michael@0: MutexAutoLock lock(mMutex); michael@0: mWorkerPrivate = nullptr; michael@0: } michael@0: michael@0: public: michael@0: NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WorkerCrossThreadDispatcher) michael@0: michael@0: // Generically useful function for running a bit of C++ code on the worker michael@0: // thread. michael@0: bool michael@0: PostTask(WorkerTask* aTask); michael@0: }; michael@0: michael@0: WorkerCrossThreadDispatcher* michael@0: GetWorkerCrossThreadDispatcher(JSContext* aCx, jsval aWorker); michael@0: michael@0: // Random unique constant to facilitate JSPrincipal debugging michael@0: const uint32_t kJSPrincipalsDebugToken = 0x7e2df9d2; michael@0: michael@0: namespace exceptions { michael@0: michael@0: // Implemented in Exceptions.cpp michael@0: void michael@0: ThrowDOMExceptionForNSResult(JSContext* aCx, nsresult aNSResult); michael@0: michael@0: } // namespace exceptions michael@0: michael@0: // Throws the JSMSG_GETTER_ONLY exception. This shouldn't be used going michael@0: // forward -- getter-only properties should just use JS_PSG for the setter michael@0: // (implying no setter at all), which will not throw when set in non-strict michael@0: // code but will in strict code. Old code should use this only for temporary michael@0: // compatibility reasons. michael@0: extern bool michael@0: GetterOnlyJSNative(JSContext* aCx, unsigned aArgc, JS::Value* aVp); michael@0: michael@0: END_WORKERS_NAMESPACE michael@0: michael@0: #endif // mozilla_dom_workers_workers_h__