Line data Source code
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_workerprivate_h__
8 : #define mozilla_dom_workers_workerprivate_h__
9 :
10 : #include "mozilla/dom/WorkerCommon.h"
11 : #include "mozilla/CondVar.h"
12 : #include "mozilla/DOMEventTargetHelper.h"
13 : #include "mozilla/RelativeTimeline.h"
14 : #include "nsIContentSecurityPolicy.h"
15 : #include "nsIEventTarget.h"
16 : #include "nsTObserverArray.h"
17 :
18 : #include "mozilla/dom/Worker.h"
19 : #include "mozilla/dom/WorkerHolder.h"
20 : #include "mozilla/dom/WorkerLoadInfo.h"
21 : #include "mozilla/dom/workerinternals/JSSettings.h"
22 : #include "mozilla/dom/workerinternals/Queue.h"
23 : #include "mozilla/PerformanceCounter.h"
24 :
25 : class nsIConsoleReportCollector;
26 : class nsIThreadInternal;
27 :
28 : namespace mozilla {
29 : namespace dom {
30 :
31 : // If you change this, the corresponding list in nsIWorkerDebugger.idl needs
32 : // to be updated too.
33 : enum WorkerType
34 : {
35 : WorkerTypeDedicated,
36 : WorkerTypeShared,
37 : WorkerTypeService
38 : };
39 :
40 : class ClientInfo;
41 : class ClientSource;
42 : class Function;
43 : class MessagePort;
44 : class MessagePortIdentifier;
45 : class PerformanceStorage;
46 : class SharedWorker;
47 : class WorkerControlRunnable;
48 : class WorkerDebugger;
49 : class WorkerDebuggerGlobalScope;
50 : class WorkerErrorReport;
51 : class WorkerEventTarget;
52 : class WorkerGlobalScope;
53 : class WorkerRunnable;
54 : class WorkerThread;
55 :
56 : // SharedMutex is a small wrapper around an (internal) reference-counted Mutex
57 : // object. It exists to avoid changing a lot of code to use Mutex* instead of
58 : // Mutex&.
59 : class SharedMutex
60 : {
61 : typedef mozilla::Mutex Mutex;
62 :
63 : class RefCountedMutex final : public Mutex
64 : {
65 : public:
66 : explicit RefCountedMutex(const char* aName)
67 : : Mutex(aName)
68 : { }
69 :
70 : NS_INLINE_DECL_THREADSAFE_REFCOUNTING(RefCountedMutex)
71 :
72 : private:
73 : ~RefCountedMutex()
74 : { }
75 : };
76 :
77 : RefPtr<RefCountedMutex> mMutex;
78 :
79 : public:
80 : explicit SharedMutex(const char* aName)
81 : : mMutex(new RefCountedMutex(aName))
82 : { }
83 :
84 : SharedMutex(SharedMutex& aOther)
85 : : mMutex(aOther.mMutex)
86 : { }
87 :
88 : operator Mutex&()
89 : {
90 2 : return *mMutex;
91 : }
92 :
93 : operator const Mutex&() const
94 : {
95 : return *mMutex;
96 : }
97 :
98 : void
99 : AssertCurrentThreadOwns() const
100 : {
101 : mMutex->AssertCurrentThreadOwns();
102 : }
103 : };
104 :
105 : class WorkerPrivate
106 : : public RelativeTimeline
107 : {
108 : public:
109 : struct LocationInfo
110 : {
111 : nsCString mHref;
112 : nsCString mProtocol;
113 : nsCString mHost;
114 : nsCString mHostname;
115 : nsCString mPort;
116 : nsCString mPathname;
117 : nsCString mSearch;
118 : nsCString mHash;
119 : nsString mOrigin;
120 : };
121 :
122 2 : NS_INLINE_DECL_REFCOUNTING(WorkerPrivate)
123 :
124 : static already_AddRefed<WorkerPrivate>
125 : Constructor(JSContext* aCx, const nsAString& aScriptURL, bool aIsChromeWorker,
126 : WorkerType aWorkerType, const nsAString& aWorkerName,
127 : const nsACString& aServiceWorkerScope,
128 : WorkerLoadInfo* aLoadInfo, ErrorResult& aRv);
129 :
130 : enum LoadGroupBehavior
131 : {
132 : InheritLoadGroup,
133 : OverrideLoadGroup
134 : };
135 :
136 : static nsresult
137 : GetLoadInfo(JSContext* aCx, nsPIDOMWindowInner* aWindow,
138 : WorkerPrivate* aParent,
139 : const nsAString& aScriptURL, bool aIsChromeWorker,
140 : LoadGroupBehavior aLoadGroupBehavior, WorkerType aWorkerType,
141 : WorkerLoadInfo* aLoadInfo);
142 :
143 : void
144 : Traverse(nsCycleCollectionTraversalCallback& aCb);
145 :
146 : void
147 : ClearSelfAndParentEventTargetRef()
148 : {
149 : AssertIsOnParentThread();
150 : MOZ_ASSERT(mSelfRef);
151 : mParentEventTargetRef = nullptr;
152 : mSelfRef = nullptr;
153 : }
154 :
155 : // May be called on any thread...
156 : bool
157 : Start();
158 :
159 : // Called on the parent thread.
160 : bool
161 : Notify(WorkerStatus aStatus);
162 :
163 : bool
164 0 : Cancel()
165 : {
166 0 : return Notify(Canceling);
167 : }
168 :
169 : bool
170 0 : Kill()
171 : {
172 0 : return Notify(Killing);
173 : }
174 :
175 : bool
176 0 : Terminate()
177 : {
178 0 : return Notify(Terminating);
179 : }
180 :
181 : bool
182 : Close();
183 :
184 : // The passed principal must be the Worker principal in case of a
185 : // ServiceWorker and the loading principal for any other type.
186 : static void
187 : OverrideLoadInfoLoadGroup(WorkerLoadInfo& aLoadInfo,
188 : nsIPrincipal* aPrincipal);
189 :
190 : bool
191 : IsDebuggerRegistered()
192 : {
193 0 : AssertIsOnMainThread();
194 :
195 : // No need to lock here since this is only ever modified by the same thread.
196 0 : return mDebuggerRegistered;
197 : }
198 :
199 : void
200 6 : SetIsDebuggerRegistered(bool aDebuggerRegistered)
201 : {
202 6 : AssertIsOnMainThread();
203 :
204 18 : MutexAutoLock lock(mMutex);
205 :
206 6 : MOZ_ASSERT(mDebuggerRegistered != aDebuggerRegistered);
207 6 : mDebuggerRegistered = aDebuggerRegistered;
208 :
209 12 : mCondVar.Notify();
210 6 : }
211 :
212 : void
213 0 : WaitForIsDebuggerRegistered(bool aDebuggerRegistered)
214 : {
215 0 : AssertIsOnParentThread();
216 :
217 0 : MOZ_ASSERT(!NS_IsMainThread());
218 :
219 0 : MutexAutoLock lock(mMutex);
220 :
221 0 : while (mDebuggerRegistered != aDebuggerRegistered) {
222 0 : mCondVar.Wait();
223 : }
224 0 : }
225 :
226 : WorkerDebugger*
227 0 : Debugger() const
228 : {
229 0 : AssertIsOnMainThread();
230 :
231 0 : MOZ_ASSERT(mDebugger);
232 0 : return mDebugger;
233 : }
234 :
235 : void
236 6 : SetDebugger(WorkerDebugger* aDebugger)
237 : {
238 6 : AssertIsOnMainThread();
239 :
240 6 : MOZ_ASSERT(mDebugger != aDebugger);
241 6 : mDebugger = aDebugger;
242 6 : }
243 :
244 : JS::UniqueChars
245 6 : AdoptDefaultLocale()
246 : {
247 12 : MOZ_ASSERT(mDefaultLocale,
248 : "the default locale must have been successfully set for anyone "
249 : "to be trying to adopt it");
250 12 : return std::move(mDefaultLocale);
251 : }
252 :
253 : void
254 : DoRunLoop(JSContext* aCx);
255 :
256 : bool
257 : InterruptCallback(JSContext* aCx);
258 :
259 : bool
260 : IsOnCurrentThread();
261 :
262 : void
263 : CloseInternal();
264 :
265 : bool
266 : FreezeInternal();
267 :
268 : bool
269 : ThawInternal();
270 :
271 : void
272 : TraverseTimeouts(nsCycleCollectionTraversalCallback& aCallback);
273 :
274 : void
275 : UnlinkTimeouts();
276 :
277 : bool
278 : ModifyBusyCountFromWorker(bool aIncrease);
279 :
280 : bool
281 : AddChildWorker(WorkerPrivate* aChildWorker);
282 :
283 : void
284 : RemoveChildWorker(WorkerPrivate* aChildWorker);
285 :
286 : void
287 : PostMessageToParent(JSContext* aCx,
288 : JS::Handle<JS::Value> aMessage,
289 : const Sequence<JSObject*>& aTransferable,
290 : ErrorResult& aRv);
291 :
292 : void
293 : PostMessageToParentMessagePort(JSContext* aCx,
294 : JS::Handle<JS::Value> aMessage,
295 : const Sequence<JSObject*>& aTransferable,
296 : ErrorResult& aRv);
297 :
298 : void
299 : EnterDebuggerEventLoop();
300 :
301 : void
302 : LeaveDebuggerEventLoop();
303 :
304 : void
305 : PostMessageToDebugger(const nsAString& aMessage);
306 :
307 : void
308 : SetDebuggerImmediate(Function& aHandler, ErrorResult& aRv);
309 :
310 : void
311 : ReportErrorToDebugger(const nsAString& aFilename, uint32_t aLineno,
312 : const nsAString& aMessage);
313 :
314 : bool
315 : NotifyInternal(WorkerStatus aStatus);
316 :
317 : void
318 : ReportError(JSContext* aCx, JS::ConstUTF8CharsZ aToStringResult,
319 : JSErrorReport* aReport);
320 :
321 : static void
322 : ReportErrorToConsole(const char* aMessage);
323 :
324 : int32_t
325 : SetTimeout(JSContext* aCx, nsIScriptTimeoutHandler* aHandler,
326 : int32_t aTimeout, bool aIsInterval,
327 : ErrorResult& aRv);
328 :
329 : void
330 : ClearTimeout(int32_t aId);
331 :
332 : bool
333 : RunExpiredTimeouts(JSContext* aCx);
334 :
335 : bool
336 : RescheduleTimeoutTimer(JSContext* aCx);
337 :
338 : void
339 : UpdateContextOptionsInternal(JSContext* aCx, const JS::ContextOptions& aContextOptions);
340 :
341 : void
342 : UpdateLanguagesInternal(const nsTArray<nsString>& aLanguages);
343 :
344 : void
345 : UpdateJSWorkerMemoryParameterInternal(JSContext* aCx, JSGCParamKey key, uint32_t aValue);
346 :
347 : enum WorkerRanOrNot {
348 : WorkerNeverRan = 0,
349 : WorkerRan
350 : };
351 :
352 : void
353 : ScheduleDeletion(WorkerRanOrNot aRanOrNot);
354 :
355 : bool
356 : CollectRuntimeStats(JS::RuntimeStats* aRtStats, bool aAnonymize);
357 :
358 : #ifdef JS_GC_ZEAL
359 : void
360 : UpdateGCZealInternal(JSContext* aCx, uint8_t aGCZeal, uint32_t aFrequency);
361 : #endif
362 :
363 : void
364 : GarbageCollectInternal(JSContext* aCx, bool aShrinking,
365 : bool aCollectChildren);
366 :
367 : void
368 : CycleCollectInternal(bool aCollectChildren);
369 :
370 : void
371 : OfflineStatusChangeEventInternal(bool aIsOffline);
372 :
373 : void
374 : MemoryPressureInternal();
375 :
376 : void
377 : SetFetchHandlerWasAdded()
378 : {
379 : MOZ_ASSERT(IsServiceWorker());
380 : AssertIsOnWorkerThread();
381 : mFetchHandlerWasAdded = true;
382 : }
383 :
384 : bool
385 : FetchHandlerWasAdded() const
386 : {
387 : MOZ_ASSERT(IsServiceWorker());
388 : AssertIsOnWorkerThread();
389 : return mFetchHandlerWasAdded;
390 : }
391 :
392 : JSContext*
393 : GetJSContext() const
394 : {
395 2 : AssertIsOnWorkerThread();
396 2 : return mJSContext;
397 : }
398 :
399 : WorkerGlobalScope*
400 : GlobalScope() const
401 : {
402 2 : AssertIsOnWorkerThread();
403 2 : return mScope;
404 : }
405 :
406 : WorkerDebuggerGlobalScope*
407 : DebuggerGlobalScope() const
408 : {
409 0 : AssertIsOnWorkerThread();
410 0 : return mDebuggerScope;
411 : }
412 :
413 : void
414 : SetThread(WorkerThread* aThread);
415 :
416 : bool
417 : IsOnWorkerThread() const;
418 :
419 : void
420 : AssertIsOnWorkerThread() const
421 : #ifdef DEBUG
422 : ;
423 : #else
424 : { }
425 : #endif
426 :
427 : // This may block!
428 : void
429 : BeginCTypesCall();
430 :
431 : // This may block!
432 : void
433 : EndCTypesCall();
434 :
435 : void
436 : BeginCTypesCallback()
437 : {
438 : // If a callback is beginning then we need to do the exact same thing as
439 : // when a ctypes call ends.
440 0 : EndCTypesCall();
441 : }
442 :
443 : void
444 : EndCTypesCallback()
445 : {
446 : // If a callback is ending then we need to do the exact same thing as
447 : // when a ctypes call begins.
448 0 : BeginCTypesCall();
449 : }
450 :
451 : bool
452 : ConnectMessagePort(JSContext* aCx, MessagePortIdentifier& aIdentifier);
453 :
454 : WorkerGlobalScope*
455 : GetOrCreateGlobalScope(JSContext* aCx);
456 :
457 : WorkerDebuggerGlobalScope*
458 : CreateDebuggerGlobalScope(JSContext* aCx);
459 :
460 : bool
461 : RegisterBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
462 :
463 : bool
464 : RegisterDebuggerBindings(JSContext* aCx, JS::Handle<JSObject*> aGlobal);
465 :
466 : bool
467 : OnLine() const
468 : {
469 : AssertIsOnWorkerThread();
470 : return mOnLine;
471 : }
472 :
473 : void
474 : StopSyncLoop(nsIEventTarget* aSyncLoopTarget, bool aResult);
475 :
476 : bool
477 : AllPendingRunnablesShouldBeCanceled() const
478 : {
479 : return mCancelAllPendingRunnables;
480 : }
481 :
482 : void
483 : ClearMainEventQueue(WorkerRanOrNot aRanOrNot);
484 :
485 : void
486 : ClearDebuggerEventQueue();
487 :
488 : void
489 : OnProcessNextEvent();
490 :
491 : void
492 : AfterProcessNextEvent();
493 :
494 : void
495 : AssertValidSyncLoop(nsIEventTarget* aSyncLoopTarget)
496 : #ifdef DEBUG
497 : ;
498 : #else
499 : { }
500 : #endif
501 :
502 : void
503 : SetWorkerScriptExecutedSuccessfully()
504 : {
505 : AssertIsOnWorkerThread();
506 : // Should only be called once!
507 : MOZ_ASSERT(!mWorkerScriptExecutedSuccessfully);
508 : mWorkerScriptExecutedSuccessfully = true;
509 : }
510 :
511 : // Only valid after CompileScriptRunnable has finished running!
512 : bool
513 : WorkerScriptExecutedSuccessfully() const
514 : {
515 : AssertIsOnWorkerThread();
516 : return mWorkerScriptExecutedSuccessfully;
517 : }
518 :
519 : // Get the event target to use when dispatching to the main thread
520 : // from this Worker thread. This may be the main thread itself or
521 : // a ThrottledEventQueue to the main thread.
522 : nsIEventTarget*
523 : MainThreadEventTarget();
524 :
525 : nsresult
526 : DispatchToMainThread(nsIRunnable* aRunnable,
527 : uint32_t aFlags = NS_DISPATCH_NORMAL);
528 :
529 : nsresult
530 : DispatchToMainThread(already_AddRefed<nsIRunnable> aRunnable,
531 : uint32_t aFlags = NS_DISPATCH_NORMAL);
532 :
533 : // Get an event target that will dispatch runnables as control runnables on
534 : // the worker thread. Implement nsICancelableRunnable if you wish to take
535 : // action on cancelation.
536 : nsISerialEventTarget*
537 : ControlEventTarget();
538 :
539 : // Get an event target that will attempt to dispatch a normal WorkerRunnable,
540 : // but if that fails will then fall back to a control runnable.
541 : nsISerialEventTarget*
542 : HybridEventTarget();
543 :
544 : void
545 : DumpCrashInformation(nsACString& aString);
546 :
547 : bool
548 : EnsureClientSource();
549 :
550 : void
551 : EnsurePerformanceStorage();
552 :
553 : void
554 : EnsurePerformanceCounter();
555 :
556 : Maybe<ClientInfo>
557 : GetClientInfo() const;
558 :
559 : const ClientState
560 : GetClientState() const;
561 :
562 : const Maybe<ServiceWorkerDescriptor>
563 : GetController();
564 :
565 : void
566 : Control(const ServiceWorkerDescriptor& aServiceWorker);
567 :
568 : void
569 : ExecutionReady();
570 :
571 : PerformanceStorage*
572 : GetPerformanceStorage();
573 :
574 : PerformanceCounter*
575 : GetPerformanceCounter();
576 :
577 : bool
578 2 : IsAcceptingEvents()
579 : {
580 2 : AssertIsOnParentThread();
581 :
582 2 : MutexAutoLock lock(mMutex);
583 2 : return mParentStatus < Terminating;
584 : }
585 :
586 : WorkerStatus
587 2 : ParentStatusProtected()
588 : {
589 2 : AssertIsOnParentThread();
590 2 : MutexAutoLock lock(mMutex);
591 2 : return mParentStatus;
592 : }
593 :
594 : WorkerStatus
595 : ParentStatus() const
596 : {
597 : mMutex.AssertCurrentThreadOwns();
598 : return mParentStatus;
599 : }
600 :
601 : Worker*
602 2 : ParentEventTargetRef() const
603 : {
604 2 : MOZ_DIAGNOSTIC_ASSERT(mParentEventTargetRef);
605 2 : return mParentEventTargetRef;
606 : }
607 :
608 : void
609 6 : SetParentEventTargetRef(Worker* aParentEventTargetRef)
610 : {
611 6 : MOZ_DIAGNOSTIC_ASSERT(aParentEventTargetRef);
612 12 : MOZ_DIAGNOSTIC_ASSERT(!mParentEventTargetRef);
613 12 : mParentEventTargetRef = aParentEventTargetRef;
614 6 : }
615 :
616 : bool
617 : ModifyBusyCount(bool aIncrease);
618 :
619 : // This method is used by RuntimeService to know what is going wrong the
620 : // shutting down.
621 : uint32_t
622 : BusyCount()
623 : {
624 0 : return mBusyCount;
625 : }
626 :
627 : // Check whether this worker is a secure context. For use from the parent
628 : // thread only; the canonical "is secure context" boolean is stored on the
629 : // compartment of the worker global. The only reason we don't
630 : // AssertIsOnParentThread() here is so we can assert that this value matches
631 : // the one on the compartment, which has to be done from the worker thread.
632 : bool IsSecureContext() const
633 : {
634 : return mIsSecureContext;
635 : }
636 :
637 : // Check whether we're running in automation.
638 : bool IsInAutomation() const
639 : {
640 : return mIsInAutomation;
641 : }
642 :
643 : TimeStamp CreationTimeStamp() const
644 : {
645 : return mCreationTimeStamp;
646 : }
647 :
648 : DOMHighResTimeStamp CreationTime() const
649 : {
650 : return mCreationTimeHighRes;
651 : }
652 :
653 : DOMHighResTimeStamp TimeStampToDOMHighRes(const TimeStamp& aTimeStamp) const
654 : {
655 : MOZ_ASSERT(!aTimeStamp.IsNull());
656 : TimeDuration duration = aTimeStamp - mCreationTimeStamp;
657 : return duration.ToMilliseconds();
658 : }
659 :
660 : LocationInfo&
661 : GetLocationInfo()
662 : {
663 : return mLocationInfo;
664 : }
665 :
666 : void
667 2 : CopyJSSettings(workerinternals::JSSettings& aSettings)
668 : {
669 2 : mozilla::MutexAutoLock lock(mMutex);
670 2 : aSettings = mJSSettings;
671 2 : }
672 :
673 : void
674 : CopyJSRealmOptions(JS::RealmOptions& aOptions)
675 : {
676 : mozilla::MutexAutoLock lock(mMutex);
677 : aOptions = IsChromeWorker() ? mJSSettings.chrome.realmOptions
678 : : mJSSettings.content.realmOptions;
679 : }
680 :
681 : // The ability to be a chrome worker is orthogonal to the type of
682 : // worker [Dedicated|Shared|Service].
683 : bool
684 : IsChromeWorker() const
685 : {
686 : return mIsChromeWorker;
687 : }
688 :
689 : WorkerPrivate*
690 : GetParent() const
691 : {
692 : return mParent;
693 : }
694 :
695 : bool
696 : IsFrozen() const
697 : {
698 2 : AssertIsOnParentThread();
699 2 : return mParentFrozen;
700 : }
701 :
702 : bool
703 2 : IsParentWindowPaused() const
704 : {
705 2 : AssertIsOnParentThread();
706 2 : return mParentWindowPausedDepth > 0;
707 : }
708 :
709 : // When we debug a worker, we want to disconnect the window and the worker
710 : // communication. This happens calling this method.
711 : // Note: this method doesn't suspend the worker! Use Freeze/Thaw instead.
712 : void
713 : ParentWindowPaused();
714 :
715 : void
716 : ParentWindowResumed();
717 :
718 : const nsString&
719 : ScriptURL() const
720 : {
721 0 : return mScriptURL;
722 : }
723 :
724 : const nsString&
725 : WorkerName() const
726 : {
727 : return mWorkerName;
728 : }
729 :
730 : WorkerType
731 : Type() const
732 : {
733 : return mWorkerType;
734 : }
735 :
736 : bool
737 : IsDedicatedWorker() const
738 : {
739 : return mWorkerType == WorkerTypeDedicated;
740 : }
741 :
742 : bool
743 : IsSharedWorker() const
744 : {
745 : return mWorkerType == WorkerTypeShared;
746 : }
747 :
748 : bool
749 : IsServiceWorker() const
750 : {
751 : return mWorkerType == WorkerTypeService;
752 : }
753 :
754 : nsContentPolicyType
755 : ContentPolicyType() const
756 : {
757 42 : return ContentPolicyType(mWorkerType);
758 : }
759 :
760 : static nsContentPolicyType
761 2 : ContentPolicyType(WorkerType aWorkerType)
762 : {
763 2 : switch (aWorkerType) {
764 : case WorkerTypeDedicated:
765 : return nsIContentPolicy::TYPE_INTERNAL_WORKER;
766 : case WorkerTypeShared:
767 0 : return nsIContentPolicy::TYPE_INTERNAL_SHARED_WORKER;
768 : case WorkerTypeService:
769 0 : return nsIContentPolicy::TYPE_INTERNAL_SERVICE_WORKER;
770 : default:
771 0 : MOZ_ASSERT_UNREACHABLE("Invalid worker type");
772 : return nsIContentPolicy::TYPE_INVALID;
773 : }
774 : }
775 :
776 : nsIScriptContext*
777 : GetScriptContext() const
778 : {
779 : AssertIsOnMainThread();
780 : return mLoadInfo.mScriptContext;
781 : }
782 :
783 : const nsCString&
784 : Domain() const
785 : {
786 6 : return mLoadInfo.mDomain;
787 : }
788 :
789 : bool
790 : IsFromWindow() const
791 : {
792 : return mLoadInfo.mFromWindow;
793 : }
794 :
795 : nsLoadFlags
796 : GetLoadFlags() const
797 : {
798 : return mLoadInfo.mLoadFlags;
799 : }
800 :
801 : uint64_t
802 : WindowID() const
803 : {
804 : return mLoadInfo.mWindowID;
805 : }
806 :
807 : uint64_t
808 0 : ServiceWorkerID() const
809 : {
810 0 : return GetServiceWorkerDescriptor().Id();
811 : }
812 :
813 : const nsCString&
814 0 : ServiceWorkerScope() const
815 : {
816 0 : return GetServiceWorkerDescriptor().Scope();
817 : }
818 :
819 : nsIURI*
820 : GetBaseURI() const
821 : {
822 2 : AssertIsOnMainThread();
823 2 : return mLoadInfo.mBaseURI;
824 : }
825 :
826 : void
827 : SetBaseURI(nsIURI* aBaseURI);
828 :
829 : nsIURI*
830 : GetResolvedScriptURI() const
831 : {
832 0 : AssertIsOnMainThread();
833 0 : return mLoadInfo.mResolvedScriptURI;
834 : }
835 :
836 : const nsString&
837 0 : ServiceWorkerCacheName() const
838 : {
839 0 : MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
840 0 : AssertIsOnMainThread();
841 0 : return mLoadInfo.mServiceWorkerCacheName;
842 : }
843 :
844 : const ServiceWorkerDescriptor&
845 0 : GetServiceWorkerDescriptor() const
846 : {
847 0 : MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
848 0 : MOZ_DIAGNOSTIC_ASSERT(mLoadInfo.mServiceWorkerDescriptor.isSome());
849 0 : return mLoadInfo.mServiceWorkerDescriptor.ref();
850 : }
851 :
852 : const ServiceWorkerRegistrationDescriptor&
853 : GetServiceWorkerRegistrationDescriptor() const
854 : {
855 : MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
856 : MOZ_DIAGNOSTIC_ASSERT(mLoadInfo.mServiceWorkerRegistrationDescriptor.isSome());
857 : return mLoadInfo.mServiceWorkerRegistrationDescriptor.ref();
858 : }
859 :
860 : void
861 : UpdateServiceWorkerState(ServiceWorkerState aState)
862 : {
863 : MOZ_DIAGNOSTIC_ASSERT(IsServiceWorker());
864 : MOZ_DIAGNOSTIC_ASSERT(mLoadInfo.mServiceWorkerDescriptor.isSome());
865 : return mLoadInfo.mServiceWorkerDescriptor.ref().SetState(aState);
866 : }
867 :
868 : const Maybe<ServiceWorkerDescriptor>&
869 : GetParentController() const
870 : {
871 0 : return mLoadInfo.mParentController;
872 : }
873 :
874 : const ChannelInfo&
875 : GetChannelInfo() const
876 : {
877 : return mLoadInfo.mChannelInfo;
878 : }
879 :
880 : void
881 : SetChannelInfo(const ChannelInfo& aChannelInfo)
882 : {
883 : AssertIsOnMainThread();
884 : MOZ_ASSERT(!mLoadInfo.mChannelInfo.IsInitialized());
885 : MOZ_ASSERT(aChannelInfo.IsInitialized());
886 : mLoadInfo.mChannelInfo = aChannelInfo;
887 : }
888 :
889 : void
890 : InitChannelInfo(nsIChannel* aChannel)
891 : {
892 6 : mLoadInfo.mChannelInfo.InitFromChannel(aChannel);
893 : }
894 :
895 : void
896 : InitChannelInfo(const ChannelInfo& aChannelInfo)
897 : {
898 0 : mLoadInfo.mChannelInfo = aChannelInfo;
899 : }
900 :
901 : nsIPrincipal*
902 : GetPrincipal() const
903 : {
904 2 : AssertIsOnMainThread();
905 2 : return mLoadInfo.mPrincipal;
906 : }
907 :
908 : nsIPrincipal*
909 : GetLoadingPrincipal() const
910 : {
911 6 : AssertIsOnMainThread();
912 12 : return mLoadInfo.mLoadingPrincipal;
913 : }
914 :
915 : const nsAString& Origin() const
916 : {
917 : return mLoadInfo.mOrigin;
918 : }
919 :
920 : nsILoadGroup*
921 : GetLoadGroup() const
922 : {
923 2 : AssertIsOnMainThread();
924 2 : return mLoadInfo.mLoadGroup;
925 : }
926 :
927 : // This method allows the principal to be retrieved off the main thread.
928 : // Principals are main-thread objects so the caller must ensure that all
929 : // access occurs on the main thread.
930 : nsIPrincipal*
931 : GetPrincipalDontAssertMainThread() const
932 : {
933 0 : return mLoadInfo.mPrincipal;
934 : }
935 :
936 : bool
937 : UsesSystemPrincipal() const
938 : {
939 : return mLoadInfo.mPrincipalIsSystem;
940 : }
941 :
942 : const mozilla::ipc::PrincipalInfo&
943 : GetPrincipalInfo() const
944 : {
945 : return *mLoadInfo.mPrincipalInfo;
946 : }
947 :
948 : already_AddRefed<nsIChannel>
949 6 : ForgetWorkerChannel()
950 : {
951 6 : AssertIsOnMainThread();
952 6 : return mLoadInfo.mChannel.forget();
953 : }
954 :
955 : nsPIDOMWindowInner*
956 : GetWindow()
957 : {
958 2 : AssertIsOnMainThread();
959 2 : return mLoadInfo.mWindow;
960 : }
961 :
962 : nsIContentSecurityPolicy*
963 : GetCSP() const
964 : {
965 6 : AssertIsOnMainThread();
966 12 : return mLoadInfo.mCSP;
967 : }
968 :
969 : void
970 : SetCSP(nsIContentSecurityPolicy* aCSP);
971 :
972 : nsresult
973 : SetCSPFromHeaderValues(const nsACString& aCSPHeaderValue,
974 : const nsACString& aCSPReportOnlyHeaderValue);
975 :
976 : void
977 : SetReferrerPolicyFromHeaderValue(const nsACString& aReferrerPolicyHeaderValue);
978 :
979 : net::ReferrerPolicy
980 : GetReferrerPolicy() const
981 : {
982 : return mLoadInfo.mReferrerPolicy;
983 : }
984 :
985 : void
986 : SetReferrerPolicy(net::ReferrerPolicy aReferrerPolicy)
987 : {
988 : mLoadInfo.mReferrerPolicy = aReferrerPolicy;
989 : }
990 :
991 : bool
992 : IsEvalAllowed() const
993 : {
994 : return mLoadInfo.mEvalAllowed;
995 : }
996 :
997 : void
998 : SetEvalAllowed(bool aEvalAllowed)
999 : {
1000 0 : mLoadInfo.mEvalAllowed = aEvalAllowed;
1001 : }
1002 :
1003 : bool
1004 : GetReportCSPViolations() const
1005 : {
1006 : return mLoadInfo.mReportCSPViolations;
1007 : }
1008 :
1009 : void
1010 : SetReportCSPViolations(bool aReport)
1011 : {
1012 : mLoadInfo.mReportCSPViolations = aReport;
1013 : }
1014 :
1015 : bool
1016 : XHRParamsAllowed() const
1017 : {
1018 : return mLoadInfo.mXHRParamsAllowed;
1019 : }
1020 :
1021 : void
1022 : SetXHRParamsAllowed(bool aAllowed)
1023 : {
1024 0 : mLoadInfo.mXHRParamsAllowed = aAllowed;
1025 : }
1026 :
1027 : bool
1028 : IsStorageAllowed() const
1029 : {
1030 : return mLoadInfo.mStorageAllowed;
1031 : }
1032 :
1033 : const OriginAttributes&
1034 : GetOriginAttributes() const
1035 : {
1036 : return mLoadInfo.mOriginAttributes;
1037 : }
1038 :
1039 : // Determine if the SW testing per-window flag is set by devtools
1040 : bool
1041 : ServiceWorkersTestingInWindow() const
1042 : {
1043 : return mLoadInfo.mServiceWorkersTestingInWindow;
1044 : }
1045 :
1046 : // Determine if the worker is currently loading its top level script.
1047 : bool
1048 : IsLoadingWorkerScript() const
1049 : {
1050 : return mLoadingWorkerScript;
1051 : }
1052 :
1053 : // Called by ScriptLoader to track when this worker is loading its
1054 : // top level script.
1055 : void
1056 : SetLoadingWorkerScript(bool aLoadingWorkerScript)
1057 : {
1058 : // any thread
1059 20 : mLoadingWorkerScript = aLoadingWorkerScript;
1060 : }
1061 :
1062 : void
1063 0 : QueueRunnable(nsIRunnable* aRunnable)
1064 : {
1065 0 : AssertIsOnParentThread();
1066 0 : mQueuedRunnables.AppendElement(aRunnable);
1067 0 : }
1068 :
1069 : bool
1070 : RegisterSharedWorker(SharedWorker* aSharedWorker, MessagePort* aPort);
1071 :
1072 : void
1073 : BroadcastErrorToSharedWorkers(JSContext* aCx,
1074 : const WorkerErrorReport* aReport,
1075 : bool aIsErrorEvent);
1076 :
1077 : void
1078 : GetAllSharedWorkers(nsTArray<RefPtr<SharedWorker>>& aSharedWorkers);
1079 :
1080 : void
1081 : CloseSharedWorkersForWindow(nsPIDOMWindowInner* aWindow);
1082 :
1083 : void
1084 : CloseAllSharedWorkers();
1085 :
1086 : void
1087 : FlushReportsToSharedWorkers(nsIConsoleReportCollector* aReporter);
1088 :
1089 : // We can assume that an nsPIDOMWindow will be available for Freeze, Thaw
1090 : // as these are only used for globals going in and out of the bfcache.
1091 : //
1092 : // XXXbz: This is a bald-faced lie given the uses in RegisterSharedWorker and
1093 : // CloseSharedWorkersForWindow, which pass null for aWindow to Thaw and Freeze
1094 : // respectively. See bug 1251722.
1095 : bool
1096 : Freeze(nsPIDOMWindowInner* aWindow);
1097 :
1098 : bool
1099 : Thaw(nsPIDOMWindowInner* aWindow);
1100 :
1101 : void
1102 : EnableDebugger();
1103 :
1104 : void
1105 : DisableDebugger();
1106 :
1107 : already_AddRefed<WorkerRunnable>
1108 : MaybeWrapAsWorkerRunnable(already_AddRefed<nsIRunnable> aRunnable);
1109 :
1110 : bool
1111 : ProxyReleaseMainThreadObjects();
1112 :
1113 : void
1114 : GarbageCollect(bool aShrinking);
1115 :
1116 : void
1117 : CycleCollect(bool aDummy);
1118 :
1119 : nsresult
1120 : SetPrincipalOnMainThread(nsIPrincipal* aPrincipal, nsILoadGroup* aLoadGroup);
1121 :
1122 : nsresult
1123 : SetPrincipalFromChannel(nsIChannel* aChannel);
1124 :
1125 : bool
1126 : FinalChannelPrincipalIsValid(nsIChannel* aChannel);
1127 :
1128 : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
1129 : bool
1130 : PrincipalURIMatchesScriptURL();
1131 : #endif
1132 :
1133 : void
1134 : UpdateOverridenLoadGroup(nsILoadGroup* aBaseLoadGroup);
1135 :
1136 : void
1137 : WorkerScriptLoaded();
1138 :
1139 : nsIDocument* GetDocument() const;
1140 :
1141 : void
1142 : MemoryPressure(bool aDummy);
1143 :
1144 : void
1145 : UpdateContextOptions(const JS::ContextOptions& aContextOptions);
1146 :
1147 : void
1148 : UpdateLanguages(const nsTArray<nsString>& aLanguages);
1149 :
1150 : void
1151 : UpdateJSWorkerMemoryParameter(JSGCParamKey key, uint32_t value);
1152 :
1153 : #ifdef JS_GC_ZEAL
1154 : void
1155 : UpdateGCZeal(uint8_t aGCZeal, uint32_t aFrequency);
1156 : #endif
1157 :
1158 : void
1159 : OfflineStatusChangeEvent(bool aIsOffline);
1160 :
1161 : nsresult
1162 : Dispatch(already_AddRefed<WorkerRunnable> aRunnable,
1163 : nsIEventTarget* aSyncLoopTarget = nullptr);
1164 :
1165 : nsresult
1166 : DispatchControlRunnable(already_AddRefed<WorkerControlRunnable> aWorkerControlRunnable);
1167 :
1168 : nsresult
1169 : DispatchDebuggerRunnable(already_AddRefed<WorkerRunnable> aDebuggerRunnable);
1170 :
1171 : #ifdef DEBUG
1172 : void
1173 : AssertIsOnParentThread() const;
1174 :
1175 : void
1176 : AssertInnerWindowIsCorrect() const;
1177 : #else
1178 : void
1179 : AssertIsOnParentThread() const
1180 : { }
1181 :
1182 : void
1183 : AssertInnerWindowIsCorrect() const
1184 : { }
1185 : #endif
1186 :
1187 : #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
1188 : bool
1189 : PrincipalIsValid() const;
1190 : #endif
1191 :
1192 : void
1193 : StartCancelingTimer();
1194 :
1195 : private:
1196 : WorkerPrivate(WorkerPrivate* aParent,
1197 : const nsAString& aScriptURL, bool aIsChromeWorker,
1198 : WorkerType aWorkerType, const nsAString& aWorkerName,
1199 : const nsACString& aServiceWorkerScope,
1200 : WorkerLoadInfo& aLoadInfo);
1201 :
1202 : ~WorkerPrivate();
1203 :
1204 : bool
1205 : MayContinueRunning()
1206 : {
1207 : AssertIsOnWorkerThread();
1208 :
1209 : WorkerStatus status;
1210 : {
1211 : MutexAutoLock lock(mMutex);
1212 : status = mStatus;
1213 : }
1214 :
1215 : if (status < Terminating) {
1216 : return true;
1217 : }
1218 :
1219 : return false;
1220 : }
1221 :
1222 : void
1223 : CancelAllTimeouts();
1224 :
1225 : enum class ProcessAllControlRunnablesResult
1226 : {
1227 : // We did not process anything.
1228 : Nothing,
1229 : // We did process something, states may have changed, but we can keep
1230 : // executing script.
1231 : MayContinue,
1232 : // We did process something, and should not continue executing script.
1233 : Abort
1234 : };
1235 :
1236 : ProcessAllControlRunnablesResult
1237 : ProcessAllControlRunnables()
1238 : {
1239 : MutexAutoLock lock(mMutex);
1240 : return ProcessAllControlRunnablesLocked();
1241 : }
1242 :
1243 : ProcessAllControlRunnablesResult
1244 : ProcessAllControlRunnablesLocked();
1245 :
1246 : void
1247 : EnableMemoryReporter();
1248 :
1249 : void
1250 : DisableMemoryReporter();
1251 :
1252 : void
1253 : WaitForWorkerEvents();
1254 :
1255 : // If the worker shutdown status is equal or greater then aFailStatus, this
1256 : // operation will fail and nullptr will be returned. See WorkerHolder.h for
1257 : // more information about the correct value to use.
1258 : already_AddRefed<nsIEventTarget>
1259 : CreateNewSyncLoop(WorkerStatus aFailStatus);
1260 :
1261 : bool
1262 : RunCurrentSyncLoop();
1263 :
1264 : bool
1265 : DestroySyncLoop(uint32_t aLoopIndex);
1266 :
1267 : void
1268 : InitializeGCTimers();
1269 :
1270 : enum GCTimerMode
1271 : {
1272 : PeriodicTimer = 0,
1273 : IdleTimer,
1274 : NoTimer
1275 : };
1276 :
1277 : void
1278 : SetGCTimerMode(GCTimerMode aMode);
1279 :
1280 : void
1281 : ShutdownGCTimers();
1282 :
1283 : bool
1284 : AddHolder(WorkerHolder* aHolder, WorkerStatus aFailStatus);
1285 :
1286 : void
1287 : RemoveHolder(WorkerHolder* aHolder);
1288 :
1289 : void
1290 : NotifyHolders(WorkerStatus aStatus);
1291 :
1292 : bool
1293 : HasActiveHolders()
1294 : {
1295 : return !(mChildWorkers.IsEmpty() && mTimeouts.IsEmpty() &&
1296 : mHolders.IsEmpty());
1297 : }
1298 :
1299 : class EventTarget;
1300 : friend class EventTarget;
1301 : friend class mozilla::dom::WorkerHolder;
1302 : friend class AutoSyncLoopHolder;
1303 :
1304 : struct TimeoutInfo;
1305 :
1306 : class MemoryReporter;
1307 : friend class MemoryReporter;
1308 :
1309 : friend class mozilla::dom::WorkerThread;
1310 :
1311 : SharedMutex mMutex;
1312 : mozilla::CondVar mCondVar;
1313 :
1314 : WorkerPrivate* mParent;
1315 :
1316 : nsString mScriptURL;
1317 :
1318 : // This is the worker name for shared workers and dedicated workers.
1319 : nsString mWorkerName;
1320 :
1321 : WorkerType mWorkerType;
1322 :
1323 : // The worker is owned by its thread, which is represented here. This is set
1324 : // in Constructor() and emptied by WorkerFinishedRunnable, and conditionally
1325 : // traversed by the cycle collector if the busy count is zero.
1326 : //
1327 : // There are 4 ways a worker can be terminated:
1328 : // 1. GC/CC - When the worker is in idle state (busycount == 0), it allows to
1329 : // traverse the 'hidden' mParentEventTargetRef pointer. This is the exposed
1330 : // Worker webidl object. Doing this, CC will be able to detect a cycle and
1331 : // Unlink is called. In Unlink, Worker calls Terminate().
1332 : // 2. Worker::Terminate() is called - the shutdown procedure starts
1333 : // immediately.
1334 : // 3. WorkerScope::Close() is called - Similar to point 2.
1335 : // 4. xpcom-shutdown notification - We call Kill().
1336 : RefPtr<Worker> mParentEventTargetRef;
1337 : RefPtr<WorkerPrivate> mSelfRef;
1338 :
1339 : // The lifetime of these objects within LoadInfo is managed explicitly;
1340 : // they do not need to be cycle collected.
1341 : WorkerLoadInfo mLoadInfo;
1342 : LocationInfo mLocationInfo;
1343 :
1344 : // Protected by mMutex.
1345 : workerinternals::JSSettings mJSSettings;
1346 :
1347 : WorkerDebugger* mDebugger;
1348 :
1349 : workerinternals::Queue<WorkerControlRunnable*, 4> mControlQueue;
1350 : workerinternals::Queue<WorkerRunnable*, 4> mDebuggerQueue;
1351 :
1352 : // Touched on multiple threads, protected with mMutex.
1353 : JSContext* mJSContext;
1354 : RefPtr<WorkerThread> mThread;
1355 : PRThread* mPRThread;
1356 :
1357 : // Things touched on worker thread only.
1358 : RefPtr<WorkerGlobalScope> mScope;
1359 : RefPtr<WorkerDebuggerGlobalScope> mDebuggerScope;
1360 : nsTArray<WorkerPrivate*> mChildWorkers;
1361 : nsTObserverArray<WorkerHolder*> mHolders;
1362 : nsTArray<nsAutoPtr<TimeoutInfo>> mTimeouts;
1363 : RefPtr<ThrottledEventQueue> mMainThreadThrottledEventQueue;
1364 : nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
1365 : RefPtr<WorkerEventTarget> mWorkerControlEventTarget;
1366 : RefPtr<WorkerEventTarget> mWorkerHybridEventTarget;
1367 :
1368 : struct SyncLoopInfo
1369 : {
1370 : explicit SyncLoopInfo(EventTarget* aEventTarget);
1371 :
1372 : RefPtr<EventTarget> mEventTarget;
1373 : bool mCompleted;
1374 : bool mResult;
1375 : #ifdef DEBUG
1376 : bool mHasRun;
1377 : #endif
1378 : };
1379 :
1380 : // This is only modified on the worker thread, but in DEBUG builds
1381 : // AssertValidSyncLoop function iterates it on other threads. Therefore
1382 : // modifications are done with mMutex held *only* in DEBUG builds.
1383 : nsTArray<nsAutoPtr<SyncLoopInfo>> mSyncLoopStack;
1384 :
1385 : nsCOMPtr<nsITimer> mTimer;
1386 : nsCOMPtr<nsITimerCallback> mTimerRunnable;
1387 :
1388 : nsCOMPtr<nsITimer> mCancelingTimer;
1389 :
1390 : nsCOMPtr<nsITimer> mGCTimer;
1391 :
1392 : RefPtr<MemoryReporter> mMemoryReporter;
1393 :
1394 : // fired on the main thread if the worker script fails to load
1395 : nsCOMPtr<nsIRunnable> mLoadFailedRunnable;
1396 :
1397 : RefPtr<PerformanceStorage> mPerformanceStorage;
1398 :
1399 : // Only used for top level workers.
1400 : nsTArray<nsCOMPtr<nsIRunnable>> mQueuedRunnables;
1401 :
1402 : // Protected by mMutex.
1403 : nsTArray<RefPtr<WorkerRunnable>> mPreStartRunnables;
1404 :
1405 : // Only touched on the parent thread (currently this is always the main
1406 : // thread as SharedWorkers are always top-level).
1407 : nsTArray<RefPtr<SharedWorker>> mSharedWorkers;
1408 :
1409 : JS::UniqueChars mDefaultLocale; // nulled during worker JSContext init
1410 : TimeStamp mKillTime;
1411 : WorkerStatus mParentStatus;
1412 : WorkerStatus mStatus;
1413 : UniquePtr<ClientSource> mClientSource;
1414 :
1415 : // This is touched on parent thread only, but it can be read on a different
1416 : // thread before crashing because hanging.
1417 : Atomic<uint64_t> mBusyCount;
1418 :
1419 : Atomic<bool> mLoadingWorkerScript;
1420 :
1421 : TimeStamp mCreationTimeStamp;
1422 : DOMHighResTimeStamp mCreationTimeHighRes;
1423 :
1424 : // Things touched on worker thread only.
1425 : uint32_t mNumHoldersPreventingShutdownStart;
1426 : uint32_t mDebuggerEventLoopLevel;
1427 :
1428 : uint32_t mErrorHandlerRecursionCount;
1429 : uint32_t mNextTimeoutId;
1430 :
1431 : // SharedWorkers may have multiple windows paused, so this must be
1432 : // a count instead of just a boolean.
1433 : uint32_t mParentWindowPausedDepth;
1434 :
1435 : bool mFrozen;
1436 : bool mTimerRunning;
1437 : bool mRunningExpiredTimeouts;
1438 : bool mPendingEventQueueClearing;
1439 : bool mCancelAllPendingRunnables;
1440 : bool mPeriodicGCTimerRunning;
1441 : bool mIdleGCTimerRunning;
1442 : bool mWorkerScriptExecutedSuccessfully;
1443 : bool mFetchHandlerWasAdded;
1444 : bool mOnLine;
1445 : bool mMainThreadObjectsForgotten;
1446 : bool mIsChromeWorker;
1447 : bool mParentFrozen;
1448 :
1449 : // mIsSecureContext is set once in our constructor; after that it can be read
1450 : // from various threads. We could make this const if we were OK with setting
1451 : // it in the initializer list via calling some function that takes all sorts
1452 : // of state (loadinfo, worker type, parent).
1453 : //
1454 : // It's a bit unfortunate that we have to have an out-of-band boolean for
1455 : // this, but we need access to this state from the parent thread, and we can't
1456 : // use our global object's secure state there.
1457 : bool mIsSecureContext;
1458 :
1459 : bool mDebuggerRegistered;
1460 :
1461 : // mIsInAutomation is true when we're running in test automation.
1462 : // We expose some extra testing functions in that case.
1463 : bool mIsInAutomation;
1464 :
1465 : // This pointer will be null if dom.performance.enable_scheduler_timing is
1466 : // false (default value)
1467 : RefPtr<mozilla::PerformanceCounter> mPerformanceCounter;
1468 : };
1469 :
1470 : class AutoSyncLoopHolder
1471 : {
1472 : WorkerPrivate* mWorkerPrivate;
1473 : nsCOMPtr<nsIEventTarget> mTarget;
1474 : uint32_t mIndex;
1475 :
1476 : public:
1477 : // See CreateNewSyncLoop() for more information about the correct value to use
1478 : // for aFailStatus.
1479 0 : AutoSyncLoopHolder(WorkerPrivate* aWorkerPrivate, WorkerStatus aFailStatus)
1480 0 : : mWorkerPrivate(aWorkerPrivate)
1481 0 : , mTarget(aWorkerPrivate->CreateNewSyncLoop(aFailStatus))
1482 0 : , mIndex(aWorkerPrivate->mSyncLoopStack.Length() - 1)
1483 : {
1484 0 : aWorkerPrivate->AssertIsOnWorkerThread();
1485 0 : }
1486 :
1487 0 : ~AutoSyncLoopHolder()
1488 0 : {
1489 0 : if (mWorkerPrivate && mTarget) {
1490 0 : mWorkerPrivate->AssertIsOnWorkerThread();
1491 0 : mWorkerPrivate->StopSyncLoop(mTarget, false);
1492 0 : mWorkerPrivate->DestroySyncLoop(mIndex);
1493 : }
1494 0 : }
1495 :
1496 : bool
1497 0 : Run()
1498 : {
1499 0 : WorkerPrivate* workerPrivate = mWorkerPrivate;
1500 0 : mWorkerPrivate = nullptr;
1501 :
1502 0 : workerPrivate->AssertIsOnWorkerThread();
1503 :
1504 2 : return workerPrivate->RunCurrentSyncLoop();
1505 : }
1506 :
1507 : nsIEventTarget*
1508 : GetEventTarget() const
1509 : {
1510 : // This can be null if CreateNewSyncLoop() fails.
1511 2 : return mTarget;
1512 : }
1513 : };
1514 :
1515 : } // dom namespace
1516 : } // mozilla namespace
1517 :
1518 : #endif /* mozilla_dom_workers_workerprivate_h__ */
|