Bumping gaia.json for 4 gaia revision(s) a=gaia-bump
[gecko.git] / dom / workers / WorkerPrivate.h
blob430886f4fe4a41f3aba1d0ca9cdcdfc1de1f3042
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__
9 #include "Workers.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"
25 #include "nsString.h"
26 #include "nsTArray.h"
27 #include "nsThreadUtils.h"
28 #include "mozilla/dom/StructuredCloneTags.h"
30 #include "Queue.h"
31 #include "WorkerFeature.h"
33 class JSAutoStructuredCloneBuffer;
34 class nsIChannel;
35 class nsIDocument;
36 class nsIEventTarget;
37 class nsIPrincipal;
38 class nsIScriptContext;
39 class nsIThread;
40 class nsIThreadInternal;
41 class nsITimer;
42 class nsIURI;
44 namespace JS {
45 struct RuntimeStats;
48 namespace mozilla {
49 namespace dom {
50 class Function;
52 namespace ipc {
53 class PrincipalInfo;
57 struct PRThread;
59 BEGIN_WORKERS_NAMESPACE
61 class AutoSyncLoopHolder;
62 class MessagePort;
63 class SharedWorker;
64 class WorkerControlRunnable;
65 class WorkerDebugger;
66 class WorkerGlobalScope;
67 class WorkerPrivate;
68 class WorkerRunnable;
69 class WorkerThread;
71 // If you change this, the corresponding list in nsIWorkerDebugger.idl needs to
72 // be updated too.
73 enum WorkerType
75 WorkerTypeDedicated,
76 WorkerTypeShared,
77 WorkerTypeService
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
82 // Mutex&.
83 class SharedMutex
85 typedef mozilla::Mutex Mutex;
87 class RefCountedMutex MOZ_FINAL : public Mutex
89 public:
90 explicit RefCountedMutex(const char* aName)
91 : Mutex(aName)
92 { }
94 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMutex)
96 private:
97 ~RefCountedMutex()
98 { }
101 nsRefPtr<RefCountedMutex> mMutex;
103 public:
104 explicit SharedMutex(const char* aName)
105 : mMutex(new RefCountedMutex(aName))
108 SharedMutex(SharedMutex& aOther)
109 : mMutex(aOther.mMutex)
112 operator Mutex&()
114 return *mMutex;
117 operator const Mutex&() const
119 return *mMutex;
122 void
123 AssertCurrentThreadOwns() const
125 mMutex->AssertCurrentThreadOwns();
129 template <class Derived>
130 class WorkerPrivateParent : public DOMEventTargetHelper
132 class SynchronizeAndResumeRunnable;
134 protected:
135 class EventTarget;
136 friend class EventTarget;
138 typedef mozilla::ipc::PrincipalInfo PrincipalInfo;
140 public:
141 struct LocationInfo
143 nsCString mHref;
144 nsCString mProtocol;
145 nsCString mHost;
146 nsCString mHostname;
147 nsCString mPort;
148 nsCString mPathname;
149 nsCString mSearch;
150 nsCString mHash;
151 nsString mOrigin;
154 struct LoadInfo
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;
167 nsCString mDomain;
169 uint64_t mWindowID;
171 bool mFromWindow;
172 bool mEvalAllowed;
173 bool mReportCSPViolations;
174 bool mXHRParamsAllowed;
175 bool mPrincipalIsSystem;
176 bool mIsInPrivilegedApp;
177 bool mIsInCertifiedApp;
178 bool mIndexedDBAllowed;
180 LoadInfo();
181 ~LoadInfo();
183 void
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);
201 MOZ_ASSERT(!mCSP);
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;
226 protected:
227 typedef mozilla::ErrorResult ErrorResult;
229 SharedMutex mMutex;
230 mozilla::CondVar mCondVar;
231 mozilla::CondVar mMemoryReportCondVar;
233 // Protected by mMutex.
234 nsRefPtr<EventTarget> mEventTarget;
235 nsTArray<nsRefPtr<WorkerRunnable>> mPreStartRunnables;
237 private:
238 WorkerPrivate* mParent;
239 nsString mScriptURL;
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.
244 LoadInfo mLoadInfo;
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;
260 uint64_t mBusyCount;
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;
270 protected:
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();
284 private:
285 Derived*
286 ParentAsWorkerPrivate() const
288 return static_cast<Derived*>(const_cast<WorkerPrivateParent*>(this));
291 // aCx is null when called from the finalizer
292 bool
293 NotifyPrivate(JSContext* aCx, Status aStatus);
295 // aCx is null when called from the finalizer
296 bool
297 TerminatePrivate(JSContext* aCx)
299 return NotifyPrivate(aCx, Terminating);
302 void
303 PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
304 const Optional<Sequence<JS::Value> >& aTransferable,
305 bool aToMessagePort, uint64_t aMessagePortSerial,
306 ErrorResult& aRv);
308 nsresult
309 DispatchPrivate(WorkerRunnable* aRunnable, nsIEventTarget* aSyncLoopTarget);
311 public:
312 virtual JSObject*
313 WrapObject(JSContext* aCx) MOZ_OVERRIDE;
315 NS_DECL_ISUPPORTS_INHERITED
316 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerPrivateParent,
317 DOMEventTargetHelper)
319 void
320 EnableDebugger();
322 void
323 DisableDebugger();
325 void
326 ClearSelfRef()
328 AssertIsOnParentThread();
329 MOZ_ASSERT(mSelfRef);
330 mSelfRef = nullptr;
333 nsresult
334 Dispatch(WorkerRunnable* aRunnable)
336 return DispatchPrivate(aRunnable, nullptr);
339 nsresult
340 DispatchControlRunnable(WorkerControlRunnable* aWorkerControlRunnable);
342 already_AddRefed<WorkerRunnable>
343 MaybeWrapAsWorkerRunnable(nsIRunnable* aRunnable);
345 already_AddRefed<nsIEventTarget>
346 GetEventTarget();
348 // May be called on any thread...
349 bool
350 Start();
352 // Called on the parent thread.
353 bool
354 Notify(JSContext* aCx, Status aStatus)
356 return NotifyPrivate(aCx, aStatus);
359 bool
360 Cancel(JSContext* aCx)
362 return Notify(aCx, Canceling);
365 bool
366 Kill(JSContext* aCx)
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.
374 bool
375 Suspend(JSContext* aCx, nsPIDOMWindow* aWindow);
377 bool
378 Resume(JSContext* aCx, nsPIDOMWindow* aWindow);
380 bool
381 SynchronizeAndResume(JSContext* aCx, nsPIDOMWindow* aWindow);
383 bool
384 Terminate(JSContext* aCx)
386 AssertIsOnParentThread();
387 return TerminatePrivate(aCx);
390 bool
391 Close(JSContext* aCx);
393 bool
394 ModifyBusyCount(JSContext* aCx, bool aIncrease);
396 void
397 ForgetMainThreadObjects(nsTArray<nsCOMPtr<nsISupports> >& aDoomed);
399 void
400 PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
401 const Optional<Sequence<JS::Value> >& aTransferable,
402 ErrorResult& aRv)
404 PostMessageInternal(aCx, aMessage, aTransferable, false, 0, aRv);
407 void
408 PostMessageToMessagePort(JSContext* aCx,
409 uint64_t aMessagePortSerial,
410 JS::Handle<JS::Value> aMessage,
411 const Optional<Sequence<JS::Value> >& aTransferable,
412 ErrorResult& aRv);
414 bool
415 DispatchMessageEventToMessagePort(
416 JSContext* aCx,
417 uint64_t aMessagePortSerial,
418 JSAutoStructuredCloneBuffer&& aBuffer,
419 nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects);
421 void
422 UpdateRuntimeOptions(JSContext* aCx,
423 const JS::RuntimeOptions& aRuntimeOptions);
425 void
426 UpdateLanguages(JSContext* aCx, const nsTArray<nsString>& aLanguages);
428 void
429 UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue);
431 void
432 UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key,
433 uint32_t value);
435 #ifdef JS_GC_ZEAL
436 void
437 UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
438 #endif
440 void
441 GarbageCollect(JSContext* aCx, bool aShrinking);
443 void
444 CycleCollect(JSContext* aCx, bool aDummy);
446 void
447 OfflineStatusChangeEvent(JSContext* aCx, bool aIsOffline);
449 bool
450 RegisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker);
452 void
453 UnregisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker);
455 void
456 BroadcastErrorToSharedWorkers(JSContext* aCx,
457 const nsAString& aMessage,
458 const nsAString& aFilename,
459 const nsAString& aLine,
460 uint32_t aLineNumber,
461 uint32_t aColumnNumber,
462 uint32_t aFlags);
464 void
465 WorkerScriptLoaded();
467 void
468 QueueRunnable(nsIRunnable* aRunnable)
470 AssertIsOnMainThread();
471 mQueuedRunnables.AppendElement(aRunnable);
474 WorkerPrivate*
475 GetParent() const
477 return mParent;
480 bool
481 IsSuspended() const
483 AssertIsOnParentThread();
484 return mParentSuspended;
487 bool
488 IsAcceptingEvents()
490 AssertIsOnParentThread();
492 MutexAutoLock lock(mMutex);
493 return mParentStatus < Terminating;
496 Status
497 ParentStatus() const
499 mMutex.AssertCurrentThreadOwns();
500 return mParentStatus;
503 JSContext*
504 ParentJSContext() const;
506 nsIScriptContext*
507 GetScriptContext() const
509 AssertIsOnMainThread();
510 return mLoadInfo.mScriptContext;
513 const nsString&
514 ScriptURL() const
516 return mScriptURL;
519 const nsCString&
520 Domain() const
522 return mLoadInfo.mDomain;
525 bool
526 IsFromWindow() const
528 return mLoadInfo.mFromWindow;
531 uint64_t
532 WindowID() const
534 return mLoadInfo.mWindowID;
537 nsIURI*
538 GetBaseURI() const
540 AssertIsOnMainThread();
541 return mLoadInfo.mBaseURI;
544 void
545 SetBaseURI(nsIURI* aBaseURI);
547 nsIURI*
548 GetResolvedScriptURI() const
550 AssertIsOnMainThread();
551 return mLoadInfo.mResolvedScriptURI;
554 TimeStamp CreationTimeStamp() const
556 return mCreationTimeStamp;
559 TimeStamp NowBaseTimeStamp() const
561 return mNowBaseTimeStamp;
564 nsIPrincipal*
565 GetPrincipal() const
567 AssertIsOnMainThread();
568 return mLoadInfo.mPrincipal;
571 nsILoadGroup*
572 GetLoadGroup() const
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.
581 nsIPrincipal*
582 GetPrincipalDontAssertMainThread() const
584 return mLoadInfo.mPrincipal;
587 void
588 SetPrincipal(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
590 bool
591 UsesSystemPrincipal() const
593 return mLoadInfo.mPrincipalIsSystem;
596 bool
597 IsInPrivilegedApp() const
599 return mLoadInfo.mIsInPrivilegedApp;
602 bool
603 IsInCertifiedApp() const
605 return mLoadInfo.mIsInCertifiedApp;
608 const PrincipalInfo&
609 GetPrincipalInfo() const
611 return *mLoadInfo.mPrincipalInfo;
614 already_AddRefed<nsIChannel>
615 ForgetWorkerChannel()
617 AssertIsOnMainThread();
618 return mLoadInfo.mChannel.forget();
621 nsIDocument*
622 GetDocument() const
624 AssertIsOnMainThread();
625 return mLoadInfo.mWindow ? mLoadInfo.mWindow->GetExtantDoc() : nullptr;
628 nsPIDOMWindow*
629 GetWindow()
631 AssertIsOnMainThread();
632 return mLoadInfo.mWindow;
635 nsIContentSecurityPolicy*
636 GetCSP() const
638 AssertIsOnMainThread();
639 return mLoadInfo.mCSP;
642 void
643 SetCSP(nsIContentSecurityPolicy* aCSP)
645 AssertIsOnMainThread();
646 mLoadInfo.mCSP = aCSP;
649 bool
650 IsEvalAllowed() const
652 return mLoadInfo.mEvalAllowed;
655 void
656 SetEvalAllowed(bool aEvalAllowed)
658 mLoadInfo.mEvalAllowed = aEvalAllowed;
661 bool
662 GetReportCSPViolations() const
664 return mLoadInfo.mReportCSPViolations;
667 bool
668 XHRParamsAllowed() const
670 return mLoadInfo.mXHRParamsAllowed;
673 void
674 SetXHRParamsAllowed(bool aAllowed)
676 mLoadInfo.mXHRParamsAllowed = aAllowed;
679 LocationInfo&
680 GetLocationInfo()
682 return mLocationInfo;
685 void
686 CopyJSSettings(JSSettings& aSettings)
688 mozilla::MutexAutoLock lock(mMutex);
689 aSettings = mJSSettings;
692 void
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].
702 bool
703 IsChromeWorker() const
705 return mIsChromeWorker;
708 WorkerType
709 Type() const
711 return mWorkerType;
714 bool
715 IsDedicatedWorker() const
717 return mWorkerType == WorkerTypeDedicated;
720 bool
721 IsSharedWorker() const
723 return mWorkerType == WorkerTypeShared;
726 bool
727 IsServiceWorker() const
729 return mWorkerType == WorkerTypeService;
732 const nsCString&
733 SharedWorkerName() const
735 return mSharedWorkerName;
738 uint64_t
739 NextMessagePortSerial()
741 AssertIsOnMainThread();
742 return mMessagePortSerial++;
745 bool
746 IsIndexedDBAllowed() const
748 return mLoadInfo.mIndexedDBAllowed;
751 void
752 GetAllSharedWorkers(nsTArray<nsRefPtr<SharedWorker>>& aSharedWorkers);
754 void
755 CloseSharedWorkersForWindow(nsPIDOMWindow* aWindow);
757 void
758 RegisterHostObjectURI(const nsACString& aURI);
760 void
761 UnregisterHostObjectURI(const nsACString& aURI);
763 void
764 StealHostObjectURIs(nsTArray<nsCString>& aArray);
766 IMPL_EVENT_HANDLER(message)
767 IMPL_EVENT_HANDLER(error)
769 #ifdef DEBUG
770 void
771 AssertIsOnParentThread() const;
773 void
774 AssertInnerWindowIsCorrect() const;
775 #else
776 void
777 AssertIsOnParentThread() const
780 void
781 AssertInnerWindowIsCorrect() const
783 #endif
786 class WorkerDebugger : public nsIWorkerDebugger {
787 mozilla::Mutex mMutex;
788 mozilla::CondVar mCondVar;
790 // Protected by mMutex
791 WorkerPrivate* mWorkerPrivate;
792 bool mIsEnabled;
794 // Only touched on the main thread.
795 nsTArray<nsCOMPtr<nsIWorkerDebuggerListener>> mListeners;
797 public:
798 explicit WorkerDebugger(WorkerPrivate* aWorkerPrivate);
800 NS_DECL_THREADSAFE_ISUPPORTS
801 NS_DECL_NSIWORKERDEBUGGER
803 void AssertIsOnParentThread();
805 void WaitIsEnabled(bool aIsEnabled);
807 void Enable();
809 void Disable();
811 private:
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;
823 struct TimeoutInfo;
825 class MemoryReporter;
826 friend class MemoryReporter;
828 friend class WorkerThread;
830 enum GCTimerMode
832 PeriodicTimer = 0,
833 IdleTimer,
834 NoTimer
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;
846 PRThread* mPRThread;
848 // Things touched on worker thread only.
849 nsRefPtr<WorkerGlobalScope> mScope;
850 nsTArray<ParentType*> mChildWorkers;
851 nsTArray<WorkerFeature*> mFeatures;
852 nsTArray<nsAutoPtr<TimeoutInfo>> mTimeouts;
854 struct SyncLoopInfo
856 explicit SyncLoopInfo(EventTarget* aEventTarget);
858 nsRefPtr<EventTarget> mEventTarget;
859 bool mCompleted;
860 bool mResult;
861 #ifdef DEBUG
862 bool mHasRun;
863 #endif
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;
884 TimeStamp mKillTime;
885 uint32_t mErrorHandlerRecursionCount;
886 uint32_t mNextTimeoutId;
887 Status mStatus;
888 bool mSuspended;
889 bool mTimerRunning;
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];
900 bool mOnLine;
902 protected:
903 ~WorkerPrivate();
905 public:
906 static already_AddRefed<WorkerPrivate>
907 Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
908 ErrorResult& aRv);
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);
921 static bool
922 WorkerAvailable(JSContext* /* unused */, JSObject* /* unused */);
924 static nsresult
925 GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent,
926 const nsAString& aScriptURL, bool aIsChromeWorker,
927 LoadInfo* aLoadInfo);
929 WorkerDebugger*
930 Debugger() const
932 AssertIsOnMainThread();
933 MOZ_ASSERT(mDebugger);
934 return mDebugger;
937 void
938 DoRunLoop(JSContext* aCx);
940 bool
941 InterruptCallback(JSContext* aCx);
943 nsresult
944 IsOnCurrentThread(bool* aIsOnCurrentThread);
946 bool
947 CloseInternal(JSContext* aCx)
949 AssertIsOnWorkerThread();
950 return NotifyInternal(aCx, Closing);
953 bool
954 SuspendInternal(JSContext* aCx);
956 bool
957 ResumeInternal(JSContext* aCx);
959 void
960 TraceTimeouts(const TraceCallbacks& aCallbacks, void* aClosure) const;
962 bool
963 ModifyBusyCountFromWorker(JSContext* aCx, bool aIncrease);
965 bool
966 AddChildWorker(JSContext* aCx, ParentType* aChildWorker);
968 void
969 RemoveChildWorker(JSContext* aCx, ParentType* aChildWorker);
971 bool
972 AddFeature(JSContext* aCx, WorkerFeature* aFeature);
974 void
975 RemoveFeature(JSContext* aCx, WorkerFeature* aFeature);
977 void
978 NotifyFeatures(JSContext* aCx, Status aStatus);
980 bool
981 HasActiveFeatures()
983 return !(mChildWorkers.IsEmpty() && mTimeouts.IsEmpty() &&
984 mFeatures.IsEmpty());
987 void
988 PostMessageToParent(JSContext* aCx,
989 JS::Handle<JS::Value> aMessage,
990 const Optional<Sequence<JS::Value>>& aTransferable,
991 ErrorResult& aRv)
993 PostMessageToParentInternal(aCx, aMessage, aTransferable, false, 0, aRv);
996 void
997 PostMessageToParentMessagePort(
998 JSContext* aCx,
999 uint64_t aMessagePortSerial,
1000 JS::Handle<JS::Value> aMessage,
1001 const Optional<Sequence<JS::Value>>& aTransferable,
1002 ErrorResult& aRv);
1004 bool
1005 NotifyInternal(JSContext* aCx, Status aStatus);
1007 void
1008 ReportError(JSContext* aCx, const char* aMessage, JSErrorReport* aReport);
1010 int32_t
1011 SetTimeout(JSContext* aCx,
1012 Function* aHandler,
1013 const nsAString& aStringHandler,
1014 int32_t aTimeout,
1015 const Sequence<JS::Value>& aArguments,
1016 bool aIsInterval,
1017 ErrorResult& aRv);
1019 void
1020 ClearTimeout(int32_t aId);
1022 bool
1023 RunExpiredTimeouts(JSContext* aCx);
1025 bool
1026 RescheduleTimeoutTimer(JSContext* aCx);
1028 void
1029 CloseHandlerStarted()
1031 AssertIsOnWorkerThread();
1032 mCloseHandlerStarted = true;
1035 void
1036 CloseHandlerFinished()
1038 AssertIsOnWorkerThread();
1039 mCloseHandlerFinished = true;
1042 void
1043 UpdateRuntimeOptionsInternal(JSContext* aCx, const JS::RuntimeOptions& aRuntimeOptions);
1045 void
1046 UpdateLanguagesInternal(JSContext* aCx, const nsTArray<nsString>& aLanguages);
1048 void
1049 UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue);
1051 void
1052 UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
1054 enum WorkerRanOrNot {
1055 WorkerNeverRan = 0,
1056 WorkerRan
1059 void
1060 ScheduleDeletion(WorkerRanOrNot aRanOrNot);
1062 bool
1063 BlockAndCollectRuntimeStats(JS::RuntimeStats* aRtStats, bool aAnonymize);
1065 #ifdef JS_GC_ZEAL
1066 void
1067 UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
1068 #endif
1070 void
1071 GarbageCollectInternal(JSContext* aCx, bool aShrinking,
1072 bool aCollectChildren);
1074 void
1075 CycleCollectInternal(JSContext* aCx, bool aCollectChildren);
1077 void
1078 OfflineStatusChangeEventInternal(JSContext* aCx, bool aIsOffline);
1080 JSContext*
1081 GetJSContext() const
1083 AssertIsOnWorkerThread();
1084 return mJSContext;
1087 WorkerGlobalScope*
1088 GlobalScope() const
1090 AssertIsOnWorkerThread();
1091 return mScope;
1094 void
1095 SetThread(WorkerThread* aThread);
1097 void
1098 AssertIsOnWorkerThread() const
1099 #ifdef DEBUG
1101 #else
1103 #endif
1105 WorkerCrossThreadDispatcher*
1106 GetCrossThreadDispatcher();
1108 // This may block!
1109 void
1110 BeginCTypesCall();
1112 // This may block!
1113 void
1114 EndCTypesCall();
1116 void
1117 BeginCTypesCallback()
1119 // If a callback is beginning then we need to do the exact same thing as
1120 // when a ctypes call ends.
1121 EndCTypesCall();
1124 void
1125 EndCTypesCallback()
1127 // If a callback is ending then we need to do the exact same thing as
1128 // when a ctypes call begins.
1129 BeginCTypesCall();
1132 bool
1133 ConnectMessagePort(JSContext* aCx, uint64_t aMessagePortSerial);
1135 void
1136 DisconnectMessagePort(uint64_t aMessagePortSerial);
1138 MessagePort*
1139 GetMessagePort(uint64_t aMessagePortSerial);
1141 JSObject*
1142 CreateGlobalScope(JSContext* aCx);
1144 bool
1145 RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
1147 bool
1148 DumpEnabled() const
1150 AssertIsOnWorkerThread();
1151 return mPreferences[WORKERPREF_DUMP];
1154 bool
1155 DOMFetchEnabled() const
1157 AssertIsOnWorkerThread();
1158 return mPreferences[WORKERPREF_DOM_FETCH];
1161 bool
1162 OnLine() const
1164 AssertIsOnWorkerThread();
1165 return mOnLine;
1168 void
1169 StopSyncLoop(nsIEventTarget* aSyncLoopTarget, bool aResult);
1171 bool
1172 AllPendingRunnablesShouldBeCanceled() const
1174 return mCancelAllPendingRunnables;
1177 void
1178 OnProcessNextEvent(uint32_t aRecursionDepth);
1180 void
1181 AfterProcessNextEvent(uint32_t aRecursionDepth);
1183 void
1184 AssertValidSyncLoop(nsIEventTarget* aSyncLoopTarget)
1185 #ifdef DEBUG
1187 #else
1189 #endif
1191 void
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!
1201 bool
1202 WorkerScriptExecutedSuccessfully() const
1204 AssertIsOnWorkerThread();
1205 return mWorkerScriptExecutedSuccessfully;
1208 // Just like nsIAppShell::RunBeforeNextEvent. May only be called on the worker
1209 // thread.
1210 bool
1211 RunBeforeNextEvent(nsIRunnable* aRunnable);
1213 private:
1214 WorkerPrivate(JSContext* aCx, WorkerPrivate* aParent,
1215 const nsAString& aScriptURL, bool aIsChromeWorker,
1216 WorkerType aWorkerType, const nsACString& aSharedWorkerName,
1217 LoadInfo& aLoadInfo);
1219 void
1220 ClearMainEventQueue(WorkerRanOrNot aRanOrNot);
1222 bool
1223 MayContinueRunning()
1225 AssertIsOnWorkerThread();
1227 Status status;
1229 MutexAutoLock lock(mMutex);
1230 status = mStatus;
1233 if (status >= Killing) {
1234 return false;
1236 if (status >= Running) {
1237 return mKillTime.IsNull() || RemainingRunTimeMS() > 0;
1239 return true;
1242 uint32_t
1243 RemainingRunTimeMS() const;
1245 void
1246 CancelAllTimeouts(JSContext* aCx);
1248 bool
1249 ScheduleKillCloseEventRunnable(JSContext* aCx);
1251 bool
1252 ProcessAllControlRunnables()
1254 MutexAutoLock lock(mMutex);
1255 return ProcessAllControlRunnablesLocked();
1258 bool
1259 ProcessAllControlRunnablesLocked();
1261 void
1262 EnableMemoryReporter();
1264 void
1265 DisableMemoryReporter();
1267 void
1268 WaitForWorkerEvents(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
1270 void
1271 PostMessageToParentInternal(JSContext* aCx,
1272 JS::Handle<JS::Value> aMessage,
1273 const Optional<Sequence<JS::Value>>& aTransferable,
1274 bool aToMessagePort,
1275 uint64_t aMessagePortSerial,
1276 ErrorResult& aRv);
1278 void
1279 GetAllPreferences(bool aPreferences[WORKERPREF_COUNT]) const
1281 AssertIsOnWorkerThread();
1282 memcpy(aPreferences, mPreferences, WORKERPREF_COUNT * sizeof(bool));
1285 already_AddRefed<nsIEventTarget>
1286 CreateNewSyncLoop();
1288 bool
1289 RunCurrentSyncLoop();
1291 bool
1292 DestroySyncLoop(uint32_t aLoopIndex, nsIThreadInternal* aThread = nullptr);
1294 void
1295 InitializeGCTimers();
1297 void
1298 SetGCTimerMode(GCTimerMode aMode);
1300 void
1301 ShutdownGCTimers();
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
1309 public:
1310 static already_AddRefed<ChromeWorkerPrivate>
1311 Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
1312 ErrorResult& rv);
1314 static bool
1315 WorkerAvailable(JSContext* aCx, JSObject* /* unused */);
1317 private:
1318 ChromeWorkerPrivate() = delete;
1319 ChromeWorkerPrivate(const ChromeWorkerPrivate& aRHS) = delete;
1320 ChromeWorkerPrivate& operator =(const ChromeWorkerPrivate& aRHS) = delete;
1323 WorkerPrivate*
1324 GetWorkerPrivateFromContext(JSContext* aCx);
1326 WorkerPrivate*
1327 GetCurrentThreadWorkerPrivate();
1329 bool
1330 IsCurrentThreadRunningChromeWorker();
1332 JSContext*
1333 GetCurrentThreadJSContext();
1335 enum WorkerStructuredDataType
1337 DOMWORKER_SCTAG_BLOB = SCTAG_DOM_MAX,
1339 DOMWORKER_SCTAG_END
1342 const JSStructuredCloneCallbacks*
1343 WorkerStructuredCloneCallbacks(bool aMainRuntime);
1345 const JSStructuredCloneCallbacks*
1346 ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime);
1348 class AutoSyncLoopHolder
1350 WorkerPrivate* mWorkerPrivate;
1351 nsCOMPtr<nsIEventTarget> mTarget;
1352 uint32_t mIndex;
1354 public:
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);
1372 bool
1373 Run()
1375 WorkerPrivate* workerPrivate = mWorkerPrivate;
1376 mWorkerPrivate = nullptr;
1378 workerPrivate->AssertIsOnWorkerThread();
1380 return workerPrivate->RunCurrentSyncLoop();
1383 nsIEventTarget*
1384 EventTarget() const
1386 return mTarget;
1390 END_WORKERS_NAMESPACE
1392 #endif /* mozilla_dom_workers_workerprivate_h__ */