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