1 /* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef mozilla_dom_workers_workerprivate_h__
7 #define mozilla_dom_workers_workerprivate_h__
11 #include "nsIContentSecurityPolicy.h"
12 #include "nsILoadGroup.h"
13 #include "nsIWorkerDebugger.h"
14 #include "nsPIDOMWindow.h"
16 #include "mozilla/CondVar.h"
17 #include "mozilla/DOMEventTargetHelper.h"
18 #include "mozilla/TimeStamp.h"
19 #include "mozilla/dom/BindingDeclarations.h"
20 #include "nsAutoPtr.h"
21 #include "nsCycleCollectionParticipant.h"
22 #include "nsDataHashtable.h"
23 #include "nsHashKeys.h"
24 #include "nsRefPtrHashtable.h"
27 #include "nsThreadUtils.h"
28 #include "mozilla/dom/StructuredCloneTags.h"
31 #include "WorkerFeature.h"
33 class JSAutoStructuredCloneBuffer
;
38 class nsIScriptContext
;
40 class nsIThreadInternal
;
59 BEGIN_WORKERS_NAMESPACE
61 class AutoSyncLoopHolder
;
64 class WorkerControlRunnable
;
66 class WorkerGlobalScope
;
71 // If you change this, the corresponding list in nsIWorkerDebugger.idl needs to
80 // SharedMutex is a small wrapper around an (internal) reference-counted Mutex
81 // object. It exists to avoid changing a lot of code to use Mutex* instead of
85 typedef mozilla::Mutex Mutex
;
87 class RefCountedMutex MOZ_FINAL
: public Mutex
90 explicit RefCountedMutex(const char* aName
)
94 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMutex
)
101 nsRefPtr
<RefCountedMutex
> mMutex
;
104 explicit SharedMutex(const char* aName
)
105 : mMutex(new RefCountedMutex(aName
))
108 SharedMutex(SharedMutex
& aOther
)
109 : mMutex(aOther
.mMutex
)
117 operator const Mutex
&() const
123 AssertCurrentThreadOwns() const
125 mMutex
->AssertCurrentThreadOwns();
129 template <class Derived
>
130 class WorkerPrivateParent
: public DOMEventTargetHelper
132 class SynchronizeAndResumeRunnable
;
136 friend class EventTarget
;
138 typedef mozilla::ipc::PrincipalInfo PrincipalInfo
;
156 // All of these should be released in ForgetMainThreadObjects.
157 nsCOMPtr
<nsIURI
> mBaseURI
;
158 nsCOMPtr
<nsIURI
> mResolvedScriptURI
;
159 nsCOMPtr
<nsIPrincipal
> mPrincipal
;
160 nsCOMPtr
<nsIScriptContext
> mScriptContext
;
161 nsCOMPtr
<nsPIDOMWindow
> mWindow
;
162 nsCOMPtr
<nsIContentSecurityPolicy
> mCSP
;
163 nsCOMPtr
<nsIChannel
> mChannel
;
164 nsCOMPtr
<nsILoadGroup
> mLoadGroup
;
166 nsAutoPtr
<PrincipalInfo
> mPrincipalInfo
;
173 bool mReportCSPViolations
;
174 bool mXHRParamsAllowed
;
175 bool mPrincipalIsSystem
;
176 bool mIsInPrivilegedApp
;
177 bool mIsInCertifiedApp
;
178 bool mIndexedDBAllowed
;
184 StealFrom(LoadInfo
& aOther
)
186 MOZ_ASSERT(!mBaseURI
);
187 aOther
.mBaseURI
.swap(mBaseURI
);
189 MOZ_ASSERT(!mResolvedScriptURI
);
190 aOther
.mResolvedScriptURI
.swap(mResolvedScriptURI
);
192 MOZ_ASSERT(!mPrincipal
);
193 aOther
.mPrincipal
.swap(mPrincipal
);
195 MOZ_ASSERT(!mScriptContext
);
196 aOther
.mScriptContext
.swap(mScriptContext
);
198 MOZ_ASSERT(!mWindow
);
199 aOther
.mWindow
.swap(mWindow
);
202 aOther
.mCSP
.swap(mCSP
);
204 MOZ_ASSERT(!mChannel
);
205 aOther
.mChannel
.swap(mChannel
);
207 MOZ_ASSERT(!mLoadGroup
);
208 aOther
.mLoadGroup
.swap(mLoadGroup
);
210 MOZ_ASSERT(!mPrincipalInfo
);
211 mPrincipalInfo
= aOther
.mPrincipalInfo
.forget();
213 mDomain
= aOther
.mDomain
;
214 mWindowID
= aOther
.mWindowID
;
215 mFromWindow
= aOther
.mFromWindow
;
216 mEvalAllowed
= aOther
.mEvalAllowed
;
217 mReportCSPViolations
= aOther
.mReportCSPViolations
;
218 mXHRParamsAllowed
= aOther
.mXHRParamsAllowed
;
219 mPrincipalIsSystem
= aOther
.mPrincipalIsSystem
;
220 mIsInPrivilegedApp
= aOther
.mIsInPrivilegedApp
;
221 mIsInCertifiedApp
= aOther
.mIsInCertifiedApp
;
222 mIndexedDBAllowed
= aOther
.mIndexedDBAllowed
;
227 typedef mozilla::ErrorResult ErrorResult
;
230 mozilla::CondVar mCondVar
;
231 mozilla::CondVar mMemoryReportCondVar
;
233 // Protected by mMutex.
234 nsRefPtr
<EventTarget
> mEventTarget
;
235 nsTArray
<nsRefPtr
<WorkerRunnable
>> mPreStartRunnables
;
238 WorkerPrivate
* mParent
;
240 nsCString mSharedWorkerName
;
241 LocationInfo mLocationInfo
;
242 // The lifetime of these objects within LoadInfo is managed explicitly;
243 // they do not need to be cycle collected.
246 // Only used for top level workers.
247 nsTArray
<nsCOMPtr
<nsIRunnable
>> mQueuedRunnables
;
248 nsRevocableEventPtr
<SynchronizeAndResumeRunnable
> mSynchronizeRunnable
;
250 // Only for ChromeWorkers without window and only touched on the main thread.
251 nsTArray
<nsCString
> mHostObjectURIs
;
253 // Protected by mMutex.
254 JSSettings mJSSettings
;
256 // Only touched on the parent thread (currently this is always the main
257 // thread as SharedWorkers are always top-level).
258 nsDataHashtable
<nsUint64HashKey
, SharedWorker
*> mSharedWorkers
;
261 uint64_t mMessagePortSerial
;
262 Status mParentStatus
;
263 bool mParentSuspended
;
264 bool mIsChromeWorker
;
265 bool mMainThreadObjectsForgotten
;
266 WorkerType mWorkerType
;
267 TimeStamp mCreationTimeStamp
;
268 TimeStamp mNowBaseTimeStamp
;
271 // The worker is owned by its thread, which is represented here. This is set
272 // in Construct() and emptied by WorkerFinishedRunnable, and conditionally
273 // traversed by the cycle collector if the busy count is zero.
274 nsRefPtr
<WorkerPrivate
> mSelfRef
;
276 WorkerPrivateParent(JSContext
* aCx
, WorkerPrivate
* aParent
,
277 const nsAString
& aScriptURL
, bool aIsChromeWorker
,
278 WorkerType aWorkerType
,
279 const nsACString
& aSharedWorkerName
,
280 LoadInfo
& aLoadInfo
);
282 ~WorkerPrivateParent();
286 ParentAsWorkerPrivate() const
288 return static_cast<Derived
*>(const_cast<WorkerPrivateParent
*>(this));
291 // aCx is null when called from the finalizer
293 NotifyPrivate(JSContext
* aCx
, Status aStatus
);
295 // aCx is null when called from the finalizer
297 TerminatePrivate(JSContext
* aCx
)
299 return NotifyPrivate(aCx
, Terminating
);
303 PostMessageInternal(JSContext
* aCx
, JS::Handle
<JS::Value
> aMessage
,
304 const Optional
<Sequence
<JS::Value
> >& aTransferable
,
305 bool aToMessagePort
, uint64_t aMessagePortSerial
,
309 DispatchPrivate(WorkerRunnable
* aRunnable
, nsIEventTarget
* aSyncLoopTarget
);
313 WrapObject(JSContext
* aCx
) MOZ_OVERRIDE
;
315 NS_DECL_ISUPPORTS_INHERITED
316 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerPrivateParent
,
317 DOMEventTargetHelper
)
328 AssertIsOnParentThread();
329 MOZ_ASSERT(mSelfRef
);
334 Dispatch(WorkerRunnable
* aRunnable
)
336 return DispatchPrivate(aRunnable
, nullptr);
340 DispatchControlRunnable(WorkerControlRunnable
* aWorkerControlRunnable
);
342 already_AddRefed
<WorkerRunnable
>
343 MaybeWrapAsWorkerRunnable(nsIRunnable
* aRunnable
);
345 already_AddRefed
<nsIEventTarget
>
348 // May be called on any thread...
352 // Called on the parent thread.
354 Notify(JSContext
* aCx
, Status aStatus
)
356 return NotifyPrivate(aCx
, aStatus
);
360 Cancel(JSContext
* aCx
)
362 return Notify(aCx
, Canceling
);
368 return Notify(aCx
, Killing
);
371 // We can assume that an nsPIDOMWindow will be available for Suspend, Resume
372 // and SynchronizeAndResume as these are only used for globals going in and
373 // out of the bfcache.
375 Suspend(JSContext
* aCx
, nsPIDOMWindow
* aWindow
);
378 Resume(JSContext
* aCx
, nsPIDOMWindow
* aWindow
);
381 SynchronizeAndResume(JSContext
* aCx
, nsPIDOMWindow
* aWindow
);
384 Terminate(JSContext
* aCx
)
386 AssertIsOnParentThread();
387 return TerminatePrivate(aCx
);
391 Close(JSContext
* aCx
);
394 ModifyBusyCount(JSContext
* aCx
, bool aIncrease
);
397 ForgetMainThreadObjects(nsTArray
<nsCOMPtr
<nsISupports
> >& aDoomed
);
400 PostMessage(JSContext
* aCx
, JS::Handle
<JS::Value
> aMessage
,
401 const Optional
<Sequence
<JS::Value
> >& aTransferable
,
404 PostMessageInternal(aCx
, aMessage
, aTransferable
, false, 0, aRv
);
408 PostMessageToMessagePort(JSContext
* aCx
,
409 uint64_t aMessagePortSerial
,
410 JS::Handle
<JS::Value
> aMessage
,
411 const Optional
<Sequence
<JS::Value
> >& aTransferable
,
415 DispatchMessageEventToMessagePort(
417 uint64_t aMessagePortSerial
,
418 JSAutoStructuredCloneBuffer
&& aBuffer
,
419 nsTArray
<nsCOMPtr
<nsISupports
>>& aClonedObjects
);
422 UpdateRuntimeOptions(JSContext
* aCx
,
423 const JS::RuntimeOptions
& aRuntimeOptions
);
426 UpdateLanguages(JSContext
* aCx
, const nsTArray
<nsString
>& aLanguages
);
429 UpdatePreference(JSContext
* aCx
, WorkerPreference aPref
, bool aValue
);
432 UpdateJSWorkerMemoryParameter(JSContext
* aCx
, JSGCParamKey key
,
437 UpdateGCZeal(JSContext
* aCx
, uint8_t aGCZeal
, uint32_t aFrequency
);
441 GarbageCollect(JSContext
* aCx
, bool aShrinking
);
444 CycleCollect(JSContext
* aCx
, bool aDummy
);
447 OfflineStatusChangeEvent(JSContext
* aCx
, bool aIsOffline
);
450 RegisterSharedWorker(JSContext
* aCx
, SharedWorker
* aSharedWorker
);
453 UnregisterSharedWorker(JSContext
* aCx
, SharedWorker
* aSharedWorker
);
456 BroadcastErrorToSharedWorkers(JSContext
* aCx
,
457 const nsAString
& aMessage
,
458 const nsAString
& aFilename
,
459 const nsAString
& aLine
,
460 uint32_t aLineNumber
,
461 uint32_t aColumnNumber
,
465 WorkerScriptLoaded();
468 QueueRunnable(nsIRunnable
* aRunnable
)
470 AssertIsOnMainThread();
471 mQueuedRunnables
.AppendElement(aRunnable
);
483 AssertIsOnParentThread();
484 return mParentSuspended
;
490 AssertIsOnParentThread();
492 MutexAutoLock
lock(mMutex
);
493 return mParentStatus
< Terminating
;
499 mMutex
.AssertCurrentThreadOwns();
500 return mParentStatus
;
504 ParentJSContext() const;
507 GetScriptContext() const
509 AssertIsOnMainThread();
510 return mLoadInfo
.mScriptContext
;
522 return mLoadInfo
.mDomain
;
528 return mLoadInfo
.mFromWindow
;
534 return mLoadInfo
.mWindowID
;
540 AssertIsOnMainThread();
541 return mLoadInfo
.mBaseURI
;
545 SetBaseURI(nsIURI
* aBaseURI
);
548 GetResolvedScriptURI() const
550 AssertIsOnMainThread();
551 return mLoadInfo
.mResolvedScriptURI
;
554 TimeStamp
CreationTimeStamp() const
556 return mCreationTimeStamp
;
559 TimeStamp
NowBaseTimeStamp() const
561 return mNowBaseTimeStamp
;
567 AssertIsOnMainThread();
568 return mLoadInfo
.mPrincipal
;
574 AssertIsOnMainThread();
575 return mLoadInfo
.mLoadGroup
;
578 // This method allows the principal to be retrieved off the main thread.
579 // Principals are main-thread objects so the caller must ensure that all
580 // access occurs on the main thread.
582 GetPrincipalDontAssertMainThread() const
584 return mLoadInfo
.mPrincipal
;
588 SetPrincipal(nsIPrincipal
* aPrincipal
, nsILoadGroup
* aLoadGroup
);
591 UsesSystemPrincipal() const
593 return mLoadInfo
.mPrincipalIsSystem
;
597 IsInPrivilegedApp() const
599 return mLoadInfo
.mIsInPrivilegedApp
;
603 IsInCertifiedApp() const
605 return mLoadInfo
.mIsInCertifiedApp
;
609 GetPrincipalInfo() const
611 return *mLoadInfo
.mPrincipalInfo
;
614 already_AddRefed
<nsIChannel
>
615 ForgetWorkerChannel()
617 AssertIsOnMainThread();
618 return mLoadInfo
.mChannel
.forget();
624 AssertIsOnMainThread();
625 return mLoadInfo
.mWindow
? mLoadInfo
.mWindow
->GetExtantDoc() : nullptr;
631 AssertIsOnMainThread();
632 return mLoadInfo
.mWindow
;
635 nsIContentSecurityPolicy
*
638 AssertIsOnMainThread();
639 return mLoadInfo
.mCSP
;
643 SetCSP(nsIContentSecurityPolicy
* aCSP
)
645 AssertIsOnMainThread();
646 mLoadInfo
.mCSP
= aCSP
;
650 IsEvalAllowed() const
652 return mLoadInfo
.mEvalAllowed
;
656 SetEvalAllowed(bool aEvalAllowed
)
658 mLoadInfo
.mEvalAllowed
= aEvalAllowed
;
662 GetReportCSPViolations() const
664 return mLoadInfo
.mReportCSPViolations
;
668 XHRParamsAllowed() const
670 return mLoadInfo
.mXHRParamsAllowed
;
674 SetXHRParamsAllowed(bool aAllowed
)
676 mLoadInfo
.mXHRParamsAllowed
= aAllowed
;
682 return mLocationInfo
;
686 CopyJSSettings(JSSettings
& aSettings
)
688 mozilla::MutexAutoLock
lock(mMutex
);
689 aSettings
= mJSSettings
;
693 CopyJSCompartmentOptions(JS::CompartmentOptions
& aOptions
)
695 mozilla::MutexAutoLock
lock(mMutex
);
696 aOptions
= IsChromeWorker() ? mJSSettings
.chrome
.compartmentOptions
697 : mJSSettings
.content
.compartmentOptions
;
700 // The ability to be a chrome worker is orthogonal to the type of
701 // worker [Dedicated|Shared|Service].
703 IsChromeWorker() const
705 return mIsChromeWorker
;
715 IsDedicatedWorker() const
717 return mWorkerType
== WorkerTypeDedicated
;
721 IsSharedWorker() const
723 return mWorkerType
== WorkerTypeShared
;
727 IsServiceWorker() const
729 return mWorkerType
== WorkerTypeService
;
733 SharedWorkerName() const
735 return mSharedWorkerName
;
739 NextMessagePortSerial()
741 AssertIsOnMainThread();
742 return mMessagePortSerial
++;
746 IsIndexedDBAllowed() const
748 return mLoadInfo
.mIndexedDBAllowed
;
752 GetAllSharedWorkers(nsTArray
<nsRefPtr
<SharedWorker
>>& aSharedWorkers
);
755 CloseSharedWorkersForWindow(nsPIDOMWindow
* aWindow
);
758 RegisterHostObjectURI(const nsACString
& aURI
);
761 UnregisterHostObjectURI(const nsACString
& aURI
);
764 StealHostObjectURIs(nsTArray
<nsCString
>& aArray
);
766 IMPL_EVENT_HANDLER(message
)
767 IMPL_EVENT_HANDLER(error
)
771 AssertIsOnParentThread() const;
774 AssertInnerWindowIsCorrect() const;
777 AssertIsOnParentThread() const
781 AssertInnerWindowIsCorrect() const
786 class WorkerDebugger
: public nsIWorkerDebugger
{
787 mozilla::Mutex mMutex
;
788 mozilla::CondVar mCondVar
;
790 // Protected by mMutex
791 WorkerPrivate
* mWorkerPrivate
;
794 // Only touched on the main thread.
795 nsTArray
<nsCOMPtr
<nsIWorkerDebuggerListener
>> mListeners
;
798 explicit WorkerDebugger(WorkerPrivate
* aWorkerPrivate
);
800 NS_DECL_THREADSAFE_ISUPPORTS
801 NS_DECL_NSIWORKERDEBUGGER
803 void AssertIsOnParentThread();
805 void WaitIsEnabled(bool aIsEnabled
);
812 virtual ~WorkerDebugger();
814 void NotifyIsEnabled(bool aIsEnabled
);
817 class WorkerPrivate
: public WorkerPrivateParent
<WorkerPrivate
>
819 friend class WorkerPrivateParent
<WorkerPrivate
>;
820 typedef WorkerPrivateParent
<WorkerPrivate
> ParentType
;
821 friend class AutoSyncLoopHolder
;
825 class MemoryReporter
;
826 friend class MemoryReporter
;
828 friend class WorkerThread
;
837 nsRefPtr
<WorkerDebugger
> mDebugger
;
839 Queue
<WorkerControlRunnable
*, 4> mControlQueue
;
841 // Touched on multiple threads, protected with mMutex.
842 JSContext
* mJSContext
;
843 nsRefPtr
<WorkerCrossThreadDispatcher
> mCrossThreadDispatcher
;
844 nsTArray
<nsCOMPtr
<nsIRunnable
>> mUndispatchedRunnablesForSyncLoop
;
845 nsRefPtr
<WorkerThread
> mThread
;
848 // Things touched on worker thread only.
849 nsRefPtr
<WorkerGlobalScope
> mScope
;
850 nsTArray
<ParentType
*> mChildWorkers
;
851 nsTArray
<WorkerFeature
*> mFeatures
;
852 nsTArray
<nsAutoPtr
<TimeoutInfo
>> mTimeouts
;
856 explicit SyncLoopInfo(EventTarget
* aEventTarget
);
858 nsRefPtr
<EventTarget
> mEventTarget
;
866 // This is only modified on the worker thread, but in DEBUG builds
867 // AssertValidSyncLoop function iterates it on other threads. Therefore
868 // modifications are done with mMutex held *only* in DEBUG builds.
869 nsTArray
<nsAutoPtr
<SyncLoopInfo
>> mSyncLoopStack
;
871 struct PreemptingRunnableInfo
;
872 nsTArray
<PreemptingRunnableInfo
> mPreemptingRunnableInfos
;
874 nsCOMPtr
<nsITimer
> mTimer
;
876 nsCOMPtr
<nsITimer
> mGCTimer
;
877 nsCOMPtr
<nsIEventTarget
> mPeriodicGCTimerTarget
;
878 nsCOMPtr
<nsIEventTarget
> mIdleGCTimerTarget
;
880 nsRefPtr
<MemoryReporter
> mMemoryReporter
;
882 nsRefPtrHashtable
<nsUint64HashKey
, MessagePort
> mWorkerPorts
;
885 uint32_t mErrorHandlerRecursionCount
;
886 uint32_t mNextTimeoutId
;
890 bool mRunningExpiredTimeouts
;
891 bool mCloseHandlerStarted
;
892 bool mCloseHandlerFinished
;
893 bool mMemoryReporterRunning
;
894 bool mBlockedForMemoryReporter
;
895 bool mCancelAllPendingRunnables
;
896 bool mPeriodicGCTimerRunning
;
897 bool mIdleGCTimerRunning
;
898 bool mWorkerScriptExecutedSuccessfully
;
899 bool mPreferences
[WORKERPREF_COUNT
];
906 static already_AddRefed
<WorkerPrivate
>
907 Constructor(const GlobalObject
& aGlobal
, const nsAString
& aScriptURL
,
910 static already_AddRefed
<WorkerPrivate
>
911 Constructor(const GlobalObject
& aGlobal
, const nsAString
& aScriptURL
,
912 bool aIsChromeWorker
, WorkerType aWorkerType
,
913 const nsACString
& aSharedWorkerName
,
914 LoadInfo
* aLoadInfo
, ErrorResult
& aRv
);
916 static already_AddRefed
<WorkerPrivate
>
917 Constructor(JSContext
* aCx
, const nsAString
& aScriptURL
, bool aIsChromeWorker
,
918 WorkerType aWorkerType
, const nsACString
& aSharedWorkerName
,
919 LoadInfo
* aLoadInfo
, ErrorResult
& aRv
);
922 WorkerAvailable(JSContext
* /* unused */, JSObject
* /* unused */);
925 GetLoadInfo(JSContext
* aCx
, nsPIDOMWindow
* aWindow
, WorkerPrivate
* aParent
,
926 const nsAString
& aScriptURL
, bool aIsChromeWorker
,
927 LoadInfo
* aLoadInfo
);
932 AssertIsOnMainThread();
933 MOZ_ASSERT(mDebugger
);
938 DoRunLoop(JSContext
* aCx
);
941 InterruptCallback(JSContext
* aCx
);
944 IsOnCurrentThread(bool* aIsOnCurrentThread
);
947 CloseInternal(JSContext
* aCx
)
949 AssertIsOnWorkerThread();
950 return NotifyInternal(aCx
, Closing
);
954 SuspendInternal(JSContext
* aCx
);
957 ResumeInternal(JSContext
* aCx
);
960 TraceTimeouts(const TraceCallbacks
& aCallbacks
, void* aClosure
) const;
963 ModifyBusyCountFromWorker(JSContext
* aCx
, bool aIncrease
);
966 AddChildWorker(JSContext
* aCx
, ParentType
* aChildWorker
);
969 RemoveChildWorker(JSContext
* aCx
, ParentType
* aChildWorker
);
972 AddFeature(JSContext
* aCx
, WorkerFeature
* aFeature
);
975 RemoveFeature(JSContext
* aCx
, WorkerFeature
* aFeature
);
978 NotifyFeatures(JSContext
* aCx
, Status aStatus
);
983 return !(mChildWorkers
.IsEmpty() && mTimeouts
.IsEmpty() &&
984 mFeatures
.IsEmpty());
988 PostMessageToParent(JSContext
* aCx
,
989 JS::Handle
<JS::Value
> aMessage
,
990 const Optional
<Sequence
<JS::Value
>>& aTransferable
,
993 PostMessageToParentInternal(aCx
, aMessage
, aTransferable
, false, 0, aRv
);
997 PostMessageToParentMessagePort(
999 uint64_t aMessagePortSerial
,
1000 JS::Handle
<JS::Value
> aMessage
,
1001 const Optional
<Sequence
<JS::Value
>>& aTransferable
,
1005 NotifyInternal(JSContext
* aCx
, Status aStatus
);
1008 ReportError(JSContext
* aCx
, const char* aMessage
, JSErrorReport
* aReport
);
1011 SetTimeout(JSContext
* aCx
,
1013 const nsAString
& aStringHandler
,
1015 const Sequence
<JS::Value
>& aArguments
,
1020 ClearTimeout(int32_t aId
);
1023 RunExpiredTimeouts(JSContext
* aCx
);
1026 RescheduleTimeoutTimer(JSContext
* aCx
);
1029 CloseHandlerStarted()
1031 AssertIsOnWorkerThread();
1032 mCloseHandlerStarted
= true;
1036 CloseHandlerFinished()
1038 AssertIsOnWorkerThread();
1039 mCloseHandlerFinished
= true;
1043 UpdateRuntimeOptionsInternal(JSContext
* aCx
, const JS::RuntimeOptions
& aRuntimeOptions
);
1046 UpdateLanguagesInternal(JSContext
* aCx
, const nsTArray
<nsString
>& aLanguages
);
1049 UpdatePreferenceInternal(JSContext
* aCx
, WorkerPreference aPref
, bool aValue
);
1052 UpdateJSWorkerMemoryParameterInternal(JSContext
* aCx
, JSGCParamKey key
, uint32_t aValue
);
1054 enum WorkerRanOrNot
{
1060 ScheduleDeletion(WorkerRanOrNot aRanOrNot
);
1063 BlockAndCollectRuntimeStats(JS::RuntimeStats
* aRtStats
, bool aAnonymize
);
1067 UpdateGCZealInternal(JSContext
* aCx
, uint8_t aGCZeal
, uint32_t aFrequency
);
1071 GarbageCollectInternal(JSContext
* aCx
, bool aShrinking
,
1072 bool aCollectChildren
);
1075 CycleCollectInternal(JSContext
* aCx
, bool aCollectChildren
);
1078 OfflineStatusChangeEventInternal(JSContext
* aCx
, bool aIsOffline
);
1081 GetJSContext() const
1083 AssertIsOnWorkerThread();
1090 AssertIsOnWorkerThread();
1095 SetThread(WorkerThread
* aThread
);
1098 AssertIsOnWorkerThread() const
1105 WorkerCrossThreadDispatcher
*
1106 GetCrossThreadDispatcher();
1117 BeginCTypesCallback()
1119 // If a callback is beginning then we need to do the exact same thing as
1120 // when a ctypes call ends.
1127 // If a callback is ending then we need to do the exact same thing as
1128 // when a ctypes call begins.
1133 ConnectMessagePort(JSContext
* aCx
, uint64_t aMessagePortSerial
);
1136 DisconnectMessagePort(uint64_t aMessagePortSerial
);
1139 GetMessagePort(uint64_t aMessagePortSerial
);
1142 CreateGlobalScope(JSContext
* aCx
);
1145 RegisterBindings(JSContext
* aCx
, JS::Handle
<JSObject
*> aGlobal
);
1150 AssertIsOnWorkerThread();
1151 return mPreferences
[WORKERPREF_DUMP
];
1155 DOMFetchEnabled() const
1157 AssertIsOnWorkerThread();
1158 return mPreferences
[WORKERPREF_DOM_FETCH
];
1164 AssertIsOnWorkerThread();
1169 StopSyncLoop(nsIEventTarget
* aSyncLoopTarget
, bool aResult
);
1172 AllPendingRunnablesShouldBeCanceled() const
1174 return mCancelAllPendingRunnables
;
1178 OnProcessNextEvent(uint32_t aRecursionDepth
);
1181 AfterProcessNextEvent(uint32_t aRecursionDepth
);
1184 AssertValidSyncLoop(nsIEventTarget
* aSyncLoopTarget
)
1192 SetWorkerScriptExecutedSuccessfully()
1194 AssertIsOnWorkerThread();
1195 // Should only be called once!
1196 MOZ_ASSERT(!mWorkerScriptExecutedSuccessfully
);
1197 mWorkerScriptExecutedSuccessfully
= true;
1200 // Only valid after CompileScriptRunnable has finished running!
1202 WorkerScriptExecutedSuccessfully() const
1204 AssertIsOnWorkerThread();
1205 return mWorkerScriptExecutedSuccessfully
;
1208 // Just like nsIAppShell::RunBeforeNextEvent. May only be called on the worker
1211 RunBeforeNextEvent(nsIRunnable
* aRunnable
);
1214 WorkerPrivate(JSContext
* aCx
, WorkerPrivate
* aParent
,
1215 const nsAString
& aScriptURL
, bool aIsChromeWorker
,
1216 WorkerType aWorkerType
, const nsACString
& aSharedWorkerName
,
1217 LoadInfo
& aLoadInfo
);
1220 ClearMainEventQueue(WorkerRanOrNot aRanOrNot
);
1223 MayContinueRunning()
1225 AssertIsOnWorkerThread();
1229 MutexAutoLock
lock(mMutex
);
1233 if (status
>= Killing
) {
1236 if (status
>= Running
) {
1237 return mKillTime
.IsNull() || RemainingRunTimeMS() > 0;
1243 RemainingRunTimeMS() const;
1246 CancelAllTimeouts(JSContext
* aCx
);
1249 ScheduleKillCloseEventRunnable(JSContext
* aCx
);
1252 ProcessAllControlRunnables()
1254 MutexAutoLock
lock(mMutex
);
1255 return ProcessAllControlRunnablesLocked();
1259 ProcessAllControlRunnablesLocked();
1262 EnableMemoryReporter();
1265 DisableMemoryReporter();
1268 WaitForWorkerEvents(PRIntervalTime interval
= PR_INTERVAL_NO_TIMEOUT
);
1271 PostMessageToParentInternal(JSContext
* aCx
,
1272 JS::Handle
<JS::Value
> aMessage
,
1273 const Optional
<Sequence
<JS::Value
>>& aTransferable
,
1274 bool aToMessagePort
,
1275 uint64_t aMessagePortSerial
,
1279 GetAllPreferences(bool aPreferences
[WORKERPREF_COUNT
]) const
1281 AssertIsOnWorkerThread();
1282 memcpy(aPreferences
, mPreferences
, WORKERPREF_COUNT
* sizeof(bool));
1285 already_AddRefed
<nsIEventTarget
>
1286 CreateNewSyncLoop();
1289 RunCurrentSyncLoop();
1292 DestroySyncLoop(uint32_t aLoopIndex
, nsIThreadInternal
* aThread
= nullptr);
1295 InitializeGCTimers();
1298 SetGCTimerMode(GCTimerMode aMode
);
1304 // This class is only used to trick the DOM bindings. We never create
1305 // instances of it, and static_casting to it is fine since it doesn't add
1306 // anything to WorkerPrivate.
1307 class ChromeWorkerPrivate
: public WorkerPrivate
1310 static already_AddRefed
<ChromeWorkerPrivate
>
1311 Constructor(const GlobalObject
& aGlobal
, const nsAString
& aScriptURL
,
1315 WorkerAvailable(JSContext
* aCx
, JSObject
* /* unused */);
1318 ChromeWorkerPrivate() = delete;
1319 ChromeWorkerPrivate(const ChromeWorkerPrivate
& aRHS
) = delete;
1320 ChromeWorkerPrivate
& operator =(const ChromeWorkerPrivate
& aRHS
) = delete;
1324 GetWorkerPrivateFromContext(JSContext
* aCx
);
1327 GetCurrentThreadWorkerPrivate();
1330 IsCurrentThreadRunningChromeWorker();
1333 GetCurrentThreadJSContext();
1335 enum WorkerStructuredDataType
1337 DOMWORKER_SCTAG_BLOB
= SCTAG_DOM_MAX
,
1342 const JSStructuredCloneCallbacks
*
1343 WorkerStructuredCloneCallbacks(bool aMainRuntime
);
1345 const JSStructuredCloneCallbacks
*
1346 ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime
);
1348 class AutoSyncLoopHolder
1350 WorkerPrivate
* mWorkerPrivate
;
1351 nsCOMPtr
<nsIEventTarget
> mTarget
;
1355 explicit AutoSyncLoopHolder(WorkerPrivate
* aWorkerPrivate
)
1356 : mWorkerPrivate(aWorkerPrivate
)
1357 , mTarget(aWorkerPrivate
->CreateNewSyncLoop())
1358 , mIndex(aWorkerPrivate
->mSyncLoopStack
.Length() - 1)
1360 aWorkerPrivate
->AssertIsOnWorkerThread();
1363 ~AutoSyncLoopHolder()
1365 if (mWorkerPrivate
) {
1366 mWorkerPrivate
->AssertIsOnWorkerThread();
1367 mWorkerPrivate
->StopSyncLoop(mTarget
, false);
1368 mWorkerPrivate
->DestroySyncLoop(mIndex
);
1375 WorkerPrivate
* workerPrivate
= mWorkerPrivate
;
1376 mWorkerPrivate
= nullptr;
1378 workerPrivate
->AssertIsOnWorkerThread();
1380 return workerPrivate
->RunCurrentSyncLoop();
1390 END_WORKERS_NAMESPACE
1392 #endif /* mozilla_dom_workers_workerprivate_h__ */