gecko/dom/workers/Workers.h
Bobby Holley 533944dd34 Bug 1029933 - Give BackstagePass an Enumerate hook to match its NewResolve hook. r=Waldo
This is required in order to avoid exposing resolve hook effects when
Object.freeze() is invoked on the global. The freeze() call first enumerates
the object, after which point any lazy properties need to be resolve so that
we can safely mark the object as non-extensible.
2014-07-04 12:41:27 -07:00

262 lines
6.1 KiB
C++

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