michael@0: /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */ michael@0: /* vim: set ts=2 et sw=2 tw=80: */ 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 michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifndef mozilla_dom_workers_runtimeservice_h__ michael@0: #define mozilla_dom_workers_runtimeservice_h__ michael@0: michael@0: #include "Workers.h" michael@0: michael@0: #include "nsIObserver.h" michael@0: michael@0: #include "mozilla/TimeStamp.h" michael@0: #include "mozilla/dom/BindingDeclarations.h" michael@0: #include "nsClassHashtable.h" michael@0: #include "nsHashKeys.h" michael@0: #include "nsTArray.h" michael@0: michael@0: class nsIRunnable; michael@0: class nsIThread; michael@0: class nsITimer; michael@0: class nsPIDOMWindow; michael@0: michael@0: BEGIN_WORKERS_NAMESPACE michael@0: michael@0: class SharedWorker; michael@0: class WorkerPrivate; michael@0: michael@0: class RuntimeService MOZ_FINAL : public nsIObserver michael@0: { michael@0: public: michael@0: class WorkerThread; michael@0: michael@0: private: michael@0: struct SharedWorkerInfo michael@0: { michael@0: WorkerPrivate* mWorkerPrivate; michael@0: nsCString mScriptSpec; michael@0: nsCString mName; michael@0: michael@0: SharedWorkerInfo(WorkerPrivate* aWorkerPrivate, michael@0: const nsACString& aScriptSpec, michael@0: const nsACString& aName) michael@0: : mWorkerPrivate(aWorkerPrivate), mScriptSpec(aScriptSpec), mName(aName) michael@0: { } michael@0: }; michael@0: michael@0: struct WorkerDomainInfo michael@0: { michael@0: nsCString mDomain; michael@0: nsTArray mActiveWorkers; michael@0: nsTArray mQueuedWorkers; michael@0: nsClassHashtable mSharedWorkerInfos; michael@0: uint32_t mChildWorkerCount; michael@0: michael@0: WorkerDomainInfo() michael@0: : mActiveWorkers(1), mChildWorkerCount(0) michael@0: { } michael@0: michael@0: uint32_t michael@0: ActiveWorkerCount() const michael@0: { michael@0: return mActiveWorkers.Length() + mChildWorkerCount; michael@0: } michael@0: }; michael@0: michael@0: struct IdleThreadInfo michael@0: { michael@0: nsRefPtr mThread; michael@0: mozilla::TimeStamp mExpirationTime; michael@0: }; michael@0: michael@0: struct MatchSharedWorkerInfo michael@0: { michael@0: WorkerPrivate* mWorkerPrivate; michael@0: SharedWorkerInfo* mSharedWorkerInfo; michael@0: michael@0: MatchSharedWorkerInfo(WorkerPrivate* aWorkerPrivate) michael@0: : mWorkerPrivate(aWorkerPrivate), mSharedWorkerInfo(nullptr) michael@0: { } michael@0: }; michael@0: michael@0: mozilla::Mutex mMutex; michael@0: michael@0: // Protected by mMutex. michael@0: nsClassHashtable mDomainMap; michael@0: michael@0: // Protected by mMutex. michael@0: nsTArray mIdleThreadArray; michael@0: michael@0: // *Not* protected by mMutex. michael@0: nsClassHashtable, michael@0: nsTArray > mWindowMap; michael@0: michael@0: // Only used on the main thread. michael@0: nsCOMPtr mIdleThreadTimer; michael@0: michael@0: static JSSettings sDefaultJSSettings; michael@0: static bool sDefaultPreferences[WORKERPREF_COUNT]; michael@0: michael@0: public: michael@0: struct NavigatorProperties michael@0: { michael@0: nsString mAppName; michael@0: nsString mAppNameOverridden; michael@0: nsString mAppVersion; michael@0: nsString mAppVersionOverridden; michael@0: nsString mPlatform; michael@0: nsString mPlatformOverridden; michael@0: nsString mUserAgent; michael@0: }; michael@0: michael@0: private: michael@0: NavigatorProperties mNavigatorProperties; michael@0: michael@0: // True when the observer service holds a reference to this object. michael@0: bool mObserved; michael@0: bool mShuttingDown; michael@0: bool mNavigatorPropertiesLoaded; michael@0: michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIOBSERVER michael@0: michael@0: static RuntimeService* michael@0: GetOrCreateService(); michael@0: michael@0: static RuntimeService* michael@0: GetService(); michael@0: michael@0: bool michael@0: RegisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate); michael@0: michael@0: void michael@0: UnregisterWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate); 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: nsresult michael@0: CreateSharedWorker(const GlobalObject& aGlobal, michael@0: const nsAString& aScriptURL, michael@0: const nsACString& aName, michael@0: SharedWorker** aSharedWorker); michael@0: michael@0: void michael@0: ForgetSharedWorker(WorkerPrivate* aWorkerPrivate); michael@0: michael@0: const NavigatorProperties& michael@0: GetNavigatorProperties() const michael@0: { michael@0: return mNavigatorProperties; michael@0: } michael@0: michael@0: void michael@0: NoteIdleThread(WorkerThread* aThread); michael@0: michael@0: static void michael@0: GetDefaultJSSettings(JSSettings& aSettings) michael@0: { michael@0: AssertIsOnMainThread(); michael@0: aSettings = sDefaultJSSettings; michael@0: } michael@0: michael@0: static void michael@0: GetDefaultPreferences(bool aPreferences[WORKERPREF_COUNT]) michael@0: { michael@0: AssertIsOnMainThread(); michael@0: memcpy(aPreferences, sDefaultPreferences, WORKERPREF_COUNT * sizeof(bool)); michael@0: } michael@0: michael@0: static void michael@0: SetDefaultRuntimeAndContextOptions( michael@0: const JS::RuntimeOptions& aRuntimeOptions, michael@0: const JS::ContextOptions& aContentCxOptions, michael@0: const JS::ContextOptions& aChromeCxOptions) michael@0: { michael@0: AssertIsOnMainThread(); michael@0: sDefaultJSSettings.runtimeOptions = aRuntimeOptions; michael@0: sDefaultJSSettings.content.contextOptions = aContentCxOptions; michael@0: sDefaultJSSettings.chrome.contextOptions = aChromeCxOptions; michael@0: } michael@0: michael@0: void michael@0: UpdateAppNameOverridePreference(const nsAString& aValue); michael@0: michael@0: void michael@0: UpdateAppVersionOverridePreference(const nsAString& aValue); michael@0: michael@0: void michael@0: UpdatePlatformOverridePreference(const nsAString& aValue); michael@0: michael@0: void michael@0: UpdateAllWorkerRuntimeAndContextOptions(); michael@0: michael@0: void michael@0: UpdateAllWorkerPreference(WorkerPreference aPref, bool aValue); michael@0: michael@0: static void michael@0: SetDefaultJSGCSettings(JSGCParamKey aKey, uint32_t aValue) michael@0: { michael@0: AssertIsOnMainThread(); michael@0: sDefaultJSSettings.ApplyGCSetting(aKey, aValue); michael@0: } michael@0: michael@0: void michael@0: UpdateAllWorkerMemoryParameter(JSGCParamKey aKey, uint32_t aValue); michael@0: michael@0: static uint32_t michael@0: GetContentCloseHandlerTimeoutSeconds() michael@0: { michael@0: return sDefaultJSSettings.content.maxScriptRuntime; michael@0: } michael@0: michael@0: static uint32_t michael@0: GetChromeCloseHandlerTimeoutSeconds() michael@0: { michael@0: return sDefaultJSSettings.chrome.maxScriptRuntime; michael@0: } michael@0: michael@0: #ifdef JS_GC_ZEAL michael@0: static void michael@0: SetDefaultGCZeal(uint8_t aGCZeal, uint32_t aFrequency) michael@0: { michael@0: AssertIsOnMainThread(); michael@0: sDefaultJSSettings.gcZeal = aGCZeal; michael@0: sDefaultJSSettings.gcZealFrequency = aFrequency; michael@0: } michael@0: michael@0: void michael@0: UpdateAllWorkerGCZeal(); michael@0: #endif michael@0: michael@0: void michael@0: GarbageCollectAllWorkers(bool aShrinking); michael@0: michael@0: void michael@0: CycleCollectAllWorkers(); michael@0: michael@0: void michael@0: SendOfflineStatusChangeEventToAllWorkers(bool aIsOffline); michael@0: michael@0: private: michael@0: RuntimeService(); michael@0: ~RuntimeService(); michael@0: michael@0: nsresult michael@0: Init(); michael@0: michael@0: void michael@0: Shutdown(); michael@0: michael@0: void michael@0: Cleanup(); michael@0: michael@0: static PLDHashOperator michael@0: AddAllTopLevelWorkersToArray(const nsACString& aKey, michael@0: WorkerDomainInfo* aData, michael@0: void* aUserArg); michael@0: michael@0: static PLDHashOperator michael@0: RemoveSharedWorkerFromWindowMap(nsPIDOMWindow* aKey, michael@0: nsAutoPtr >& aData, michael@0: void* aUserArg); michael@0: michael@0: static PLDHashOperator michael@0: FindSharedWorkerInfo(const nsACString& aKey, michael@0: SharedWorkerInfo* aData, michael@0: void* aUserArg); michael@0: michael@0: void michael@0: GetWorkersForWindow(nsPIDOMWindow* aWindow, michael@0: nsTArray& aWorkers); michael@0: michael@0: bool michael@0: ScheduleWorker(JSContext* aCx, WorkerPrivate* aWorkerPrivate); michael@0: michael@0: static void michael@0: ShutdownIdleThreads(nsITimer* aTimer, void* aClosure); michael@0: michael@0: static void michael@0: WorkerPrefChanged(const char* aPrefName, void* aClosure); michael@0: michael@0: static void michael@0: JSVersionChanged(const char* aPrefName, void* aClosure); michael@0: }; michael@0: michael@0: END_WORKERS_NAMESPACE michael@0: michael@0: #endif /* mozilla_dom_workers_runtimeservice_h__ */