Backed out changeset 3fe07c50c854 (bug 946316) for bustage. a=backout
[gecko.git] / dom / workers / WorkerPrivate.h
blobdd75b74b076267533aa1494e9c3b9623ea39a512
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 "nsIRunnable.h"
13 #include "nsIThread.h"
14 #include "nsIThreadInternal.h"
15 #include "nsPIDOMWindow.h"
17 #include "mozilla/Assertions.h"
18 #include "mozilla/CondVar.h"
19 #include "mozilla/TimeStamp.h"
20 #include "mozilla/dom/BindingDeclarations.h"
21 #include "nsCycleCollectionParticipant.h"
22 #include "nsDataHashtable.h"
23 #include "nsDOMEventTargetHelper.h"
24 #include "nsEventQueue.h"
25 #include "nsHashKeys.h"
26 #include "nsRefPtrHashtable.h"
27 #include "nsString.h"
28 #include "nsTArray.h"
29 #include "nsThreadUtils.h"
30 #include "nsTPriorityQueue.h"
31 #include "StructuredCloneTags.h"
33 #include "Queue.h"
34 #include "WorkerFeature.h"
36 class JSAutoStructuredCloneBuffer;
37 class nsIChannel;
38 class nsIDocument;
39 class nsIPrincipal;
40 class nsIScriptContext;
41 class nsITimer;
42 class nsIURI;
44 namespace JS {
45 class RuntimeStats;
48 namespace mozilla {
49 namespace dom {
50 class Function;
54 BEGIN_WORKERS_NAMESPACE
56 class MessagePort;
57 class SharedWorker;
58 class WorkerGlobalScope;
59 class WorkerPrivate;
61 class WorkerRunnable : public nsIRunnable
63 public:
64 enum Target { ParentThread, WorkerThread };
65 enum BusyBehavior { ModifyBusyCount, UnchangedBusyCount };
66 enum ClearingBehavior { SkipWhenClearing, RunWhenClearing };
68 protected:
69 WorkerPrivate* mWorkerPrivate;
70 Target mTarget;
71 BusyBehavior mBusyBehavior;
72 ClearingBehavior mClearingBehavior;
74 public:
75 NS_DECL_THREADSAFE_ISUPPORTS
77 bool
78 Dispatch(JSContext* aCx);
80 static bool
81 DispatchToMainThread(nsIRunnable*);
83 bool
84 WantsToRunDuringClear()
86 return mClearingBehavior == RunWhenClearing;
89 protected:
90 WorkerRunnable(WorkerPrivate* aWorkerPrivate, Target aTarget,
91 BusyBehavior aBusyBehavior,
92 ClearingBehavior aClearingBehavior)
93 #ifdef DEBUG
95 #else
96 : mWorkerPrivate(aWorkerPrivate), mTarget(aTarget),
97 mBusyBehavior(aBusyBehavior), mClearingBehavior(aClearingBehavior)
98 { }
99 #endif
101 virtual ~WorkerRunnable()
104 virtual bool
105 PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
107 virtual void
108 PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
109 bool aDispatchResult);
111 virtual bool
112 DispatchInternal();
114 virtual bool
115 WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) = 0;
117 virtual void
118 PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate, bool aRunResult);
120 public:
121 NS_DECL_NSIRUNNABLE
124 class WorkerSyncRunnable : public WorkerRunnable
126 protected:
127 uint32_t mSyncQueueKey;
128 bool mBypassSyncQueue;
130 protected:
131 friend class WorkerPrivate;
133 WorkerSyncRunnable(WorkerPrivate* aWorkerPrivate, uint32_t aSyncQueueKey,
134 bool aBypassSyncQueue = false,
135 ClearingBehavior aClearingBehavior = SkipWhenClearing)
136 : WorkerRunnable(aWorkerPrivate, WorkerThread, UnchangedBusyCount,
137 aClearingBehavior),
138 mSyncQueueKey(aSyncQueueKey), mBypassSyncQueue(aBypassSyncQueue)
141 virtual ~WorkerSyncRunnable()
144 virtual bool
145 DispatchInternal() MOZ_OVERRIDE;
148 class MainThreadSyncRunnable : public WorkerSyncRunnable
150 public:
151 MainThreadSyncRunnable(WorkerPrivate* aWorkerPrivate,
152 ClearingBehavior aClearingBehavior,
153 uint32_t aSyncQueueKey,
154 bool aBypassSyncEventQueue)
155 : WorkerSyncRunnable(aWorkerPrivate, aSyncQueueKey, aBypassSyncEventQueue,
156 aClearingBehavior)
158 AssertIsOnMainThread();
161 bool
162 PreDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate) MOZ_OVERRIDE
164 AssertIsOnMainThread();
165 return true;
168 void
169 PostDispatch(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
170 bool aDispatchResult) MOZ_OVERRIDE
172 AssertIsOnMainThread();
176 class WorkerControlRunnable : public WorkerRunnable
178 protected:
179 WorkerControlRunnable(WorkerPrivate* aWorkerPrivate, Target aTarget,
180 BusyBehavior aBusyBehavior)
181 : WorkerRunnable(aWorkerPrivate, aTarget, aBusyBehavior, SkipWhenClearing)
184 virtual ~WorkerControlRunnable()
187 virtual bool
188 DispatchInternal() MOZ_OVERRIDE;
191 // SharedMutex is a small wrapper around an (internal) reference-counted Mutex
192 // object. It exists to avoid changing a lot of code to use Mutex* instead of
193 // Mutex&.
194 class SharedMutex
196 typedef mozilla::Mutex Mutex;
198 class RefCountedMutex : public Mutex
200 public:
201 RefCountedMutex(const char* aName)
202 : Mutex(aName)
205 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMutex)
207 private:
208 ~RefCountedMutex()
212 nsRefPtr<RefCountedMutex> mMutex;
214 public:
215 SharedMutex(const char* aName)
216 : mMutex(new RefCountedMutex(aName))
219 SharedMutex(SharedMutex& aOther)
220 : mMutex(aOther.mMutex)
223 operator Mutex&()
225 MOZ_ASSERT(mMutex);
226 return *mMutex;
229 operator const Mutex&() const
231 MOZ_ASSERT(mMutex);
232 return *mMutex;
235 void
236 AssertCurrentThreadOwns() const
238 MOZ_ASSERT(mMutex);
239 mMutex->AssertCurrentThreadOwns();
243 template <class Derived>
244 class WorkerPrivateParent : public nsDOMEventTargetHelper
246 class SynchronizeAndResumeRunnable;
248 public:
249 struct LocationInfo
251 nsCString mHref;
252 nsCString mProtocol;
253 nsCString mHost;
254 nsCString mHostname;
255 nsCString mPort;
256 nsCString mPathname;
257 nsCString mSearch;
258 nsCString mHash;
261 struct LoadInfo
263 // All of these should be released in ForgetMainThreadObjects.
264 nsCOMPtr<nsIURI> mBaseURI;
265 nsCOMPtr<nsIURI> mResolvedScriptURI;
266 nsCOMPtr<nsIPrincipal> mPrincipal;
267 nsCOMPtr<nsIScriptContext> mScriptContext;
268 nsCOMPtr<nsPIDOMWindow> mWindow;
269 nsCOMPtr<nsIContentSecurityPolicy> mCSP;
270 nsCOMPtr<nsIChannel> mChannel;
272 nsCString mDomain;
274 bool mEvalAllowed;
275 bool mReportCSPViolations;
276 bool mXHRParamsAllowed;
277 bool mPrincipalIsSystem;
279 LoadInfo()
280 : mEvalAllowed(false), mReportCSPViolations(false),
281 mXHRParamsAllowed(false), mPrincipalIsSystem(false)
284 void
285 StealFrom(LoadInfo& aOther)
287 mBaseURI = aOther.mBaseURI.forget();
288 mResolvedScriptURI = aOther.mResolvedScriptURI.forget();
289 mPrincipal = aOther.mPrincipal.forget();
290 mScriptContext = aOther.mScriptContext.forget();
291 mWindow = aOther.mWindow.forget();
292 mCSP = aOther.mCSP.forget();
293 mChannel = aOther.mChannel.forget();
294 mDomain = aOther.mDomain;
295 mEvalAllowed = aOther.mEvalAllowed;
296 mReportCSPViolations = aOther.mReportCSPViolations;
297 mXHRParamsAllowed = aOther.mXHRParamsAllowed;
298 mPrincipalIsSystem = aOther.mPrincipalIsSystem;
302 enum WorkerType
304 WorkerTypeDedicated,
305 WorkerTypeShared
308 protected:
309 typedef mozilla::ErrorResult ErrorResult;
311 SharedMutex mMutex;
312 mozilla::CondVar mCondVar;
313 mozilla::CondVar mMemoryReportCondVar;
315 private:
316 WorkerPrivate* mParent;
317 nsString mScriptURL;
318 nsString mSharedWorkerName;
319 LocationInfo mLocationInfo;
320 // The lifetime of these objects within LoadInfo is managed explicitly;
321 // they do not need to be cycle collected.
322 LoadInfo mLoadInfo;
324 // Only used for top level workers.
325 nsTArray<nsRefPtr<WorkerRunnable> > mQueuedRunnables;
326 nsRevocableEventPtr<SynchronizeAndResumeRunnable> mSynchronizeRunnable;
328 // Only for ChromeWorkers without window and only touched on the main thread.
329 nsTArray<nsCString> mHostObjectURIs;
331 // Protected by mMutex.
332 JSSettings mJSSettings;
334 // Only touched on the parent thread (currently this is always the main
335 // thread as SharedWorkers are always top-level).
336 nsDataHashtable<nsUint64HashKey, SharedWorker*> mSharedWorkers;
338 uint64_t mBusyCount;
339 uint64_t mMessagePortSerial;
340 Status mParentStatus;
341 bool mRooted;
342 bool mParentSuspended;
343 bool mIsChromeWorker;
344 bool mMainThreadObjectsForgotten;
345 WorkerType mWorkerType;
347 protected:
348 WorkerPrivateParent(JSContext* aCx, WorkerPrivate* aParent,
349 const nsAString& aScriptURL, bool aIsChromeWorker,
350 WorkerType aWorkerType,
351 const nsAString& aSharedWorkerName, LoadInfo& aLoadInfo);
353 ~WorkerPrivateParent();
355 private:
356 Derived*
357 ParentAsWorkerPrivate() const
359 return static_cast<Derived*>(const_cast<WorkerPrivateParent*>(this));
362 // aCx is null when called from the finalizer
363 bool
364 NotifyPrivate(JSContext* aCx, Status aStatus);
366 // aCx is null when called from the finalizer
367 bool
368 TerminatePrivate(JSContext* aCx)
370 return NotifyPrivate(aCx, Terminating);
373 void
374 PostMessageInternal(JSContext* aCx, JS::Handle<JS::Value> aMessage,
375 const Optional<Sequence<JS::Value> >& aTransferable,
376 bool aToMessagePort, uint64_t aMessagePortSerial,
377 ErrorResult& aRv);
379 public:
381 virtual JSObject*
382 WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
384 NS_DECL_ISUPPORTS_INHERITED
385 NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(WorkerPrivateParent,
386 nsDOMEventTargetHelper)
388 // May be called on any thread...
389 bool
390 Start();
392 // Called on the parent thread.
393 bool
394 Notify(JSContext* aCx, Status aStatus)
396 return NotifyPrivate(aCx, aStatus);
399 bool
400 Cancel(JSContext* aCx)
402 return Notify(aCx, Canceling);
405 bool
406 Kill(JSContext* aCx)
408 return Notify(aCx, Killing);
411 bool
412 Suspend(JSContext* aCx, nsPIDOMWindow* aWindow);
414 bool
415 Resume(JSContext* aCx, nsPIDOMWindow* aWindow);
417 bool
418 SynchronizeAndResume(JSContext* aCx, nsPIDOMWindow* aWindow,
419 nsIScriptContext* aScriptContext);
421 void
422 _finalize(JSFreeOp* aFop);
424 void
425 Finish(JSContext* aCx)
427 Root(false);
430 bool
431 Terminate(JSContext* aCx)
433 AssertIsOnParentThread();
434 Root(false);
435 return TerminatePrivate(aCx);
438 bool
439 Close(JSContext* aCx);
441 bool
442 ModifyBusyCount(JSContext* aCx, bool aIncrease);
444 void
445 Root(bool aRoot);
447 void
448 ForgetMainThreadObjects(nsTArray<nsCOMPtr<nsISupports> >& aDoomed);
450 void
451 PostMessage(JSContext* aCx, JS::Handle<JS::Value> aMessage,
452 const Optional<Sequence<JS::Value> >& aTransferable,
453 ErrorResult& aRv)
455 PostMessageInternal(aCx, aMessage, aTransferable, false, 0, aRv);
458 void
459 PostMessageToMessagePort(JSContext* aCx,
460 uint64_t aMessagePortSerial,
461 JS::Handle<JS::Value> aMessage,
462 const Optional<Sequence<JS::Value> >& aTransferable,
463 ErrorResult& aRv);
465 bool
466 DispatchMessageEventToMessagePort(
467 JSContext* aCx,
468 uint64_t aMessagePortSerial,
469 JSAutoStructuredCloneBuffer& aBuffer,
470 nsTArray<nsCOMPtr<nsISupports>>& aClonedObjects);
472 uint64_t
473 GetInnerWindowId();
475 void
476 UpdateJSContextOptions(JSContext* aCx, const JS::ContextOptions& aChromeOptions,
477 const JS::ContextOptions& aContentOptions);
479 void
480 UpdatePreference(JSContext* aCx, WorkerPreference aPref, bool aValue);
482 void
483 UpdateJSWorkerMemoryParameter(JSContext* aCx, JSGCParamKey key,
484 uint32_t value);
486 #ifdef JS_GC_ZEAL
487 void
488 UpdateGCZeal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
489 #endif
491 void
492 UpdateJITHardening(JSContext* aCx, bool aJITHardening);
494 void
495 GarbageCollect(JSContext* aCx, bool aShrinking);
497 void
498 CycleCollect(JSContext* aCx, bool aDummy);
500 bool
501 RegisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker);
503 void
504 UnregisterSharedWorker(JSContext* aCx, SharedWorker* aSharedWorker);
506 void
507 BroadcastErrorToSharedWorkers(JSContext* aCx,
508 const nsAString& aMessage,
509 const nsAString& aFilename,
510 const nsAString& aLine,
511 uint32_t aLineNumber,
512 uint32_t aColumnNumber,
513 uint32_t aFlags);
515 void
516 WorkerScriptLoaded();
518 void
519 QueueRunnable(WorkerRunnable* aRunnable)
521 AssertIsOnMainThread();
522 mQueuedRunnables.AppendElement(aRunnable);
525 WorkerPrivate*
526 GetParent() const
528 return mParent;
531 bool
532 IsSuspended() const
534 AssertIsOnParentThread();
535 return mParentSuspended;
538 bool
539 IsAcceptingEvents()
541 AssertIsOnParentThread();
542 bool acceptingEvents;
544 mozilla::MutexAutoLock lock(mMutex);
545 acceptingEvents = mParentStatus < Terminating;
547 return acceptingEvents;
550 Status
551 ParentStatus() const
553 mMutex.AssertCurrentThreadOwns();
554 return mParentStatus;
557 JSContext*
558 ParentJSContext() const;
560 nsIScriptContext*
561 GetScriptContext() const
563 AssertIsOnMainThread();
564 return mLoadInfo.mScriptContext;
567 const nsString&
568 ScriptURL() const
570 return mScriptURL;
573 const nsCString&
574 Domain() const
576 return mLoadInfo.mDomain;
579 nsIURI*
580 GetBaseURI() const
582 AssertIsOnMainThread();
583 return mLoadInfo.mBaseURI;
586 void
587 SetBaseURI(nsIURI* aBaseURI);
589 nsIURI*
590 GetResolvedScriptURI() const
592 AssertIsOnMainThread();
593 return mLoadInfo.mResolvedScriptURI;
596 nsIPrincipal*
597 GetPrincipal() const
599 AssertIsOnMainThread();
600 return mLoadInfo.mPrincipal;
603 void
604 SetPrincipal(nsIPrincipal* aPrincipal);
606 bool
607 UsesSystemPrincipal() const
609 return mLoadInfo.mPrincipalIsSystem;
612 already_AddRefed<nsIChannel>
613 ForgetWorkerChannel()
615 AssertIsOnMainThread();
616 return mLoadInfo.mChannel.forget();
619 nsIDocument*
620 GetDocument() const
622 AssertIsOnMainThread();
623 return mLoadInfo.mWindow ? mLoadInfo.mWindow->GetExtantDoc() : nullptr;
626 nsPIDOMWindow*
627 GetWindow()
629 AssertIsOnMainThread();
630 return mLoadInfo.mWindow;
633 nsIContentSecurityPolicy*
634 GetCSP() const
636 AssertIsOnMainThread();
637 return mLoadInfo.mCSP;
640 void
641 SetCSP(nsIContentSecurityPolicy* aCSP)
643 AssertIsOnMainThread();
644 mLoadInfo.mCSP = aCSP;
647 bool
648 IsEvalAllowed() const
650 return mLoadInfo.mEvalAllowed;
653 void
654 SetEvalAllowed(bool aEvalAllowed)
656 mLoadInfo.mEvalAllowed = aEvalAllowed;
659 bool
660 GetReportCSPViolations() const
662 return mLoadInfo.mReportCSPViolations;
665 bool
666 XHRParamsAllowed() const
668 return mLoadInfo.mXHRParamsAllowed;
671 void
672 SetXHRParamsAllowed(bool aAllowed)
674 mLoadInfo.mXHRParamsAllowed = aAllowed;
677 LocationInfo&
678 GetLocationInfo()
680 return mLocationInfo;
683 void
684 CopyJSSettings(JSSettings& aSettings)
686 mozilla::MutexAutoLock lock(mMutex);
687 aSettings = mJSSettings;
690 // The ability to be a chrome worker is orthogonal to the type of
691 // worker [Dedicated|Shared].
692 bool
693 IsChromeWorker() const
695 return mIsChromeWorker;
698 bool
699 IsDedicatedWorker() const
701 return mWorkerType == WorkerTypeDedicated;
704 bool
705 IsSharedWorker() const
707 return mWorkerType == WorkerTypeShared;
710 const nsString&
711 SharedWorkerName() const
713 return mSharedWorkerName;
716 uint64_t
717 NextMessagePortSerial()
719 AssertIsOnMainThread();
720 return mMessagePortSerial++;
723 void
724 GetAllSharedWorkers(nsTArray<nsRefPtr<SharedWorker>>& aSharedWorkers);
726 void
727 CloseSharedWorkersForWindow(nsPIDOMWindow* aWindow);
729 void
730 RegisterHostObjectURI(const nsACString& aURI);
732 void
733 UnregisterHostObjectURI(const nsACString& aURI);
735 void
736 StealHostObjectURIs(nsTArray<nsCString>& aArray);
738 IMPL_EVENT_HANDLER(message)
739 IMPL_EVENT_HANDLER(error)
741 #ifdef DEBUG
742 void
743 AssertIsOnParentThread() const;
745 void
746 AssertInnerWindowIsCorrect() const;
747 #else
748 void
749 AssertIsOnParentThread() const
752 void
753 AssertInnerWindowIsCorrect() const
755 #endif
758 class WorkerPrivate : public WorkerPrivateParent<WorkerPrivate>
760 friend class WorkerPrivateParent<WorkerPrivate>;
761 typedef WorkerPrivateParent<WorkerPrivate> ParentType;
763 struct TimeoutInfo;
765 typedef Queue<WorkerRunnable*, 50> EventQueue;
766 EventQueue mQueue;
767 EventQueue mControlQueue;
769 struct SyncQueue
771 Queue<WorkerRunnable*, 10> mQueue;
772 bool mComplete;
773 bool mResult;
775 SyncQueue()
776 : mComplete(false), mResult(false)
779 ~SyncQueue()
781 WorkerRunnable* event;
782 while (mQueue.Pop(event)) {
783 event->Release();
788 class MemoryReporter;
789 friend class MemoryReporter;
791 nsTArray<nsAutoPtr<SyncQueue> > mSyncQueues;
793 // Touched on multiple threads, protected with mMutex.
794 JSContext* mJSContext;
795 nsRefPtr<WorkerCrossThreadDispatcher> mCrossThreadDispatcher;
797 // Things touched on worker thread only.
798 nsRefPtr<WorkerGlobalScope> mScope;
799 nsTArray<ParentType*> mChildWorkers;
800 nsTArray<WorkerFeature*> mFeatures;
801 nsTArray<nsAutoPtr<TimeoutInfo> > mTimeouts;
803 nsCOMPtr<nsITimer> mTimer;
804 nsRefPtr<MemoryReporter> mMemoryReporter;
806 nsRefPtrHashtable<nsUint64HashKey, MessagePort> mWorkerPorts;
808 mozilla::TimeStamp mKillTime;
809 uint32_t mErrorHandlerRecursionCount;
810 uint32_t mNextTimeoutId;
811 Status mStatus;
812 bool mSuspended;
813 bool mTimerRunning;
814 bool mRunningExpiredTimeouts;
815 bool mCloseHandlerStarted;
816 bool mCloseHandlerFinished;
817 bool mMemoryReporterRunning;
818 bool mBlockedForMemoryReporter;
820 #ifdef DEBUG
821 nsCOMPtr<nsIThread> mThread;
822 #endif
824 bool mPreferences[WORKERPREF_COUNT];
826 protected:
827 ~WorkerPrivate();
829 public:
830 static already_AddRefed<WorkerPrivate>
831 Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
832 ErrorResult& aRv);
834 static already_AddRefed<WorkerPrivate>
835 Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
836 bool aIsChromeWorker, WorkerType aWorkerType,
837 const nsAString& aSharedWorkerName,
838 LoadInfo* aLoadInfo, ErrorResult& aRv);
840 static bool
841 WorkerAvailable(JSContext* /* unused */, JSObject* /* unused */);
843 static nsresult
844 GetLoadInfo(JSContext* aCx, nsPIDOMWindow* aWindow, WorkerPrivate* aParent,
845 const nsAString& aScriptURL, bool aIsChromeWorker,
846 LoadInfo* aLoadInfo);
848 void
849 DoRunLoop(JSContext* aCx);
851 bool
852 OperationCallback(JSContext* aCx);
854 bool
855 Dispatch(WorkerRunnable* aEvent)
857 return Dispatch(aEvent, &mQueue);
860 bool
861 Dispatch(WorkerSyncRunnable* aEvent)
863 if (aEvent->mBypassSyncQueue) {
864 return Dispatch(aEvent, &mQueue);
867 return DispatchToSyncQueue(aEvent);
870 bool
871 Dispatch(WorkerControlRunnable* aEvent)
873 return Dispatch(aEvent, &mControlQueue);
876 bool
877 CloseInternal(JSContext* aCx)
879 AssertIsOnWorkerThread();
880 return NotifyInternal(aCx, Closing);
883 bool
884 SuspendInternal(JSContext* aCx);
886 bool
887 ResumeInternal(JSContext* aCx);
889 void
890 TraceTimeouts(const TraceCallbacks& aCallbacks, void* aClosure) const;
892 bool
893 ModifyBusyCountFromWorker(JSContext* aCx, bool aIncrease);
895 bool
896 AddChildWorker(JSContext* aCx, ParentType* aChildWorker);
898 void
899 RemoveChildWorker(JSContext* aCx, ParentType* aChildWorker);
901 bool
902 AddFeature(JSContext* aCx, WorkerFeature* aFeature);
904 void
905 RemoveFeature(JSContext* aCx, WorkerFeature* aFeature);
907 void
908 NotifyFeatures(JSContext* aCx, Status aStatus);
910 bool
911 HasActiveFeatures()
913 return !(mChildWorkers.IsEmpty() && mTimeouts.IsEmpty() &&
914 mFeatures.IsEmpty());
917 uint32_t
918 CreateNewSyncLoop();
920 bool
921 RunSyncLoop(JSContext* aCx, uint32_t aSyncLoopKey);
923 void
924 StopSyncLoop(uint32_t aSyncLoopKey, bool aSyncResult);
926 void
927 DestroySyncLoop(uint32_t aSyncLoopKey);
929 void
930 PostMessageToParent(JSContext* aCx,
931 JS::Handle<JS::Value> aMessage,
932 const Optional<Sequence<JS::Value>>& aTransferable,
933 ErrorResult& aRv)
935 PostMessageToParentInternal(aCx, aMessage, aTransferable, false, 0, aRv);
938 void
939 PostMessageToParentMessagePort(
940 JSContext* aCx,
941 uint64_t aMessagePortSerial,
942 JS::Handle<JS::Value> aMessage,
943 const Optional<Sequence<JS::Value>>& aTransferable,
944 ErrorResult& aRv);
946 bool
947 NotifyInternal(JSContext* aCx, Status aStatus);
949 void
950 ReportError(JSContext* aCx, const char* aMessage, JSErrorReport* aReport);
952 int32_t
953 SetTimeout(JSContext* aCx,
954 Function* aHandler,
955 const nsAString& aStringHandler,
956 int32_t aTimeout,
957 const Sequence<JS::Value>& aArguments,
958 bool aIsInterval,
959 ErrorResult& aRv);
961 void
962 ClearTimeout(int32_t aId);
964 bool
965 RunExpiredTimeouts(JSContext* aCx);
967 bool
968 RescheduleTimeoutTimer(JSContext* aCx);
970 void
971 CloseHandlerStarted()
973 AssertIsOnWorkerThread();
974 mCloseHandlerStarted = true;
977 void
978 CloseHandlerFinished()
980 AssertIsOnWorkerThread();
981 mCloseHandlerFinished = true;
984 void
985 UpdateJSContextOptionsInternal(JSContext* aCx, const JS::ContextOptions& aContentOptions,
986 const JS::ContextOptions& aChromeOptions);
988 void
989 UpdatePreferenceInternal(JSContext* aCx, WorkerPreference aPref, bool aValue);
991 void
992 UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
994 void
995 ScheduleDeletion(bool aWasPending);
997 bool
998 BlockAndCollectRuntimeStats(JS::RuntimeStats* aRtStats);
1000 #ifdef JS_GC_ZEAL
1001 void
1002 UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
1003 #endif
1005 void
1006 UpdateJITHardeningInternal(JSContext* aCx, bool aJITHardening);
1008 void
1009 GarbageCollectInternal(JSContext* aCx, bool aShrinking,
1010 bool aCollectChildren);
1012 void
1013 CycleCollectInternal(JSContext* aCx, bool aCollectChildren);
1015 JSContext*
1016 GetJSContext() const
1018 AssertIsOnWorkerThread();
1019 return mJSContext;
1022 WorkerGlobalScope*
1023 GlobalScope() const
1025 AssertIsOnWorkerThread();
1026 return mScope;
1029 #ifdef DEBUG
1030 void
1031 AssertIsOnWorkerThread() const;
1033 void
1034 SetThread(nsIThread* aThread)
1036 mThread = aThread;
1038 #else
1039 void
1040 AssertIsOnWorkerThread() const
1042 #endif
1044 WorkerCrossThreadDispatcher*
1045 GetCrossThreadDispatcher();
1047 // This may block!
1048 void
1049 BeginCTypesCall();
1051 // This may block!
1052 void
1053 EndCTypesCall();
1055 void
1056 BeginCTypesCallback()
1058 // If a callback is beginning then we need to do the exact same thing as
1059 // when a ctypes call ends.
1060 EndCTypesCall();
1063 void
1064 EndCTypesCallback()
1066 // If a callback is ending then we need to do the exact same thing as
1067 // when a ctypes call begins.
1068 BeginCTypesCall();
1071 bool
1072 ConnectMessagePort(JSContext* aCx, uint64_t aMessagePortSerial);
1074 void
1075 DisconnectMessagePort(uint64_t aMessagePortSerial);
1077 MessagePort*
1078 GetMessagePort(uint64_t aMessagePortSerial);
1080 JSObject*
1081 CreateGlobalScope(JSContext* aCx);
1083 bool
1084 RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
1086 bool
1087 DumpEnabled() const
1089 AssertIsOnWorkerThread();
1090 return mPreferences[WORKERPREF_DUMP];
1093 bool
1094 PromiseEnabled() const
1096 AssertIsOnWorkerThread();
1097 return mPreferences[WORKERPREF_PROMISE];
1100 private:
1101 WorkerPrivate(JSContext* aCx, WorkerPrivate* aParent,
1102 const nsAString& aScriptURL, bool aIsChromeWorker,
1103 WorkerType aWorkerType, const nsAString& aSharedWorkerName,
1104 LoadInfo& aLoadInfo);
1106 bool
1107 Dispatch(WorkerRunnable* aEvent, EventQueue* aQueue);
1109 bool
1110 DispatchToSyncQueue(WorkerSyncRunnable* aEvent);
1112 void
1113 ClearQueue(EventQueue* aQueue);
1115 bool
1116 MayContinueRunning()
1118 AssertIsOnWorkerThread();
1120 Status status;
1122 mozilla::MutexAutoLock lock(mMutex);
1123 status = mStatus;
1126 if (status >= Killing) {
1127 return false;
1129 if (status >= Running) {
1130 return mKillTime.IsNull() || RemainingRunTimeMS() > 0;
1132 return true;
1135 uint32_t
1136 RemainingRunTimeMS() const;
1138 void
1139 CancelAllTimeouts(JSContext* aCx);
1141 bool
1142 ScheduleKillCloseEventRunnable(JSContext* aCx);
1144 void
1145 StopAcceptingEvents()
1147 AssertIsOnWorkerThread();
1149 mozilla::MutexAutoLock lock(mMutex);
1151 mStatus = Dead;
1152 mJSContext = nullptr;
1154 ClearQueue(&mControlQueue);
1155 ClearQueue(&mQueue);
1158 bool
1159 ProcessAllControlRunnables();
1161 void
1162 EnableMemoryReporter();
1164 void
1165 DisableMemoryReporter();
1167 void
1168 WaitForWorkerEvents(PRIntervalTime interval = PR_INTERVAL_NO_TIMEOUT);
1170 void
1171 PostMessageToParentInternal(JSContext* aCx,
1172 JS::Handle<JS::Value> aMessage,
1173 const Optional<Sequence<JS::Value>>& aTransferable,
1174 bool aToMessagePort,
1175 uint64_t aMessagePortSerial,
1176 ErrorResult& aRv);
1178 void
1179 GetAllPreferences(bool aPreferences[WORKERPREF_COUNT]) const
1181 AssertIsOnWorkerThread();
1182 memcpy(aPreferences, mPreferences, WORKERPREF_COUNT * sizeof(bool));
1186 // This class is only used to trick the DOM bindings. We never create
1187 // instances of it, and static_casting to it is fine since it doesn't add
1188 // anything to WorkerPrivate.
1189 class ChromeWorkerPrivate : public WorkerPrivate
1191 public:
1192 static already_AddRefed<ChromeWorkerPrivate>
1193 Constructor(const GlobalObject& aGlobal, const nsAString& aScriptURL,
1194 ErrorResult& rv);
1196 static bool
1197 WorkerAvailable(JSContext* /* unused */, JSObject* /* unused */);
1199 private:
1200 ChromeWorkerPrivate() MOZ_DELETE;
1201 ChromeWorkerPrivate(const ChromeWorkerPrivate& aRHS) MOZ_DELETE;
1202 ChromeWorkerPrivate& operator =(const ChromeWorkerPrivate& aRHS) MOZ_DELETE;
1205 WorkerPrivate*
1206 GetWorkerPrivateFromContext(JSContext* aCx);
1208 WorkerPrivate*
1209 GetCurrentThreadWorkerPrivate();
1211 bool
1212 IsCurrentThreadRunningChromeWorker();
1214 JSContext*
1215 GetCurrentThreadJSContext();
1217 enum WorkerStructuredDataType
1219 DOMWORKER_SCTAG_FILE = SCTAG_DOM_MAX,
1220 DOMWORKER_SCTAG_BLOB,
1222 DOMWORKER_SCTAG_END
1225 JSStructuredCloneCallbacks*
1226 WorkerStructuredCloneCallbacks(bool aMainRuntime);
1228 JSStructuredCloneCallbacks*
1229 ChromeWorkerStructuredCloneCallbacks(bool aMainRuntime);
1231 class AutoSyncLoopHolder
1233 public:
1234 AutoSyncLoopHolder(WorkerPrivate* aWorkerPrivate)
1235 : mWorkerPrivate(aWorkerPrivate), mSyncLoopKey(UINT32_MAX)
1237 mSyncLoopKey = mWorkerPrivate->CreateNewSyncLoop();
1240 ~AutoSyncLoopHolder()
1242 if (mWorkerPrivate) {
1243 mWorkerPrivate->StopSyncLoop(mSyncLoopKey, false);
1244 mWorkerPrivate->DestroySyncLoop(mSyncLoopKey);
1248 bool
1249 RunAndForget(JSContext* aCx)
1251 WorkerPrivate* workerPrivate = mWorkerPrivate;
1252 mWorkerPrivate = nullptr;
1253 return workerPrivate->RunSyncLoop(aCx, mSyncLoopKey);
1256 uint32_t
1257 SyncQueueKey() const
1259 return mSyncLoopKey;
1262 private:
1263 WorkerPrivate* mWorkerPrivate;
1264 uint32_t mSyncLoopKey;
1267 END_WORKERS_NAMESPACE
1269 #endif /* mozilla_dom_workers_workerprivate_h__ */