diff options
Diffstat (limited to 'dom/workers/WorkerPrivate.cpp')
-rw-r--r-- | dom/workers/WorkerPrivate.cpp | 267 |
1 files changed, 178 insertions, 89 deletions
diff --git a/dom/workers/WorkerPrivate.cpp b/dom/workers/WorkerPrivate.cpp index df248acda4..d9bf764312 100644 --- a/dom/workers/WorkerPrivate.cpp +++ b/dom/workers/WorkerPrivate.cpp @@ -180,19 +180,20 @@ inline UniquePtrComparator<T> GetUniquePtrComparator( // This class is used to wrap any runnables that the worker receives via the // nsIEventTarget::Dispatch() method (either from NS_DispatchToCurrentThread or // from the worker's EventTarget). -class ExternalRunnableWrapper final : public WorkerRunnable { +class ExternalRunnableWrapper final : public WorkerThreadRunnable { nsCOMPtr<nsIRunnable> mWrappedRunnable; public: ExternalRunnableWrapper(WorkerPrivate* aWorkerPrivate, nsIRunnable* aWrappedRunnable) - : WorkerRunnable(aWorkerPrivate, "ExternalRunnableWrapper", WorkerThread), + : WorkerThreadRunnable("ExternalRunnableWrapper"), mWrappedRunnable(aWrappedRunnable) { MOZ_ASSERT(aWorkerPrivate); MOZ_ASSERT(aWrappedRunnable); } - NS_INLINE_DECL_REFCOUNTING_INHERITED(ExternalRunnableWrapper, WorkerRunnable) + NS_INLINE_DECL_REFCOUNTING_INHERITED(ExternalRunnableWrapper, + WorkerThreadRunnable) private: ~ExternalRunnableWrapper() = default; @@ -249,8 +250,7 @@ class WorkerFinishedRunnable final : public WorkerControlRunnable { public: WorkerFinishedRunnable(WorkerPrivate* aWorkerPrivate, WorkerPrivate* aFinishedWorker) - : WorkerControlRunnable(aWorkerPrivate, "WorkerFinishedRunnable", - WorkerThread), + : WorkerControlRunnable("WorkerFinishedRunnable"), mFinishedWorker(aFinishedWorker) { aFinishedWorker->IncreaseWorkerFinishedRunnableCount(); } @@ -337,8 +337,7 @@ class CompileScriptRunnable final : public WorkerDebuggeeRunnable { UniquePtr<SerializedStackHolder> aOriginStack, const nsAString& aScriptURL, const mozilla::Encoding* aDocumentEncoding) - : WorkerDebuggeeRunnable(aWorkerPrivate, "CompileScriptRunnable", - WorkerThread), + : WorkerDebuggeeRunnable("CompileScriptRunnable"), mScriptURL(aScriptURL), mDocumentEncoding(aDocumentEncoding), mOriginStack(aOriginStack.release()) {} @@ -436,7 +435,7 @@ class CompileScriptRunnable final : public WorkerDebuggeeRunnable { if (!aRunResult) { aWorkerPrivate->CloseInternal(); } - WorkerRunnable::PostRun(aCx, aWorkerPrivate, aRunResult); + WorkerThreadRunnable::PostRun(aCx, aWorkerPrivate, aRunResult); } }; @@ -445,8 +444,7 @@ class NotifyRunnable final : public WorkerControlRunnable { public: NotifyRunnable(WorkerPrivate* aWorkerPrivate, WorkerStatus aStatus) - : WorkerControlRunnable(aWorkerPrivate, "NotifyRunnable", WorkerThread), - mStatus(aStatus) { + : WorkerControlRunnable("NotifyRunnable"), mStatus(aStatus) { MOZ_ASSERT(aStatus == Closing || aStatus == Canceling || aStatus == Killing); } @@ -474,7 +472,7 @@ class NotifyRunnable final : public WorkerControlRunnable { class FreezeRunnable final : public WorkerControlRunnable { public: explicit FreezeRunnable(WorkerPrivate* aWorkerPrivate) - : WorkerControlRunnable(aWorkerPrivate, "FreezeRunnable", WorkerThread) {} + : WorkerControlRunnable("FreezeRunnable") {} private: virtual bool WorkerRun(JSContext* aCx, @@ -486,7 +484,7 @@ class FreezeRunnable final : public WorkerControlRunnable { class ThawRunnable final : public WorkerControlRunnable { public: explicit ThawRunnable(WorkerPrivate* aWorkerPrivate) - : WorkerControlRunnable(aWorkerPrivate, "ThawRunnable", WorkerThread) {} + : WorkerControlRunnable("ThawRunnable") {} private: virtual bool WorkerRun(JSContext* aCx, @@ -500,9 +498,8 @@ class PropagateStorageAccessPermissionGrantedRunnable final public: explicit PropagateStorageAccessPermissionGrantedRunnable( WorkerPrivate* aWorkerPrivate) - : WorkerControlRunnable(aWorkerPrivate, - "PropagateStorageAccessPermissionGrantedRunnable", - WorkerThread) {} + : WorkerControlRunnable( + "PropagateStorageAccessPermissionGrantedRunnable") {} private: bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { @@ -511,7 +508,7 @@ class PropagateStorageAccessPermissionGrantedRunnable final } }; -class ReportErrorToConsoleRunnable final : public WorkerRunnable { +class ReportErrorToConsoleRunnable final : public WorkerParentThreadRunnable { const char* mMessage; const nsTArray<nsString> mParams; @@ -529,7 +526,7 @@ class ReportErrorToConsoleRunnable final : public WorkerRunnable { if (aWorkerPrivate) { RefPtr<ReportErrorToConsoleRunnable> runnable = new ReportErrorToConsoleRunnable(aWorkerPrivate, aMessage, aParams); - runnable->Dispatch(); + runnable->Dispatch(aWorkerPrivate); return; } @@ -543,8 +540,7 @@ class ReportErrorToConsoleRunnable final : public WorkerRunnable { ReportErrorToConsoleRunnable(WorkerPrivate* aWorkerPrivate, const char* aMessage, const nsTArray<nsString>& aParams) - : WorkerRunnable(aWorkerPrivate, "ReportErrorToConsoleRunnable", - ParentThread), + : WorkerParentThreadRunnable("ReportErrorToConsoleRunnable"), mMessage(aMessage), mParams(aParams.Clone()) {} @@ -565,14 +561,13 @@ class ReportErrorToConsoleRunnable final : public WorkerRunnable { } }; -class RunExpiredTimoutsRunnable final : public WorkerRunnable, +class RunExpiredTimoutsRunnable final : public WorkerThreadRunnable, public nsITimerCallback { public: NS_DECL_ISUPPORTS_INHERITED explicit RunExpiredTimoutsRunnable(WorkerPrivate* aWorkerPrivate) - : WorkerRunnable(aWorkerPrivate, "RunExpiredTimoutsRunnable", - WorkerThread) {} + : WorkerThreadRunnable("RunExpiredTimoutsRunnable") {} private: ~RunExpiredTimoutsRunnable() = default; @@ -599,17 +594,16 @@ class RunExpiredTimoutsRunnable final : public WorkerRunnable, Notify(nsITimer* aTimer) override { return Run(); } }; -NS_IMPL_ISUPPORTS_INHERITED(RunExpiredTimoutsRunnable, WorkerRunnable, +NS_IMPL_ISUPPORTS_INHERITED(RunExpiredTimoutsRunnable, WorkerThreadRunnable, nsITimerCallback) -class DebuggerImmediateRunnable final : public WorkerRunnable { +class DebuggerImmediateRunnable final : public WorkerThreadRunnable { RefPtr<dom::Function> mHandler; public: explicit DebuggerImmediateRunnable(WorkerPrivate* aWorkerPrivate, dom::Function& aHandler) - : WorkerRunnable(aWorkerPrivate, "DebuggerImmediateRunnable", - WorkerThread), + : WorkerThreadRunnable("DebuggerImmediateRunnable"), mHandler(&aHandler) {} private: @@ -670,8 +664,7 @@ class UpdateContextOptionsRunnable final : public WorkerControlRunnable { public: UpdateContextOptionsRunnable(WorkerPrivate* aWorkerPrivate, const JS::ContextOptions& aContextOptions) - : WorkerControlRunnable(aWorkerPrivate, "UpdateContextOptionsRunnable", - WorkerThread), + : WorkerControlRunnable("UpdateContextOptionsRunnable"), mContextOptions(aContextOptions) {} private: @@ -682,13 +675,13 @@ class UpdateContextOptionsRunnable final : public WorkerControlRunnable { } }; -class UpdateLanguagesRunnable final : public WorkerRunnable { +class UpdateLanguagesRunnable final : public WorkerThreadRunnable { nsTArray<nsString> mLanguages; public: UpdateLanguagesRunnable(WorkerPrivate* aWorkerPrivate, const nsTArray<nsString>& aLanguages) - : WorkerRunnable(aWorkerPrivate, "UpdateLanguagesRunnable"), + : WorkerThreadRunnable("UpdateLanguagesRunnable"), mLanguages(aLanguages.Clone()) {} virtual bool WorkerRun(JSContext* aCx, @@ -707,9 +700,7 @@ class UpdateJSWorkerMemoryParameterRunnable final UpdateJSWorkerMemoryParameterRunnable(WorkerPrivate* aWorkerPrivate, JSGCParamKey aKey, Maybe<uint32_t> aValue) - : WorkerControlRunnable(aWorkerPrivate, - "UpdateJSWorkerMemoryParameterRunnable", - WorkerThread), + : WorkerControlRunnable("UpdateJSWorkerMemoryParameterRunnable"), mValue(aValue), mKey(aKey) {} @@ -729,8 +720,7 @@ class UpdateGCZealRunnable final : public WorkerControlRunnable { public: UpdateGCZealRunnable(WorkerPrivate* aWorkerPrivate, uint8_t aGCZeal, uint32_t aFrequency) - : WorkerControlRunnable(aWorkerPrivate, "UpdateGCZealRunnable", - WorkerThread), + : WorkerControlRunnable("UpdateGCZealRunnable"), mGCZeal(aGCZeal), mFrequency(aFrequency) {} @@ -748,9 +738,7 @@ class SetLowMemoryStateRunnable final : public WorkerControlRunnable { public: SetLowMemoryStateRunnable(WorkerPrivate* aWorkerPrivate, bool aState) - : WorkerControlRunnable(aWorkerPrivate, "SetLowMemoryStateRunnable", - WorkerThread), - mState(aState) {} + : WorkerControlRunnable("SetLowMemoryStateRunnable"), mState(aState) {} private: virtual bool WorkerRun(JSContext* aCx, @@ -767,8 +755,7 @@ class GarbageCollectRunnable final : public WorkerControlRunnable { public: GarbageCollectRunnable(WorkerPrivate* aWorkerPrivate, bool aShrinking, bool aCollectChildren) - : WorkerControlRunnable(aWorkerPrivate, "GarbageCollectRunnable", - WorkerThread), + : WorkerControlRunnable("GarbageCollectRunnable"), mShrinking(aShrinking), mCollectChildren(aCollectChildren) {} @@ -802,8 +789,7 @@ class CycleCollectRunnable final : public WorkerControlRunnable { public: CycleCollectRunnable(WorkerPrivate* aWorkerPrivate, bool aCollectChildren) - : WorkerControlRunnable(aWorkerPrivate, "CycleCollectRunnable", - WorkerThread), + : WorkerControlRunnable("CycleCollectRunnable"), mCollectChildren(aCollectChildren) {} bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { @@ -812,10 +798,10 @@ class CycleCollectRunnable final : public WorkerControlRunnable { } }; -class OfflineStatusChangeRunnable final : public WorkerRunnable { +class OfflineStatusChangeRunnable final : public WorkerThreadRunnable { public: OfflineStatusChangeRunnable(WorkerPrivate* aWorkerPrivate, bool aIsOffline) - : WorkerRunnable(aWorkerPrivate, "OfflineStatusChangeRunnable"), + : WorkerThreadRunnable("OfflineStatusChangeRunnable"), mIsOffline(aIsOffline) {} bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { @@ -830,8 +816,7 @@ class OfflineStatusChangeRunnable final : public WorkerRunnable { class MemoryPressureRunnable final : public WorkerControlRunnable { public: explicit MemoryPressureRunnable(WorkerPrivate* aWorkerPrivate) - : WorkerControlRunnable(aWorkerPrivate, "MemoryPressureRunnable", - WorkerThread) {} + : WorkerControlRunnable("MemoryPressureRunnable") {} bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { aWorkerPrivate->MemoryPressureInternal(); @@ -859,11 +844,10 @@ PRThread* PRThreadFromThread(nsIThread* aThread) { // called. This runnable is executed on the parent process in order to cancel // the current runnable. It uses a normal WorkerDebuggeeRunnable in order to be // sure that all the pending WorkerDebuggeeRunnables are executed before this. -class CancelingOnParentRunnable final : public WorkerDebuggeeRunnable { +class CancelingOnParentRunnable final : public WorkerParentDebuggeeRunnable { public: explicit CancelingOnParentRunnable(WorkerPrivate* aWorkerPrivate) - : WorkerDebuggeeRunnable(aWorkerPrivate, "CancelingOnParentRunnable", - ParentThread) {} + : WorkerParentDebuggeeRunnable("CancelingOnParentRunnable") {} bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { aWorkerPrivate->Cancel(); @@ -873,12 +857,10 @@ class CancelingOnParentRunnable final : public WorkerDebuggeeRunnable { // A runnable to cancel the worker from the parent process. class CancelingWithTimeoutOnParentRunnable final - : public WorkerControlRunnable { + : public WorkerParentControlRunnable { public: explicit CancelingWithTimeoutOnParentRunnable(WorkerPrivate* aWorkerPrivate) - : WorkerControlRunnable(aWorkerPrivate, - "CancelingWithTimeoutOnParentRunnable", - ParentThread) {} + : WorkerParentControlRunnable("CancelingWithTimeoutOnParentRunnable") {} bool WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override { aWorkerPrivate->AssertIsOnParentThread(); @@ -926,7 +908,7 @@ class CancelingRunnable final : public Runnable { // Now we can cancel the this worker from the parent process. RefPtr<CancelingOnParentRunnable> r = new CancelingOnParentRunnable(workerPrivate); - r->Dispatch(); + r->Dispatch(workerPrivate); return NS_OK; } @@ -1252,7 +1234,7 @@ WorkerPrivate::MemoryReporter::CollectReports( aAnonymize, path); } - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(mWorkerPrivate)) { return NS_ERROR_UNEXPECTED; } @@ -1262,7 +1244,7 @@ WorkerPrivate::MemoryReporter::CollectReports( WorkerPrivate::MemoryReporter::CollectReportsRunnable::CollectReportsRunnable( WorkerPrivate* aWorkerPrivate, nsIHandleReportCallback* aHandleReport, nsISupports* aHandlerData, bool aAnonymize, const nsACString& aPath) - : MainThreadWorkerControlRunnable(aWorkerPrivate), + : MainThreadWorkerControlRunnable("CollectReportsRunnable"), mFinishCollectRunnable(new FinishCollectRunnable( aHandleReport, aHandlerData, aAnonymize, aPath)), mAnonymize(aAnonymize) {} @@ -1559,8 +1541,48 @@ void WorkerPrivate::Traverse(nsCycleCollectionTraversalCallback& aCb) { nsresult WorkerPrivate::Dispatch(already_AddRefed<WorkerRunnable> aRunnable, nsIEventTarget* aSyncLoopTarget) { // May be called on any thread! + RefPtr<WorkerRunnable> runnable(aRunnable); + + LOGV(("WorkerPrivate::Dispatch [%p] runnable %p", this, runnable.get())); + if (!aSyncLoopTarget) { + // Dispatch control runnable + if (runnable->IsControlRunnable()) { + return DispatchControlRunnable(runnable.forget()); + } + + // Dispatch debugger runnable + if (runnable->IsDebuggerRunnable()) { + return DispatchDebuggerRunnable(runnable.forget()); + } + } MutexAutoLock lock(mMutex); - return DispatchLockHeld(std::move(aRunnable), aSyncLoopTarget, lock); + return DispatchLockHeld(runnable.forget(), aSyncLoopTarget, lock); +} + +nsresult WorkerPrivate::DispatchToParent( + already_AddRefed<WorkerRunnable> aRunnable) { + RefPtr<WorkerRunnable> runnable(aRunnable); + + LOGV(("WorkerPrivate::DispatchToParent [%p] runnable %p", this, + runnable.get())); + + WorkerPrivate* parent = GetParent(); + // Dispatch to parent worker + if (parent) { + if (runnable->IsControlRunnable()) { + return parent->DispatchControlRunnable(runnable.forget()); + } + return parent->Dispatch(runnable.forget()); + } + + // Dispatch to main thread + if (runnable->IsDebuggeeRunnable()) { + RefPtr<WorkerParentDebuggeeRunnable> debuggeeRunnable = + runnable.forget().downcast<WorkerParentDebuggeeRunnable>(); + return DispatchDebuggeeToMainThread(debuggeeRunnable.forget(), + NS_DISPATCH_NORMAL); + } + return DispatchToMainThread(runnable.forget()); } nsresult WorkerPrivate::DispatchLockHeld( @@ -1573,6 +1595,7 @@ nsresult WorkerPrivate::DispatchLockHeld( MOZ_ASSERT_IF(aSyncLoopTarget, mThread); + // Dispatch normal worker runnable if (mStatus == Dead || (!aSyncLoopTarget && ParentStatus() > Canceling)) { NS_WARNING( "A runnable was posted to a worker that is already shutting " @@ -1592,7 +1615,10 @@ nsresult WorkerPrivate::DispatchLockHeld( ("WorkerPrivate::DispatchLockHeld [%p] runnable %p is queued in " "mPreStartRunnables", this, runnable.get())); - mPreStartRunnables.AppendElement(runnable); + RefPtr<WorkerThreadRunnable> workerThreadRunnable = + static_cast<WorkerThreadRunnable*>(runnable.get()); + workerThreadRunnable->mWorkerPrivateForPreStartCleaning = this; + mPreStartRunnables.AppendElement(workerThreadRunnable); return NS_OK; } @@ -1654,10 +1680,10 @@ void WorkerPrivate::DisableDebugger() { } nsresult WorkerPrivate::DispatchControlRunnable( - already_AddRefed<WorkerControlRunnable> aWorkerControlRunnable) { + already_AddRefed<WorkerRunnable> aWorkerRunnable) { // May be called on any thread! - RefPtr<WorkerControlRunnable> runnable(aWorkerControlRunnable); - MOZ_ASSERT(runnable); + RefPtr<WorkerRunnable> runnable(aWorkerRunnable); + MOZ_ASSERT_DEBUG_OR_FUZZING(runnable && runnable->IsControlRunnable()); LOG(WorkerLog(), ("WorkerPrivate::DispatchControlRunnable [%p] runnable %p", this, runnable.get())); @@ -1769,6 +1795,8 @@ bool WorkerPrivate::Notify(WorkerStatus aStatus) { mCancellationCallback = nullptr; } + mParentRef->DropWorkerPrivate(); + if (pending) { #ifdef DEBUG { @@ -1803,7 +1831,7 @@ bool WorkerPrivate::Notify(WorkerStatus aStatus) { } RefPtr<NotifyRunnable> runnable = new NotifyRunnable(this, aStatus); - return runnable->Dispatch(); + return runnable->Dispatch(this); } bool WorkerPrivate::Freeze(const nsPIDOMWindowInner* aWindow) { @@ -1841,7 +1869,7 @@ bool WorkerPrivate::Freeze(const nsPIDOMWindowInner* aWindow) { DisableDebugger(); RefPtr<FreezeRunnable> runnable = new FreezeRunnable(this); - return runnable->Dispatch(); + return runnable->Dispatch(this); } bool WorkerPrivate::Thaw(const nsPIDOMWindowInner* aWindow) { @@ -1883,7 +1911,7 @@ bool WorkerPrivate::Thaw(const nsPIDOMWindowInner* aWindow) { EnableDebugger(); RefPtr<ThawRunnable> runnable = new ThawRunnable(this); - return runnable->Dispatch(); + return runnable->Dispatch(this); } void WorkerPrivate::ParentWindowPaused() { @@ -1945,7 +1973,33 @@ void WorkerPrivate::PropagateStorageAccessPermissionGranted() { RefPtr<PropagateStorageAccessPermissionGrantedRunnable> runnable = new PropagateStorageAccessPermissionGrantedRunnable(this); - Unused << NS_WARN_IF(!runnable->Dispatch()); + Unused << NS_WARN_IF(!runnable->Dispatch(this)); +} + +void WorkerPrivate::NotifyStorageKeyUsed() { + AssertIsOnWorkerThread(); + + // Only notify once per global. + if (hasNotifiedStorageKeyUsed) { + return; + } + hasNotifiedStorageKeyUsed = true; + + // Notify about storage access on the main thread. + RefPtr<StrongWorkerRef> strongRef = + StrongWorkerRef::Create(this, "WorkerPrivate::NotifyStorageKeyUsed"); + if (!strongRef) { + return; + } + RefPtr<ThreadSafeWorkerRef> ref = new ThreadSafeWorkerRef(strongRef); + DispatchToMainThread(NS_NewRunnableFunction( + "WorkerPrivate::NotifyStorageKeyUsed", [ref = std::move(ref)] { + nsGlobalWindowInner* window = + nsGlobalWindowInner::Cast(ref->Private()->GetAncestorWindow()); + if (window) { + window->MaybeNotifyStorageKeyUsed(); + } + })); } bool WorkerPrivate::Close() { @@ -1987,7 +2041,7 @@ void WorkerPrivate::UpdateContextOptions( RefPtr<UpdateContextOptionsRunnable> runnable = new UpdateContextOptionsRunnable(this, aContextOptions); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { NS_WARNING("Failed to update worker context options!"); } } @@ -1997,7 +2051,7 @@ void WorkerPrivate::UpdateLanguages(const nsTArray<nsString>& aLanguages) { RefPtr<UpdateLanguagesRunnable> runnable = new UpdateLanguagesRunnable(this, aLanguages); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { NS_WARNING("Failed to update worker languages!"); } } @@ -2016,7 +2070,7 @@ void WorkerPrivate::UpdateJSWorkerMemoryParameter(JSGCParamKey aKey, if (changed) { RefPtr<UpdateJSWorkerMemoryParameterRunnable> runnable = new UpdateJSWorkerMemoryParameterRunnable(this, aKey, aValue); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { NS_WARNING("Failed to update memory parameter!"); } } @@ -2034,7 +2088,7 @@ void WorkerPrivate::UpdateGCZeal(uint8_t aGCZeal, uint32_t aFrequency) { RefPtr<UpdateGCZealRunnable> runnable = new UpdateGCZealRunnable(this, aGCZeal, aFrequency); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { NS_WARNING("Failed to update worker gczeal!"); } } @@ -2045,7 +2099,7 @@ void WorkerPrivate::SetLowMemoryState(bool aState) { RefPtr<SetLowMemoryStateRunnable> runnable = new SetLowMemoryStateRunnable(this, aState); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { NS_WARNING("Failed to set low memory state!"); } } @@ -2055,7 +2109,7 @@ void WorkerPrivate::GarbageCollect(bool aShrinking) { RefPtr<GarbageCollectRunnable> runnable = new GarbageCollectRunnable( this, aShrinking, /* aCollectChildren = */ true); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { NS_WARNING("Failed to GC worker!"); } } @@ -2065,7 +2119,7 @@ void WorkerPrivate::CycleCollect() { RefPtr<CycleCollectRunnable> runnable = new CycleCollectRunnable(this, /* aCollectChildren = */ true); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { NS_WARNING("Failed to CC worker!"); } } @@ -2075,7 +2129,7 @@ void WorkerPrivate::OfflineStatusChangeEvent(bool aIsOffline) { RefPtr<OfflineStatusChangeRunnable> runnable = new OfflineStatusChangeRunnable(this, aIsOffline); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { NS_WARNING("Failed to dispatch offline status change event!"); } } @@ -2118,7 +2172,7 @@ void WorkerPrivate::MemoryPressure() { AssertIsOnParentThread(); RefPtr<MemoryPressureRunnable> runnable = new MemoryPressureRunnable(this); - Unused << NS_WARN_IF(!runnable->Dispatch()); + Unused << NS_WARN_IF(!runnable->Dispatch(this)); } RefPtr<WorkerPrivate::JSMemoryUsagePromise> WorkerPrivate::GetJSMemoryUsage() { @@ -2661,6 +2715,7 @@ already_AddRefed<WorkerPrivate> WorkerPrivate::Constructor( // must keep ourself alive. We can now only be cleared by // ClearSelfAndParentEventTargetRef(). worker->mSelfRef = worker; + worker->mParentRef = MakeRefPtr<WorkerParentRef>(worker); worker->EnableDebugger(); @@ -2681,7 +2736,7 @@ already_AddRefed<WorkerPrivate> WorkerPrivate::Constructor( RefPtr<CompileScriptRunnable> compiler = new CompileScriptRunnable( worker, std::move(stack), aScriptURL, aDocumentEncoding); - if (!compiler->Dispatch()) { + if (!compiler->Dispatch(worker)) { aRv.Throw(NS_ERROR_UNEXPECTED); return nullptr; } @@ -3134,7 +3189,7 @@ void WorkerPrivate::RunLoopNeverRan() { // After mStatus is set to Dead there can be no more // WorkerControlRunnables so no need to lock here. if (!mControlQueue.IsEmpty()) { - WorkerControlRunnable* runnable = nullptr; + WorkerRunnable* runnable = nullptr; while (mControlQueue.Pop(runnable)) { runnable->Cancel(); runnable->Release(); @@ -3146,8 +3201,6 @@ void WorkerPrivate::RunLoopNeverRan() { // PerformanceStorageWorker which holds a WeakWorkerRef. // Notify WeakWorkerRefs with Dead status. NotifyWorkerRefs(Dead); - - ScheduleDeletion(WorkerPrivate::WorkerRan); } void WorkerPrivate::UnrootGlobalScopes() { @@ -3355,7 +3408,7 @@ void WorkerPrivate::DoRunLoop(JSContext* aCx) { ("WorkerPrivate::DoRunLoop [%p] dropping control runnables in " "Dead status", this)); - WorkerControlRunnable* runnable = nullptr; + WorkerRunnable* runnable = nullptr; while (mControlQueue.Pop(runnable)) { runnable->Cancel(); runnable->Release(); @@ -3530,8 +3583,11 @@ nsresult WorkerPrivate::DispatchToMainThread( } nsresult WorkerPrivate::DispatchDebuggeeToMainThread( - already_AddRefed<WorkerDebuggeeRunnable> aRunnable, uint32_t aFlags) { - return mMainThreadDebuggeeEventTarget->Dispatch(std::move(aRunnable), aFlags); + already_AddRefed<WorkerRunnable> aRunnable, uint32_t aFlags) { + RefPtr<WorkerRunnable> debuggeeRunnable = std::move(aRunnable); + MOZ_ASSERT_DEBUG_OR_FUZZING(debuggeeRunnable->IsDebuggeeRunnable()); + return mMainThreadDebuggeeEventTarget->Dispatch(debuggeeRunnable.forget(), + aFlags); } nsISerialEventTarget* WorkerPrivate::ControlEventTarget() { @@ -3915,7 +3971,7 @@ void WorkerPrivate::ScheduleDeletion(WorkerRanOrNot aRanOrNot) { if (WorkerPrivate* parent = GetParent()) { RefPtr<WorkerFinishedRunnable> runnable = new WorkerFinishedRunnable(parent, this); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(parent)) { NS_WARNING("Failed to dispatch runnable!"); } } else { @@ -4028,7 +4084,7 @@ WorkerPrivate::ProcessAllControlRunnablesLocked() { auto result = ProcessAllControlRunnablesResult::Nothing; for (;;) { - WorkerControlRunnable* event; + WorkerRunnable* event; if (!mControlQueue.Pop(event)) { break; } @@ -4327,6 +4383,11 @@ void WorkerPrivate::RunShutdownTasks() { mWorkerHybridEventTarget->ForgetWorkerPrivate(this); } +RefPtr<WorkerParentRef> WorkerPrivate::GetWorkerParentRef() const { + RefPtr<WorkerParentRef> ref(mParentRef); + return ref; +} + void WorkerPrivate::AdjustNonblockingCCBackgroundActorCount(int32_t aCount) { AssertIsOnWorkerThread(); auto data = mWorkerThreadAccessible.Access(); @@ -4704,7 +4765,7 @@ void WorkerPrivate::DispatchCancelingRunnable() { this)); RefPtr<CancelingWithTimeoutOnParentRunnable> rr = new CancelingWithTimeoutOnParentRunnable(this); - rr->Dispatch(); + rr->Dispatch(this); } void WorkerPrivate::ReportUseCounters() { @@ -4848,8 +4909,8 @@ void WorkerPrivate::PostMessageToParent( return; } - RefPtr<MessageEventRunnable> runnable = - new MessageEventRunnable(this, WorkerRunnable::ParentThread); + RefPtr<MessageEventToParentRunnable> runnable = + new MessageEventToParentRunnable(this); JS::CloneDataPolicy clonePolicy; @@ -4866,7 +4927,7 @@ void WorkerPrivate::PostMessageToParent( return; } - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { aRv = NS_ERROR_FAILURE; } } @@ -4966,7 +5027,7 @@ void WorkerPrivate::SetDebuggerImmediate(dom::Function& aHandler, RefPtr<DebuggerImmediateRunnable> runnable = new DebuggerImmediateRunnable(this, aHandler); - if (!runnable->Dispatch()) { + if (!runnable->Dispatch(this)) { aRv.Throw(NS_ERROR_FAILURE); } } @@ -5711,10 +5772,11 @@ void WorkerPrivate::ResetWorkerPrivateInWorkerThread() { // Release the mutex before doomedThread. MutexAutoLock lock(mMutex); + MOZ_ASSERT(mStatus == Dead); MOZ_ASSERT(mThread); - mThread->SetWorker(WorkerThreadFriendKey{}, nullptr); + mThread->ClearEventQueueAndWorker(WorkerThreadFriendKey{}); mThread.swap(doomedThread); } @@ -6229,5 +6291,32 @@ WorkerPrivate::AutoPushEventLoopGlobal::~AutoPushEventLoopGlobal() { data->mCurrentEventLoopGlobal = std::move(mOldEventLoopGlobal); } +// ----------------------------------------------------------------------------- +// WorkerParentRef +WorkerParentRef::WorkerParentRef(RefPtr<WorkerPrivate>& aWorkerPrivate) + : mWorkerPrivate(aWorkerPrivate) { + LOGV(("WorkerParentRef::WorkerParentRef [%p] aWorkerPrivate %p", this, + aWorkerPrivate.get())); + MOZ_ASSERT(mWorkerPrivate); + mWorkerPrivate->AssertIsOnParentThread(); +} + +const RefPtr<WorkerPrivate>& WorkerParentRef::Private() const { + if (mWorkerPrivate) { + mWorkerPrivate->AssertIsOnParentThread(); + } + return mWorkerPrivate; +} + +void WorkerParentRef::DropWorkerPrivate() { + LOGV(("WorkerParentRef::DropWorkerPrivate [%p]", this)); + if (mWorkerPrivate) { + mWorkerPrivate->AssertIsOnParentThread(); + mWorkerPrivate = nullptr; + } +} + +WorkerParentRef::~WorkerParentRef() = default; + } // namespace dom } // namespace mozilla |