summaryrefslogtreecommitdiffstats
path: root/dom/workers/WorkerRunnable.cpp
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:37 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-12 05:35:37 +0000
commita90a5cba08fdf6c0ceb95101c275108a152a3aed (patch)
tree532507288f3defd7f4dcf1af49698bcb76034855 /dom/workers/WorkerRunnable.cpp
parentAdding debian version 126.0.1-1. (diff)
downloadfirefox-a90a5cba08fdf6c0ceb95101c275108a152a3aed.tar.xz
firefox-a90a5cba08fdf6c0ceb95101c275108a152a3aed.zip
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'dom/workers/WorkerRunnable.cpp')
-rw-r--r--dom/workers/WorkerRunnable.cpp563
1 files changed, 295 insertions, 268 deletions
diff --git a/dom/workers/WorkerRunnable.cpp b/dom/workers/WorkerRunnable.cpp
index 14a3e5e3f9..05831c7cef 100644
--- a/dom/workers/WorkerRunnable.cpp
+++ b/dom/workers/WorkerRunnable.cpp
@@ -54,129 +54,17 @@ const nsIID kWorkerRunnableIID = {
} // namespace
#ifdef DEBUG
-WorkerRunnable::WorkerRunnable(WorkerPrivate* aWorkerPrivate, const char* aName,
- Target aTarget)
- : mWorkerPrivate(aWorkerPrivate),
- mTarget(aTarget),
+WorkerRunnable::WorkerRunnable(const char* aName)
# ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY
- mName(aName),
-# endif
- mCallingCancelWithinRun(false) {
- LOG(("WorkerRunnable::WorkerRunnable [%p]", this));
- MOZ_ASSERT(aWorkerPrivate);
-}
-#endif
-
-bool WorkerRunnable::IsDebuggerRunnable() const { return false; }
-
-nsIGlobalObject* WorkerRunnable::DefaultGlobalObject() const {
- if (IsDebuggerRunnable()) {
- return mWorkerPrivate->DebuggerGlobalScope();
- } else {
- return mWorkerPrivate->GlobalScope();
- }
-}
-
-bool WorkerRunnable::PreDispatch(WorkerPrivate* aWorkerPrivate) {
-#ifdef DEBUG
- MOZ_ASSERT(aWorkerPrivate);
-
- switch (mTarget) {
- case ParentThread:
- aWorkerPrivate->AssertIsOnWorkerThread();
- break;
-
- case WorkerThread:
- aWorkerPrivate->AssertIsOnParentThread();
- break;
-
- default:
- MOZ_ASSERT_UNREACHABLE("Unknown behavior!");
- }
-#endif
- return true;
-}
-
-bool WorkerRunnable::Dispatch() {
- bool ok = PreDispatch(mWorkerPrivate);
- if (ok) {
- ok = DispatchInternal();
- }
- PostDispatch(mWorkerPrivate, ok);
- return ok;
+ : mName(aName) {
+ LOG(("WorkerRunnable::WorkerRunnable [%p] (%s)", this, mName));
}
-
-bool WorkerRunnable::DispatchInternal() {
- LOG(("WorkerRunnable::DispatchInternal [%p]", this));
- RefPtr<WorkerRunnable> runnable(this);
-
- if (mTarget == WorkerThread) {
- if (IsDebuggerRunnable()) {
- return NS_SUCCEEDED(
- mWorkerPrivate->DispatchDebuggerRunnable(runnable.forget()));
- } else {
- return NS_SUCCEEDED(mWorkerPrivate->Dispatch(runnable.forget()));
- }
- }
-
- MOZ_ASSERT(mTarget == ParentThread);
-
- if (WorkerPrivate* parent = mWorkerPrivate->GetParent()) {
- return NS_SUCCEEDED(parent->Dispatch(runnable.forget()));
- }
-
- if (IsDebuggeeRunnable()) {
- RefPtr<WorkerDebuggeeRunnable> debuggeeRunnable =
- runnable.forget().downcast<WorkerDebuggeeRunnable>();
- return NS_SUCCEEDED(mWorkerPrivate->DispatchDebuggeeToMainThread(
- debuggeeRunnable.forget(), NS_DISPATCH_NORMAL));
- }
-
- return NS_SUCCEEDED(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
-}
-
-void WorkerRunnable::PostDispatch(WorkerPrivate* aWorkerPrivate,
- bool aDispatchResult) {
- MOZ_ASSERT(aWorkerPrivate);
-
-#ifdef DEBUG
- switch (mTarget) {
- case ParentThread:
- aWorkerPrivate->AssertIsOnWorkerThread();
- break;
-
- case WorkerThread:
- aWorkerPrivate->AssertIsOnParentThread();
- break;
-
- default:
- MOZ_ASSERT_UNREACHABLE("Unknown behavior!");
- }
-#endif
+# else
+{
+ LOG(("WorkerRunnable::WorkerRunnable [%p]", this));
}
-
-bool WorkerRunnable::PreRun(WorkerPrivate* aWorkerPrivate) { return true; }
-
-void WorkerRunnable::PostRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate,
- bool aRunResult) {
- MOZ_ASSERT(aCx);
- MOZ_ASSERT(aWorkerPrivate);
-
-#ifdef DEBUG
- switch (mTarget) {
- case ParentThread:
- aWorkerPrivate->AssertIsOnParentThread();
- break;
-
- case WorkerThread:
- aWorkerPrivate->AssertIsOnWorkerThread();
- break;
-
- default:
- MOZ_ASSERT_UNREACHABLE("Unknown behavior!");
- }
+# endif
#endif
-}
// static
WorkerRunnable* WorkerRunnable::FromRunnable(nsIRunnable* aRunnable) {
@@ -193,6 +81,20 @@ WorkerRunnable* WorkerRunnable::FromRunnable(nsIRunnable* aRunnable) {
return runnable;
}
+bool WorkerRunnable::Dispatch(WorkerPrivate* aWorkerPrivate) {
+ LOG(("WorkerRunnable::Dispatch [%p] aWorkerPrivate: %p", this,
+ aWorkerPrivate));
+ MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
+ bool ok = PreDispatch(aWorkerPrivate);
+ if (ok) {
+ ok = DispatchInternal(aWorkerPrivate);
+ }
+ PostDispatch(aWorkerPrivate, ok);
+ return ok;
+}
+
+NS_IMETHODIMP WorkerRunnable::Run() { return NS_OK; }
+
NS_IMPL_ADDREF(WorkerRunnable)
NS_IMPL_RELEASE(WorkerRunnable)
@@ -221,79 +123,83 @@ NS_INTERFACE_MAP_BEGIN(WorkerRunnable)
} else
NS_INTERFACE_MAP_END
-NS_IMETHODIMP
-WorkerRunnable::Run() {
- LOG(("WorkerRunnable::Run [%p]", this));
- bool targetIsWorkerThread = mTarget == WorkerThread;
+WorkerParentThreadRunnable::WorkerParentThreadRunnable(const char* aName)
+ : WorkerRunnable(aName) {
+ LOG(("WorkerParentThreadRunnable::WorkerParentThreadRunnable [%p]", this));
+}
+WorkerParentThreadRunnable::~WorkerParentThreadRunnable() = default;
+
+bool WorkerParentThreadRunnable::PreDispatch(WorkerPrivate* aWorkerPrivate) {
#ifdef DEBUG
- if (targetIsWorkerThread) {
- mWorkerPrivate->AssertIsOnWorkerThread();
- } else {
- MOZ_ASSERT(mTarget == ParentThread);
- mWorkerPrivate->AssertIsOnParentThread();
- }
+ MOZ_ASSERT(aWorkerPrivate);
+ aWorkerPrivate->AssertIsOnWorkerThread();
#endif
+ return true;
+}
- if (targetIsWorkerThread && !mCallingCancelWithinRun &&
- mWorkerPrivate->CancelBeforeWorkerScopeConstructed()) {
- mCallingCancelWithinRun = true;
- Cancel();
- mCallingCancelWithinRun = false;
+bool WorkerParentThreadRunnable::DispatchInternal(
+ WorkerPrivate* aWorkerPrivate) {
+ LOG(("WorkerParentThreadRunnable::DispatchInternal [%p]", this));
+ mWorkerParentRef = aWorkerPrivate->GetWorkerParentRef();
+ RefPtr<WorkerParentThreadRunnable> runnable(this);
+ return NS_SUCCEEDED(aWorkerPrivate->DispatchToParent(runnable.forget()));
+}
+
+void WorkerParentThreadRunnable::PostDispatch(WorkerPrivate* aWorkerPrivate,
+ bool aDispatchResult) {
+#ifdef DEBUG
+ MOZ_ASSERT(aWorkerPrivate);
+ aWorkerPrivate->AssertIsOnWorkerThread();
+#endif
+}
+
+bool WorkerParentThreadRunnable::PreRun(WorkerPrivate* aWorkerPrivate) {
+ return true;
+}
+
+void WorkerParentThreadRunnable::PostRun(JSContext* aCx,
+ WorkerPrivate* aWorkerPrivate,
+ bool aRunResult) {
+ MOZ_ASSERT(aCx);
+#ifdef DEBUG
+ MOZ_ASSERT(aWorkerPrivate);
+ aWorkerPrivate->AssertIsOnParentThread();
+#endif
+}
+
+NS_IMETHODIMP
+WorkerParentThreadRunnable::Run() {
+ LOG(("WorkerParentThreadRunnable::Run [%p]", this));
+ RefPtr<WorkerPrivate> workerPrivate;
+ MOZ_ASSERT(mWorkerParentRef);
+ workerPrivate = mWorkerParentRef->Private();
+ if (!workerPrivate) {
+ NS_WARNING("Worker has already shut down!!!");
return NS_OK;
}
+#ifdef DEBUG
+ workerPrivate->AssertIsOnParentThread();
+#endif
- bool result = PreRun(mWorkerPrivate);
- if (!result) {
- MOZ_ASSERT(targetIsWorkerThread,
- "The only PreRun implementation that can fail is "
- "ScriptExecutorRunnable");
- mWorkerPrivate->AssertIsOnWorkerThread();
- MOZ_ASSERT(!JS_IsExceptionPending(mWorkerPrivate->GetJSContext()));
- // We can't enter a useful realm on the JSContext here; just pass it
- // in as-is.
- PostRun(mWorkerPrivate->GetJSContext(), mWorkerPrivate, false);
- return NS_ERROR_FAILURE;
- }
+ WorkerPrivate* parent = workerPrivate->GetParent();
+ bool isOnMainThread = !parent;
+ bool result = PreRun(workerPrivate);
+ MOZ_ASSERT(result);
+
+ LOG(("WorkerParentThreadRunnable::Run [%p] WorkerPrivate: %p, parent: %p",
+ this, workerPrivate.get(), parent));
// Track down the appropriate global, if any, to use for the AutoEntryScript.
nsCOMPtr<nsIGlobalObject> globalObject;
- bool isMainThread = !targetIsWorkerThread && !mWorkerPrivate->GetParent();
- MOZ_ASSERT(isMainThread == NS_IsMainThread());
- RefPtr<WorkerPrivate> kungFuDeathGrip;
- if (targetIsWorkerThread) {
- globalObject = mWorkerPrivate->GetCurrentEventLoopGlobal();
- if (!globalObject) {
- globalObject = DefaultGlobalObject();
- // Our worker thread may not be in a good state here if there is no
- // JSContext avaliable. The way this manifests itself is that
- // globalObject ends up null (though it's not clear to me how we can be
- // running runnables at all when DefaultGlobalObject() is returning
- // false!) and then when we try to init the AutoJSAPI either
- // CycleCollectedJSContext::Get() returns null or it has a null JSContext.
- // In any case, we used to have a check for
- // GetCurrentWorkerThreadJSContext() being non-null here and that seems to
- // avoid the problem, so let's keep doing that check even if we don't need
- // the JSContext here at all.
- if (NS_WARN_IF(!globalObject && !GetCurrentWorkerThreadJSContext())) {
- return NS_ERROR_FAILURE;
- }
- }
-
- // We may still not have a globalObject here: in the case of
- // CompileScriptRunnable, we don't actually create the global object until
- // we have the script data, which happens in a syncloop under
- // CompileScriptRunnable::WorkerRun, so we can't assert that it got created
- // in the PreRun call above.
+ if (isOnMainThread) {
+ MOZ_ASSERT(isOnMainThread == NS_IsMainThread());
+ globalObject = nsGlobalWindowInner::Cast(workerPrivate->GetWindow());
} else {
- kungFuDeathGrip = mWorkerPrivate;
- if (isMainThread) {
- globalObject = nsGlobalWindowInner::Cast(mWorkerPrivate->GetWindow());
- } else {
- globalObject = mWorkerPrivate->GetParent()->GlobalScope();
- }
+ MOZ_ASSERT(parent == GetCurrentThreadWorkerPrivate());
+ globalObject = parent->GlobalScope();
+ MOZ_DIAGNOSTIC_ASSERT(globalObject);
}
-
// We might run script as part of WorkerRun, so we need an AutoEntryScript.
// This is part of the HTML spec for workers at:
// http://www.whatwg.org/specs/web-apps/current-work/#run-a-worker
@@ -303,8 +209,9 @@ WorkerRunnable::Run() {
Maybe<mozilla::dom::AutoEntryScript> aes;
JSContext* cx;
AutoJSAPI* jsapi;
+
if (globalObject) {
- aes.emplace(globalObject, "Worker runnable", isMainThread);
+ aes.emplace(globalObject, "Worker parent thread runnable", isOnMainThread);
jsapi = aes.ptr();
cx = aes->cx();
} else {
@@ -315,7 +222,7 @@ WorkerRunnable::Run() {
}
// Note that we can't assert anything about
- // mWorkerPrivate->ParentEventTargetRef()->GetWrapper()
+ // workerPrivate->ParentEventTargetRef()->GetWrapper()
// existing, since it may in fact have been GCed (and we may be one of the
// runnables cleaning up the worker as a result).
@@ -325,17 +232,18 @@ WorkerRunnable::Run() {
// definitely have a globalObject. If it _is_ the main thread, globalObject
// can be null for workers started from JSMs or other non-window contexts,
// sadly.
- MOZ_ASSERT_IF(!targetIsWorkerThread && !isMainThread,
- mWorkerPrivate->IsDedicatedWorker() && globalObject);
+ MOZ_ASSERT_IF(!isOnMainThread,
+ workerPrivate->IsDedicatedWorker() && globalObject);
// If we're on the parent thread we might be in a null realm in the
// situation described above when globalObject is null. Make sure to enter
// the realm of the worker's reflector if there is one. There might
// not be one if we're just starting to compile the script for this worker.
Maybe<JSAutoRealm> ar;
- if (!targetIsWorkerThread && mWorkerPrivate->IsDedicatedWorker() &&
- mWorkerPrivate->ParentEventTargetRef()->GetWrapper()) {
- JSObject* wrapper = mWorkerPrivate->ParentEventTargetRef()->GetWrapper();
+ if (workerPrivate->IsDedicatedWorker() &&
+ workerPrivate->ParentEventTargetRef() &&
+ workerPrivate->ParentEventTargetRef()->GetWrapper()) {
+ JSObject* wrapper = workerPrivate->ParentEventTargetRef()->GetWrapper();
// If we're on the parent thread and have a reflector and a globalObject,
// then the realms of cx, globalObject, and the worker's reflector
@@ -359,12 +267,9 @@ WorkerRunnable::Run() {
}
MOZ_ASSERT(!jsapi->HasException());
- result = WorkerRun(cx, mWorkerPrivate);
+ result = WorkerRun(cx, workerPrivate);
jsapi->ReportException();
- // We can't even assert that this didn't create our global, since in the case
- // of CompileScriptRunnable it _does_.
-
// It would be nice to avoid passing a JSContext to PostRun, but in the case
// of ScriptExecutorRunnable we need to know the current compartment on the
// JSContext (the one we set up based on the global returned from PreRun) so
@@ -383,71 +288,226 @@ WorkerRunnable::Run() {
// this point; in the one case in which we could do that
// (CompileScriptRunnable) it actually doesn't matter which compartment we're
// in for PostRun.
- PostRun(cx, mWorkerPrivate, result);
+ PostRun(cx, workerPrivate, result);
MOZ_ASSERT(!jsapi->HasException());
return result ? NS_OK : NS_ERROR_FAILURE;
}
-nsresult WorkerRunnable::Cancel() {
- LOG(("WorkerRunnable::Cancel [%p]", this));
+nsresult WorkerParentThreadRunnable::Cancel() {
+ LOG(("WorkerParentThreadRunnable::Cancel [%p]", this));
return NS_OK;
}
-void WorkerDebuggerRunnable::PostDispatch(WorkerPrivate* aWorkerPrivate,
- bool aDispatchResult) {}
+WorkerParentControlRunnable::WorkerParentControlRunnable(const char* aName)
+ : WorkerParentThreadRunnable(aName) {}
-WorkerSyncRunnable::WorkerSyncRunnable(WorkerPrivate* aWorkerPrivate,
- nsIEventTarget* aSyncLoopTarget,
- const char* aName)
- : WorkerRunnable(aWorkerPrivate, aName, WorkerThread),
- mSyncLoopTarget(aSyncLoopTarget) {
-#ifdef DEBUG
- if (mSyncLoopTarget) {
- mWorkerPrivate->AssertValidSyncLoop(mSyncLoopTarget);
+WorkerParentControlRunnable::~WorkerParentControlRunnable() = default;
+
+nsresult WorkerParentControlRunnable::Cancel() {
+ LOG(("WorkerParentControlRunnable::Cancel [%p]", this));
+ if (NS_FAILED(Run())) {
+ NS_WARNING("WorkerParentControlRunnable::Run() failed.");
+ }
+ return NS_OK;
+}
+
+WorkerThreadRunnable::WorkerThreadRunnable(const char* aName)
+ : WorkerRunnable(aName), mCallingCancelWithinRun(false) {
+ LOG(("WorkerThreadRunnable::WorkerThreadRunnable [%p]", this));
+}
+
+nsIGlobalObject* WorkerThreadRunnable::DefaultGlobalObject(
+ WorkerPrivate* aWorkerPrivate) const {
+ MOZ_DIAGNOSTIC_ASSERT(aWorkerPrivate);
+ if (IsDebuggerRunnable()) {
+ return aWorkerPrivate->DebuggerGlobalScope();
}
+ return aWorkerPrivate->GlobalScope();
+}
+
+bool WorkerThreadRunnable::PreDispatch(WorkerPrivate* aWorkerPrivate) {
+ MOZ_ASSERT(aWorkerPrivate);
+#ifdef DEBUG
+ aWorkerPrivate->AssertIsOnParentThread();
#endif
+ return true;
}
-WorkerSyncRunnable::WorkerSyncRunnable(
- WorkerPrivate* aWorkerPrivate, nsCOMPtr<nsIEventTarget>&& aSyncLoopTarget,
- const char* aName)
- : WorkerRunnable(aWorkerPrivate, aName, WorkerThread),
- mSyncLoopTarget(std::move(aSyncLoopTarget)) {
+bool WorkerThreadRunnable::DispatchInternal(WorkerPrivate* aWorkerPrivate) {
+ LOG(("WorkerThreadRunnable::DispatchInternal [%p]", this));
+ RefPtr<WorkerThreadRunnable> runnable(this);
+ return NS_SUCCEEDED(aWorkerPrivate->Dispatch(runnable.forget()));
+}
+
+void WorkerThreadRunnable::PostDispatch(WorkerPrivate* aWorkerPrivate,
+ bool aDispatchResult) {
+ MOZ_ASSERT(aWorkerPrivate);
#ifdef DEBUG
- if (mSyncLoopTarget) {
- mWorkerPrivate->AssertValidSyncLoop(mSyncLoopTarget);
+ aWorkerPrivate->AssertIsOnParentThread();
+#endif
+}
+
+bool WorkerThreadRunnable::PreRun(WorkerPrivate* aWorkerPrivate) {
+ return true;
+}
+
+void WorkerThreadRunnable::PostRun(JSContext* aCx,
+ WorkerPrivate* aWorkerPrivate,
+ bool aRunResult) {
+ MOZ_ASSERT(aCx);
+ MOZ_ASSERT(aWorkerPrivate);
+
+#ifdef DEBUG
+ aWorkerPrivate->AssertIsOnWorkerThread();
+#endif
+}
+
+NS_IMETHODIMP
+WorkerThreadRunnable::Run() {
+ LOG(("WorkerThreadRunnable::Run [%p]", this));
+ WorkerPrivate* workerPrivate = GetCurrentThreadWorkerPrivate();
+ if (!workerPrivate && mWorkerPrivateForPreStartCleaning) {
+ workerPrivate = mWorkerPrivateForPreStartCleaning;
+ mWorkerPrivateForPreStartCleaning = nullptr;
}
+ MOZ_ASSERT_DEBUG_OR_FUZZING(workerPrivate);
+#ifdef DEBUG
+ workerPrivate->AssertIsOnWorkerThread();
#endif
+
+ if (!mCallingCancelWithinRun &&
+ workerPrivate->CancelBeforeWorkerScopeConstructed()) {
+ mCallingCancelWithinRun = true;
+ Cancel();
+ mCallingCancelWithinRun = false;
+ return NS_OK;
+ }
+
+ bool result = PreRun(workerPrivate);
+ if (!result) {
+ workerPrivate->AssertIsOnWorkerThread();
+ MOZ_ASSERT(!JS_IsExceptionPending(workerPrivate->GetJSContext()));
+ // We can't enter a useful realm on the JSContext here; just pass it
+ // in as-is.
+ PostRun(workerPrivate->GetJSContext(), workerPrivate, false);
+ return NS_ERROR_FAILURE;
+ }
+
+ // Track down the appropriate global, if any, to use for the AutoEntryScript.
+ nsCOMPtr<nsIGlobalObject> globalObject =
+ workerPrivate->GetCurrentEventLoopGlobal();
+ if (!globalObject) {
+ globalObject = DefaultGlobalObject(workerPrivate);
+ // Our worker thread may not be in a good state here if there is no
+ // JSContext avaliable. The way this manifests itself is that
+ // globalObject ends up null (though it's not clear to me how we can be
+ // running runnables at all when default globalObject(DebuggerGlobalScope
+ // for debugger runnable, and GlobalScope for normal runnables) is returning
+ // false!) and then when we try to init the AutoJSAPI either
+ // CycleCollectedJSContext::Get() returns null or it has a null JSContext.
+ // In any case, we used to have a check for
+ // GetCurrentWorkerThreadJSContext() being non-null here and that seems to
+ // avoid the problem, so let's keep doing that check even if we don't need
+ // the JSContext here at all.
+ if (NS_WARN_IF(!globalObject && !GetCurrentWorkerThreadJSContext())) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // We might run script as part of WorkerRun, so we need an AutoEntryScript.
+ // This is part of the HTML spec for workers at:
+ // http://www.whatwg.org/specs/web-apps/current-work/#run-a-worker
+ // If we don't have a globalObject we have to use an AutoJSAPI instead, but
+ // this is OK as we won't be running script in these circumstances.
+ Maybe<mozilla::dom::AutoJSAPI> maybeJSAPI;
+ Maybe<mozilla::dom::AutoEntryScript> aes;
+ JSContext* cx;
+ AutoJSAPI* jsapi;
+ if (globalObject) {
+ aes.emplace(globalObject, "Worker runnable", false);
+ jsapi = aes.ptr();
+ cx = aes->cx();
+ } else {
+ maybeJSAPI.emplace();
+ maybeJSAPI->Init();
+ jsapi = maybeJSAPI.ptr();
+ cx = jsapi->cx();
+ }
+
+ MOZ_ASSERT(!jsapi->HasException());
+ result = WorkerRun(cx, workerPrivate);
+ jsapi->ReportException();
+
+ // We can't even assert that this didn't create our global, since in the case
+ // of CompileScriptRunnable it _does_.
+
+ // It would be nice to avoid passing a JSContext to PostRun, but in the case
+ // of ScriptExecutorRunnable we need to know the current compartment on the
+ // JSContext (the one we set up based on the global returned from PreRun) so
+ // that we can sanely do exception reporting. In particular, we want to make
+ // sure that we do our JS_SetPendingException while still in that compartment,
+ // because otherwise we might end up trying to create a cross-compartment
+ // wrapper when we try to move the JS exception from our runnable's
+ // ErrorResult to the JSContext, and that's not desirable in this case.
+ //
+ // We _could_ skip passing a JSContext here and then in
+ // ScriptExecutorRunnable::PostRun end up grabbing it from the WorkerPrivate
+ // and looking at its current compartment. But that seems like slightly weird
+ // action-at-a-distance...
+ //
+ // In any case, we do NOT try to change the compartment on the JSContext at
+ // this point; in the one case in which we could do that
+ // (CompileScriptRunnable) it actually doesn't matter which compartment we're
+ // in for PostRun.
+ PostRun(cx, workerPrivate, result);
+ MOZ_ASSERT(!jsapi->HasException());
+
+ return result ? NS_OK : NS_ERROR_FAILURE;
}
+nsresult WorkerThreadRunnable::Cancel() {
+ LOG(("WorkerThreadRunnable::Cancel [%p]", this));
+ return NS_OK;
+}
+
+void WorkerDebuggerRunnable::PostDispatch(WorkerPrivate* aWorkerPrivate,
+ bool aDispatchResult) {}
+
+WorkerSyncRunnable::WorkerSyncRunnable(nsIEventTarget* aSyncLoopTarget,
+ const char* aName)
+ : WorkerThreadRunnable(aName), mSyncLoopTarget(aSyncLoopTarget) {}
+
+WorkerSyncRunnable::WorkerSyncRunnable(
+ nsCOMPtr<nsIEventTarget>&& aSyncLoopTarget, const char* aName)
+ : WorkerThreadRunnable(aName),
+ mSyncLoopTarget(std::move(aSyncLoopTarget)) {}
+
WorkerSyncRunnable::~WorkerSyncRunnable() = default;
-bool WorkerSyncRunnable::DispatchInternal() {
+bool WorkerSyncRunnable::DispatchInternal(WorkerPrivate* aWorkerPrivate) {
if (mSyncLoopTarget) {
+#ifdef DEBUG
+ aWorkerPrivate->AssertValidSyncLoop(mSyncLoopTarget);
+#endif
RefPtr<WorkerSyncRunnable> runnable(this);
return NS_SUCCEEDED(
mSyncLoopTarget->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL));
}
- return WorkerRunnable::DispatchInternal();
+ return WorkerThreadRunnable::DispatchInternal(aWorkerPrivate);
}
void MainThreadWorkerSyncRunnable::PostDispatch(WorkerPrivate* aWorkerPrivate,
bool aDispatchResult) {}
MainThreadStopSyncLoopRunnable::MainThreadStopSyncLoopRunnable(
- WorkerPrivate* aWorkerPrivate, nsCOMPtr<nsIEventTarget>&& aSyncLoopTarget,
- nsresult aResult)
- : WorkerSyncRunnable(aWorkerPrivate, std::move(aSyncLoopTarget)),
- mResult(aResult) {
+ nsCOMPtr<nsIEventTarget>&& aSyncLoopTarget, nsresult aResult)
+ : WorkerSyncRunnable(std::move(aSyncLoopTarget)), mResult(aResult) {
LOG(("MainThreadStopSyncLoopRunnable::MainThreadStopSyncLoopRunnable [%p]",
this));
AssertIsOnMainThread();
-#ifdef DEBUG
- mWorkerPrivate->AssertValidSyncLoop(mSyncLoopTarget);
-#endif
}
nsresult MainThreadStopSyncLoopRunnable::Cancel() {
@@ -470,9 +530,12 @@ bool MainThreadStopSyncLoopRunnable::WorkerRun(JSContext* aCx,
return true;
}
-bool MainThreadStopSyncLoopRunnable::DispatchInternal() {
+bool MainThreadStopSyncLoopRunnable::DispatchInternal(
+ WorkerPrivate* aWorkerPrivate) {
MOZ_ASSERT(mSyncLoopTarget);
-
+#ifdef DEBUG
+ aWorkerPrivate->AssertValidSyncLoop(mSyncLoopTarget);
+#endif
RefPtr<MainThreadStopSyncLoopRunnable> runnable(this);
return NS_SUCCEEDED(
mSyncLoopTarget->Dispatch(runnable.forget(), NS_DISPATCH_NORMAL));
@@ -481,13 +544,8 @@ bool MainThreadStopSyncLoopRunnable::DispatchInternal() {
void MainThreadStopSyncLoopRunnable::PostDispatch(WorkerPrivate* aWorkerPrivate,
bool aDispatchResult) {}
-#ifdef DEBUG
-WorkerControlRunnable::WorkerControlRunnable(WorkerPrivate* aWorkerPrivate,
- const char* aName, Target aTarget)
- : WorkerRunnable(aWorkerPrivate, aName, aTarget) {
- MOZ_ASSERT(aWorkerPrivate);
-}
-#endif
+WorkerControlRunnable::WorkerControlRunnable(const char* aName)
+ : WorkerThreadRunnable(aName) {}
nsresult WorkerControlRunnable::Cancel() {
LOG(("WorkerControlRunnable::Cancel [%p]", this));
@@ -498,21 +556,6 @@ nsresult WorkerControlRunnable::Cancel() {
return NS_OK;
}
-bool WorkerControlRunnable::DispatchInternal() {
- RefPtr<WorkerControlRunnable> runnable(this);
-
- if (mTarget == WorkerThread) {
- return NS_SUCCEEDED(
- mWorkerPrivate->DispatchControlRunnable(runnable.forget()));
- }
-
- if (WorkerPrivate* parent = mWorkerPrivate->GetParent()) {
- return NS_SUCCEEDED(parent->DispatchControlRunnable(runnable.forget()));
- }
-
- return NS_SUCCEEDED(mWorkerPrivate->DispatchToMainThread(runnable.forget()));
-}
-
WorkerMainThreadRunnable::WorkerMainThreadRunnable(
WorkerPrivate* aWorkerPrivate, const nsACString& aTelemetryKey)
: mozilla::Runnable("dom::WorkerMainThreadRunnable"),
@@ -570,11 +613,10 @@ WorkerMainThreadRunnable::Run() {
bool runResult = MainThreadRun();
RefPtr<MainThreadStopSyncLoopRunnable> response =
- new MainThreadStopSyncLoopRunnable(mWorkerPrivate,
- std::move(mSyncLoopTarget),
+ new MainThreadStopSyncLoopRunnable(std::move(mSyncLoopTarget),
runResult ? NS_OK : NS_ERROR_FAILURE);
- MOZ_ALWAYS_TRUE(response->Dispatch());
+ MOZ_ALWAYS_TRUE(response->Dispatch(mWorkerPrivate));
return NS_OK;
}
@@ -633,15 +675,15 @@ void WorkerProxyToMainThreadRunnable::PostDispatchOnMainThread() {
RefPtr<WorkerProxyToMainThreadRunnable> mRunnable;
public:
- ReleaseRunnable(WorkerPrivate* aWorkerPrivate,
- WorkerProxyToMainThreadRunnable* aRunnable)
- : MainThreadWorkerControlRunnable(aWorkerPrivate),
+ explicit ReleaseRunnable(WorkerProxyToMainThreadRunnable* aRunnable)
+ : MainThreadWorkerControlRunnable("ReleaseRunnable"),
mRunnable(aRunnable) {
MOZ_ASSERT(aRunnable);
}
virtual nsresult Cancel() override {
- Unused << WorkerRun(nullptr, mWorkerPrivate);
+ MOZ_ASSERT(GetCurrentThreadWorkerPrivate());
+ Unused << WorkerRun(nullptr, GetCurrentThreadWorkerPrivate());
return NS_OK;
}
@@ -665,25 +707,10 @@ void WorkerProxyToMainThreadRunnable::PostDispatchOnMainThread() {
~ReleaseRunnable() = default;
};
- RefPtr<WorkerControlRunnable> runnable =
- new ReleaseRunnable(mWorkerRef->Private(), this);
- Unused << NS_WARN_IF(!runnable->Dispatch());
+ RefPtr<WorkerControlRunnable> runnable = new ReleaseRunnable(this);
+ Unused << NS_WARN_IF(!runnable->Dispatch(mWorkerRef->Private()));
}
void WorkerProxyToMainThreadRunnable::ReleaseWorker() { mWorkerRef = nullptr; }
-bool WorkerDebuggeeRunnable::PreDispatch(WorkerPrivate* aWorkerPrivate) {
- if (mTarget == ParentThread) {
- RefPtr<StrongWorkerRef> strongRef = StrongWorkerRef::Create(
- aWorkerPrivate, "WorkerDebuggeeRunnable::mSender");
- if (!strongRef) {
- return false;
- }
-
- mSender = new ThreadSafeWorkerRef(strongRef);
- }
-
- return WorkerRunnable::PreDispatch(aWorkerPrivate);
-}
-
} // namespace mozilla::dom