зеркало из https://github.com/mozilla/gecko-dev.git
Bug 936700 - Worker Preferences cache. r=bent
This commit is contained in:
Родитель
c78157de46
Коммит
e8f2e2d695
|
@ -20,8 +20,6 @@
|
|||
#include "nsPIDOMWindow.h"
|
||||
#include "nsJSEnvironment.h"
|
||||
|
||||
#include "mozilla/dom/RuntimeService.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
|
@ -256,23 +254,14 @@ Promise::EnabledForScope(JSContext* aCx, JSObject* /* unused */)
|
|||
return true;
|
||||
}
|
||||
} else {
|
||||
RuntimeService* service = RuntimeService::GetService();
|
||||
MOZ_ASSERT(service);
|
||||
// Can't just do return ... since the chrome worker/certified app checks
|
||||
// below should also run.
|
||||
if (service->PromiseEnabled()) {
|
||||
return true;
|
||||
}
|
||||
WorkerPrivate* workerPrivate = GetWorkerPrivateFromContext(aCx);
|
||||
return workerPrivate->PromiseEnabled() || workerPrivate->UsesSystemPrincipal();
|
||||
}
|
||||
// Enable if the pref is enabled or if we're chrome or if we're a
|
||||
// certified app.
|
||||
// Note that we have no concept of a certified app in workers.
|
||||
// XXXbz well, why not?
|
||||
// FIXME(nsm): Remove these checks once promises are enabled by default.
|
||||
if (!NS_IsMainThread()) {
|
||||
return workers::GetWorkerPrivateFromContext(aCx)->UsesSystemPrincipal();
|
||||
}
|
||||
|
||||
nsIPrincipal* prin = nsContentUtils::GetSubjectPrincipal();
|
||||
return nsContentUtils::IsSystemPrincipal(prin) ||
|
||||
prin->GetAppStatus() == nsIPrincipal::APP_STATUS_CERTIFIED;
|
||||
|
|
|
@ -56,11 +56,6 @@ WorkerPrivate::RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool promiseEnabled = false;
|
||||
RuntimeService* service = RuntimeService::GetService();
|
||||
MOZ_ASSERT(service);
|
||||
promiseEnabled = service->PromiseEnabled();
|
||||
|
||||
// Init other paris-bindings.
|
||||
if (!DOMExceptionBinding::GetConstructorObject(aCx, aGlobal) ||
|
||||
!EventBinding::GetConstructorObject(aCx, aGlobal) ||
|
||||
|
@ -68,7 +63,8 @@ WorkerPrivate::RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal)
|
|||
!ImageDataBinding::GetConstructorObject(aCx, aGlobal) ||
|
||||
!MessageEventBinding::GetConstructorObject(aCx, aGlobal) ||
|
||||
!MessagePortBinding::GetConstructorObject(aCx, aGlobal) ||
|
||||
(promiseEnabled && !PromiseBinding::GetConstructorObject(aCx, aGlobal)) ||
|
||||
(PromiseEnabled() &&
|
||||
!PromiseBinding::GetConstructorObject(aCx, aGlobal)) ||
|
||||
!TextDecoderBinding::GetConstructorObject(aCx, aGlobal) ||
|
||||
!TextEncoderBinding::GetConstructorObject(aCx, aGlobal) ||
|
||||
!XMLHttpRequestBinding_workers::GetConstructorObject(aCx, aGlobal) ||
|
||||
|
|
|
@ -176,43 +176,10 @@ static_assert(NS_ARRAY_LENGTH(gStringChars) == ID_COUNT,
|
|||
#if !(defined(DEBUG) || defined(MOZ_ENABLE_JS_DUMP))
|
||||
#define DUMP_CONTROLLED_BY_PREF 1
|
||||
#define PREF_DOM_WINDOW_DUMP_ENABLED "browser.dom.window.dump.enabled"
|
||||
|
||||
// Protected by RuntimeService::mMutex.
|
||||
// Initialized by DumpPrefChanged via RuntimeService::Init().
|
||||
bool gWorkersDumpEnabled;
|
||||
|
||||
static int
|
||||
DumpPrefChanged(const char* aPrefName, void* aClosure)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
bool enabled = Preferences::GetBool(PREF_DOM_WINDOW_DUMP_ENABLED, false);
|
||||
|
||||
Mutex* mutex = static_cast<Mutex*>(aClosure);
|
||||
MutexAutoLock lock(*mutex);
|
||||
gWorkersDumpEnabled = enabled;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define PREF_PROMISE_ENABLED "dom.promise.enabled"
|
||||
|
||||
// Protected by RuntimeService::mMutex.
|
||||
bool gPromiseEnabled;
|
||||
|
||||
static int
|
||||
PromiseEnableChanged(const char* aPrefName, void* aClosure)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
bool enabled = Preferences::GetBool(PREF_PROMISE_ENABLED, false);
|
||||
|
||||
Mutex* mutex = static_cast<Mutex*>(aClosure);
|
||||
MutexAutoLock lock(*mutex);
|
||||
gPromiseEnabled = enabled;
|
||||
return 0;
|
||||
}
|
||||
|
||||
class LiteralRebindingCString : public nsDependentCString
|
||||
{
|
||||
public:
|
||||
|
@ -1177,6 +1144,7 @@ END_WORKERS_NAMESPACE
|
|||
|
||||
// This is only touched on the main thread. Initialized in Init() below.
|
||||
JSSettings RuntimeService::sDefaultJSSettings;
|
||||
bool RuntimeService::sDefaultPreferences[WORKERPREF_COUNT] = { false };
|
||||
|
||||
RuntimeService::RuntimeService()
|
||||
: mMutex("RuntimeService::mMutex"), mObserved(false),
|
||||
|
@ -1587,6 +1555,11 @@ RuntimeService::Init()
|
|||
WORKER_DEFAULT_ALLOCATION_THRESHOLD);
|
||||
}
|
||||
|
||||
// If dump is not controlled by pref, it's set to true.
|
||||
#ifndef DUMP_CONTROLLED_BY_PREF
|
||||
sDefaultPreferences[WORKERPREF_DUMP] = true;
|
||||
#endif
|
||||
|
||||
mIdleThreadTimer = do_CreateInstance(NS_TIMER_CONTRACTID);
|
||||
NS_ENSURE_STATE(mIdleThreadTimer);
|
||||
|
||||
|
@ -1642,14 +1615,14 @@ RuntimeService::Init()
|
|||
#endif
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
DumpPrefChanged,
|
||||
WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
&mMutex)) ||
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
NS_FAILED(Preferences::RegisterCallbackAndCall(
|
||||
PromiseEnableChanged,
|
||||
WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
&mMutex)) ||
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
NS_FAILED(Preferences::RegisterCallback(LoadJSContextOptions,
|
||||
PREF_JS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
|
@ -1812,13 +1785,13 @@ RuntimeService::Cleanup()
|
|||
NS_FAILED(Preferences::UnregisterCallback(LoadJSContextOptions,
|
||||
PREF_WORKERS_OPTIONS_PREFIX,
|
||||
nullptr)) ||
|
||||
NS_FAILED(Preferences::UnregisterCallback(PromiseEnableChanged,
|
||||
NS_FAILED(Preferences::UnregisterCallback(WorkerPrefChanged,
|
||||
PREF_PROMISE_ENABLED,
|
||||
&mMutex)) ||
|
||||
reinterpret_cast<void *>(WORKERPREF_PROMISE))) ||
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
NS_FAILED(Preferences::UnregisterCallback(DumpPrefChanged,
|
||||
NS_FAILED(Preferences::UnregisterCallback(WorkerPrefChanged,
|
||||
PREF_DOM_WINDOW_DUMP_ENABLED,
|
||||
&mMutex)) ||
|
||||
reinterpret_cast<void *>(WORKERPREF_DUMP))) ||
|
||||
#endif
|
||||
#ifdef JS_GC_ZEAL
|
||||
NS_FAILED(Preferences::UnregisterCallback(
|
||||
|
@ -2196,6 +2169,12 @@ RuntimeService::UpdateAllWorkerJSContextOptions()
|
|||
sDefaultJSSettings.chrome.options);
|
||||
}
|
||||
|
||||
void
|
||||
RuntimeService::UpdateAllWorkerPreference(WorkerPreference aPref, bool aValue)
|
||||
{
|
||||
BROADCAST_ALL_WORKERS(UpdatePreference, aPref, aValue);
|
||||
}
|
||||
|
||||
void
|
||||
RuntimeService::UpdateAllWorkerMemoryParameter(JSGCParamKey aKey,
|
||||
uint32_t aValue)
|
||||
|
@ -2255,22 +2234,33 @@ RuntimeService::Observe(nsISupports* aSubject, const char* aTopic,
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
RuntimeService::WorkersDumpEnabled()
|
||||
/* static */ int
|
||||
RuntimeService::WorkerPrefChanged(const char* aPrefName, void* aClosure)
|
||||
{
|
||||
#if DUMP_CONTROLLED_BY_PREF
|
||||
MutexAutoLock lock(mMutex);
|
||||
// In optimized builds we check a pref that controls if we should
|
||||
// enable output from dump() or not, in debug builds it's always
|
||||
// enabled.
|
||||
return gWorkersDumpEnabled;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
AssertIsOnMainThread();
|
||||
|
||||
bool
|
||||
RuntimeService::PromiseEnabled()
|
||||
{
|
||||
return gPromiseEnabled;
|
||||
uintptr_t tmp = reinterpret_cast<uintptr_t>(aClosure);
|
||||
MOZ_ASSERT(tmp >= 0 && tmp < WORKERPREF_COUNT);
|
||||
WorkerPreference key = static_cast<WorkerPreference>(tmp);
|
||||
|
||||
if (key == WORKERPREF_PROMISE) {
|
||||
sDefaultPreferences[WORKERPREF_PROMISE] =
|
||||
Preferences::GetBool(PREF_PROMISE_ENABLED, false);
|
||||
#ifdef DUMP_CONTROLLED_BY_PREF
|
||||
} else if (key == WORKERPREF_DUMP) {
|
||||
key = WORKERPREF_DUMP;
|
||||
sDefaultPreferences[WORKERPREF_DUMP] =
|
||||
Preferences::GetBool(PREF_DOM_WINDOW_DUMP_ENABLED, false);
|
||||
#endif
|
||||
}
|
||||
|
||||
// This function should never be registered as a callback for a preference it
|
||||
// does not handle.
|
||||
MOZ_ASSERT(key != WORKERPREF_COUNT);
|
||||
|
||||
RuntimeService* rts = RuntimeService::GetService();
|
||||
if (rts) {
|
||||
rts->UpdateAllWorkerPreference(key, sDefaultPreferences[key]);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ class RuntimeService MOZ_FINAL : public nsIObserver
|
|||
nsCString mSystemCharset;
|
||||
|
||||
static JSSettings sDefaultJSSettings;
|
||||
static bool sDefaultPreferences[WORKERPREF_COUNT];
|
||||
|
||||
public:
|
||||
struct NavigatorStrings
|
||||
|
@ -181,6 +182,13 @@ public:
|
|||
aSettings = sDefaultJSSettings;
|
||||
}
|
||||
|
||||
static void
|
||||
GetDefaultPreferences(bool aPreferences[WORKERPREF_COUNT])
|
||||
{
|
||||
AssertIsOnMainThread();
|
||||
memcpy(aPreferences, sDefaultPreferences, WORKERPREF_COUNT * sizeof(bool));
|
||||
}
|
||||
|
||||
static void
|
||||
SetDefaultJSContextOptions(const JS::ContextOptions& aContentOptions,
|
||||
const JS::ContextOptions& aChromeOptions)
|
||||
|
@ -193,6 +201,9 @@ public:
|
|||
void
|
||||
UpdateAllWorkerJSContextOptions();
|
||||
|
||||
void
|
||||
UpdateAllWorkerPreference(WorkerPreference aPref, bool aValue);
|
||||
|
||||
static void
|
||||
SetDefaultJSGCSettings(JSGCParamKey aKey, uint32_t aValue)
|
||||
{
|
||||
|
@ -241,12 +252,6 @@ public:
|
|||
void
|
||||
GarbageCollectAllWorkers(bool aShrinking);
|
||||
|
||||
bool
|
||||
WorkersDumpEnabled();
|
||||
|
||||
bool
|
||||
PromiseEnabled();
|
||||
|
||||
private:
|
||||
RuntimeService();
|
||||
~RuntimeService();
|
||||
|
@ -284,6 +289,9 @@ private:
|
|||
|
||||
static void
|
||||
ShutdownIdleThreads(nsITimer* aTimer, void* aClosure);
|
||||
|
||||
static int
|
||||
WorkerPrefChanged(const char* aPrefName, void* aClosure);
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
|
|
@ -1465,6 +1465,29 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
class UpdatePreferenceRunnable : public WorkerControlRunnable
|
||||
{
|
||||
WorkerPreference mPref;
|
||||
bool mValue;
|
||||
|
||||
public:
|
||||
UpdatePreferenceRunnable(WorkerPrivate* aWorkerPrivate,
|
||||
WorkerPreference aPref,
|
||||
bool aValue)
|
||||
: WorkerControlRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount),
|
||||
mPref(aPref),
|
||||
mValue(aValue)
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
|
||||
{
|
||||
aWorkerPrivate->UpdatePreferenceInternal(aCx, mPref, mValue);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
class UpdateJSWorkerMemoryParameterRunnable : public WorkerControlRunnable
|
||||
{
|
||||
uint32_t mValue;
|
||||
|
@ -2778,6 +2801,21 @@ WorkerPrivateParent<Derived>::UpdateJSContextOptions(JSContext* aCx,
|
|||
}
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue)
|
||||
{
|
||||
AssertIsOnParentThread();
|
||||
MOZ_ASSERT(aPref >= 0 && aPref < WORKERPREF_COUNT);
|
||||
|
||||
nsRefPtr<UpdatePreferenceRunnable> runnable =
|
||||
new UpdatePreferenceRunnable(ParentAsWorkerPrivate(), aPref, aValue);
|
||||
if (!runnable->Dispatch(aCx)) {
|
||||
NS_WARNING("Failed to update worker preferences!");
|
||||
JS_ClearPendingException(aCx);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
void
|
||||
WorkerPrivateParent<Derived>::UpdateJSWorkerMemoryParameter(JSContext* aCx,
|
||||
|
@ -3284,6 +3322,15 @@ WorkerPrivate::WorkerPrivate(JSContext* aCx,
|
|||
{
|
||||
MOZ_ASSERT_IF(IsSharedWorker(), !aSharedWorkerName.IsVoid());
|
||||
MOZ_ASSERT_IF(!IsSharedWorker(), aSharedWorkerName.IsEmpty());
|
||||
|
||||
if (aParent) {
|
||||
aParent->AssertIsOnWorkerThread();
|
||||
aParent->GetAllPreferences(mPreferences);
|
||||
}
|
||||
else {
|
||||
AssertIsOnMainThread();
|
||||
RuntimeService::GetDefaultPreferences(mPreferences);
|
||||
}
|
||||
}
|
||||
|
||||
WorkerPrivate::~WorkerPrivate()
|
||||
|
@ -5083,6 +5130,19 @@ WorkerPrivate::UpdateJSContextOptionsInternal(JSContext* aCx,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue)
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
MOZ_ASSERT(aPref >= 0 && aPref < WORKERPREF_COUNT);
|
||||
|
||||
mPreferences[aPref] = aValue;
|
||||
|
||||
for (uint32_t index = 0; index < mChildWorkers.Length(); index++) {
|
||||
mChildWorkers[index]->UpdatePreference(aCx, aPref, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WorkerPrivate::UpdateJSWorkerMemoryParameterInternal(JSContext* aCx,
|
||||
JSGCParamKey aKey,
|
||||
|
|
|
@ -476,6 +476,9 @@ public:
|
|||
UpdateJSContextOptions(JSContext* aCx, const JS::ContextOptions& aChromeOptions,
|
||||
const JS::ContextOptions& aContentOptions);
|
||||
|
||||
void
|
||||
UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue);
|
||||
|
||||
void
|
||||
UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key,
|
||||
uint32_t value);
|
||||
|
@ -815,6 +818,8 @@ class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
|
|||
nsCOMPtr<nsIThread> mThread;
|
||||
#endif
|
||||
|
||||
bool mPreferences[WORKERPREF_COUNT];
|
||||
|
||||
protected:
|
||||
~WorkerPrivate();
|
||||
|
||||
|
@ -977,6 +982,9 @@ public:
|
|||
UpdateJSContextOptionsInternal(JSContext* aCx, const JS::ContextOptions& aContentOptions,
|
||||
const JS::ContextOptions& aChromeOptions);
|
||||
|
||||
void
|
||||
UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue);
|
||||
|
||||
void
|
||||
UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
|
||||
|
||||
|
@ -1069,6 +1077,20 @@ public:
|
|||
bool
|
||||
RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
|
||||
|
||||
bool
|
||||
DumpEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_DUMP];
|
||||
}
|
||||
|
||||
bool
|
||||
PromiseEnabled() const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
return mPreferences[WORKERPREF_PROMISE];
|
||||
}
|
||||
|
||||
private:
|
||||
WorkerPrivate(JSContext* aCx, WorkerPrivate* aParent,
|
||||
const nsAString& aScriptURL, bool aIsChromeWorker,
|
||||
|
@ -1146,6 +1168,13 @@ private:
|
|||
bool aToMessagePort,
|
||||
uint64_t aMessagePortSerial,
|
||||
ErrorResult& aRv);
|
||||
|
||||
void
|
||||
GetAllPreferences(bool aPreferences[WORKERPREF_COUNT]) const
|
||||
{
|
||||
AssertIsOnWorkerThread();
|
||||
memcpy(aPreferences, mPreferences, WORKERPREF_COUNT * sizeof(bool));
|
||||
}
|
||||
};
|
||||
|
||||
// This class is only used to trick the DOM bindings. We never create
|
||||
|
|
|
@ -237,7 +237,7 @@ WorkerGlobalScope::Dump(const Optional<nsAString>& aString) const
|
|||
RuntimeService* runtimeService = RuntimeService::GetService();
|
||||
MOZ_ASSERT(runtimeService);
|
||||
|
||||
if (!runtimeService->WorkersDumpEnabled()) {
|
||||
if (!mWorkerPrivate->DumpEnabled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -162,6 +162,13 @@ struct JSSettings
|
|||
}
|
||||
};
|
||||
|
||||
enum WorkerPreference
|
||||
{
|
||||
WORKERPREF_DUMP = 0, // browser.dom.window.dump.enabled
|
||||
WORKERPREF_PROMISE, // dom.promise.enabled
|
||||
WORKERPREF_COUNT
|
||||
};
|
||||
|
||||
// All of these are implemented in RuntimeService.cpp
|
||||
bool
|
||||
ResolveWorkerClasses(JSContext* aCx, JS::Handle<JSObject*> aObj, JS::Handle<jsid> aId,
|
||||
|
|
|
@ -8,7 +8,6 @@ TEST_DIRS += ['test']
|
|||
|
||||
# Public stuff.
|
||||
EXPORTS.mozilla.dom += [
|
||||
'RuntimeService.h',
|
||||
'WorkerPrivate.h',
|
||||
'WorkerScope.h',
|
||||
]
|
||||
|
|
Загрузка…
Ссылка в новой задаче