Bug 1687597 - Ensure worker thread is reset before scheduling for deletion. r=dom-workers-and-storage-reviewers,asuth

Differential Revision: https://phabricator.services.mozilla.com/D102439
This commit is contained in:
Simon Giesecke 2021-01-26 09:47:08 +00:00
Родитель 51b7d9634a
Коммит 6bffb40eae
1 изменённых файлов: 70 добавлений и 89 удалений

Просмотреть файл

@ -2167,33 +2167,7 @@ WorkerThreadPrimaryRunnable::Run() {
using mozilla::ipc::BackgroundChild;
class MOZ_STACK_CLASS SetThreadHelper final {
// Raw pointer: this class is on the stack.
WorkerPrivate* mWorkerPrivate;
public:
SetThreadHelper(WorkerPrivate* aWorkerPrivate, WorkerThread& aThread)
: mWorkerPrivate(aWorkerPrivate) {
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->SetWorkerPrivateInWorkerThread(&aThread);
}
~SetThreadHelper() {
if (mWorkerPrivate) {
mWorkerPrivate->ResetWorkerPrivateInWorkerThread();
}
}
void Nullify() {
MOZ_ASSERT(mWorkerPrivate);
mWorkerPrivate->ResetWorkerPrivateInWorkerThread();
mWorkerPrivate = nullptr;
}
};
SetThreadHelper threadHelper(mWorkerPrivate, *mThread);
{
auto failureCleanup = MakeScopeExit([&]() {
// The creation of threadHelper above is the point at which a worker is
// considered to have run, because the `mPreStartRunnables` are all
@ -2202,6 +2176,14 @@ WorkerThreadPrimaryRunnable::Run() {
mWorkerPrivate->RunLoopNeverRan();
});
mWorkerPrivate->SetWorkerPrivateInWorkerThread(mThread.unsafeGetRawPtr());
const auto threadCleanup = MakeScopeExit([&] {
// This must be called before ScheduleDeletion, which is either called
// from failureCleanup leaving scope, or from the outer scope.
mWorkerPrivate->ResetWorkerPrivateInWorkerThread();
});
mWorkerPrivate->AssertIsOnWorkerThread();
// This needs to be initialized on the worker thread before being used on
@ -2235,8 +2217,8 @@ WorkerThreadPrimaryRunnable::Run() {
{
// We're on the worker thread here, and WorkerPrivate's refcounting is
// non-threadsafe: you can only do it on the parent thread. What that
// means in practice is that we're relying on it being kept alive while
// we run. Hopefully.
// means in practice is that we're relying on it being kept alive
// while we run. Hopefully.
MOZ_KnownLive(mWorkerPrivate)->DoRunLoop(cx);
// The AutoJSAPI in DoRunLoop should have reported any exceptions left
// on cx.
@ -2268,8 +2250,7 @@ WorkerThreadPrimaryRunnable::Run() {
// down the cycle collector. This breaks any remaining cycles and collects
// any remaining C++ objects.
}
threadHelper.Nullify();
}
mWorkerPrivate->ScheduleDeletion(WorkerPrivate::WorkerRan);