1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* 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_runtimeservice_h__
#define mozilla_dom_workers_runtimeservice_h__
#include "MainThreadUtils.h"
#include "js/ContextOptions.h"
#include "mozilla/Atomics.h"
#include "mozilla/Mutex.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/SafeRefPtr.h"
#include "mozilla/dom/WorkerCommon.h"
#include "mozilla/dom/workerinternals/JSSettings.h"
#include "nsClassHashtable.h"
#include "nsHashKeys.h"
#include "nsIObserver.h"
#include "nsTArray.h"
class nsPIDOMWindowInner;
namespace mozilla::dom {
struct WorkerLoadInfo;
class WorkerThread;
namespace workerinternals {
class RuntimeService final : public nsIObserver {
struct WorkerDomainInfo {
nsCString mDomain;
nsTArray<WorkerPrivate*> mActiveWorkers;
nsTArray<WorkerPrivate*> mActiveServiceWorkers;
nsTArray<WorkerPrivate*> mQueuedWorkers;
uint32_t mChildWorkerCount;
WorkerDomainInfo() : mActiveWorkers(1), mChildWorkerCount(0) {}
uint32_t ActiveWorkerCount() const {
return mActiveWorkers.Length() + mChildWorkerCount;
}
uint32_t ActiveServiceWorkerCount() const {
return mActiveServiceWorkers.Length();
}
bool HasNoWorkers() const {
return ActiveWorkerCount() == 0 && ActiveServiceWorkerCount() == 0;
}
};
mozilla::Mutex mMutex;
// Protected by mMutex.
nsClassHashtable<nsCStringHashKey, WorkerDomainInfo> mDomainMap
MOZ_GUARDED_BY(mMutex);
// *Not* protected by mMutex.
nsClassHashtable<nsPtrHashKey<const nsPIDOMWindowInner>,
nsTArray<WorkerPrivate*> >
mWindowMap;
static StaticAutoPtr<workerinternals::JSSettings> sDefaultJSSettings;
public:
struct NavigatorProperties {
nsString mAppVersion;
nsString mAppVersionOverridden;
nsString mPlatform;
nsString mPlatformOverridden;
CopyableTArray<nsString> mLanguages;
};
private:
NavigatorProperties mNavigatorProperties;
// True when the observer service holds a reference to this object.
bool mObserved;
bool mShuttingDown;
bool mNavigatorPropertiesLoaded;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
static RuntimeService* GetOrCreateService();
static RuntimeService* GetService();
bool RegisterWorker(WorkerPrivate& aWorkerPrivate);
void UnregisterWorker(WorkerPrivate& aWorkerPrivate);
void CancelWorkersForWindow(const nsPIDOMWindowInner& aWindow);
void UpdateWorkersBackgroundState(const nsPIDOMWindowInner& aWindow,
bool aIsBackground);
void UpdateWorkersPeerConnections(const nsPIDOMWindowInner& aWindow,
bool aHasPeerConnections);
void FreezeWorkersForWindow(const nsPIDOMWindowInner& aWindow);
void ThawWorkersForWindow(const nsPIDOMWindowInner& aWindow);
void SuspendWorkersForWindow(const nsPIDOMWindowInner& aWindow);
void ResumeWorkersForWindow(const nsPIDOMWindowInner& aWindow);
void PropagateStorageAccessPermissionGranted(
const nsPIDOMWindowInner& aWindow);
const NavigatorProperties& GetNavigatorProperties() const {
return mNavigatorProperties;
}
static void GetDefaultJSSettings(workerinternals::JSSettings& aSettings) {
AssertIsOnMainThread();
aSettings = *sDefaultJSSettings;
}
static void SetDefaultContextOptions(
const JS::ContextOptions& aContextOptions) {
AssertIsOnMainThread();
sDefaultJSSettings->contextOptions = aContextOptions;
}
void UpdateAppVersionOverridePreference(const nsAString& aValue);
void UpdatePlatformOverridePreference(const nsAString& aValue);
void UpdateAllWorkerContextOptions();
void UpdateAllWorkerLanguages(const nsTArray<nsString>& aLanguages);
static void SetDefaultJSGCSettings(JSGCParamKey aKey,
Maybe<uint32_t> aValue) {
AssertIsOnMainThread();
sDefaultJSSettings->ApplyGCSetting(aKey, aValue);
}
void UpdateAllWorkerMemoryParameter(JSGCParamKey aKey,
Maybe<uint32_t> aValue);
#ifdef JS_GC_ZEAL
static void SetDefaultGCZeal(uint8_t aGCZeal, uint32_t aFrequency) {
AssertIsOnMainThread();
sDefaultJSSettings->gcZeal = aGCZeal;
sDefaultJSSettings->gcZealFrequency = aFrequency;
}
void UpdateAllWorkerGCZeal();
#endif
void SetLowMemoryStateAllWorkers(bool aState);
void GarbageCollectAllWorkers(bool aShrinking);
void CycleCollectAllWorkers();
void SendOfflineStatusChangeEventToAllWorkers(bool aIsOffline);
void MemoryPressureAllWorkers();
uint32_t ClampedHardwareConcurrency(bool aRFPHardcoded,
bool aRFPTiered) const;
void CrashIfHanging();
bool IsShuttingDown() const { return mShuttingDown; }
void DumpRunningWorkers();
void UpdateWorkersPlaybackState(const nsPIDOMWindowInner& aWindow,
bool aIsPlayingAudio);
private:
RuntimeService();
~RuntimeService();
nsresult Init();
void Shutdown();
void Cleanup();
void AddAllTopLevelWorkersToArray(nsTArray<WorkerPrivate*>& aWorkers)
MOZ_REQUIRES(mMutex);
nsTArray<WorkerPrivate*> GetWorkersForWindow(
const nsPIDOMWindowInner& aWindow) const;
bool ScheduleWorker(WorkerPrivate& aWorkerPrivate);
template <typename Func>
void BroadcastAllWorkers(const Func& aFunc);
};
} // namespace workerinternals
} // namespace mozilla::dom
#endif /* mozilla_dom_workers_runtimeservice_h__ */
|