Bug 1279498 - Force WorkerPrivate->SetThread(nullptr) using a RAII, r=khuey
--- a/dom/workers/RuntimeService.cpp
+++ b/dom/workers/RuntimeService.cpp
@@ -2520,17 +2520,47 @@ WorkerThreadPrimaryRunnable::Run()
// Note: SynchronouslyCreateForCurrentThread() must be called prior to
// mWorkerPrivate->SetThread() in order to avoid accidentally consuming
// worker messages here.
if (NS_WARN_IF(!BackgroundChild::SynchronouslyCreateForCurrentThread())) {
// XXX need to fire an error at parent.
return NS_ERROR_UNEXPECTED;
}
- mWorkerPrivate->SetThread(mThread);
+ 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(aWorkerPrivate);
+ MOZ_ASSERT(aThread);
+
+ mWorkerPrivate->SetThread(aThread);
+ }
+
+ ~SetThreadHelper()
+ {
+ if (mWorkerPrivate) {
+ mWorkerPrivate->SetThread(nullptr);
+ }
+ }
+
+ void Nullify()
+ {
+ MOZ_ASSERT(mWorkerPrivate);
+ mWorkerPrivate->SetThread(nullptr);
+ mWorkerPrivate = nullptr;
+ }
+ };
+
+ SetThreadHelper threadHelper(mWorkerPrivate, mThread);
mWorkerPrivate->AssertIsOnWorkerThread();
{
nsCycleCollector_startup();
WorkerJSRuntime runtime(mWorkerPrivate);
nsresult rv = runtime.Initialize(mParentRuntime);
@@ -2590,17 +2620,17 @@ WorkerThreadPrimaryRunnable::Run()
// cleanup.
mWorkerPrivate->ClearMainEventQueue(WorkerPrivate::WorkerRan);
// Now WorkerJSRuntime goes out of scope and its destructor will shut
// down the cycle collector. This breaks any remaining cycles and collects
// any remaining C++ objects.
}
- mWorkerPrivate->SetThread(nullptr);
+ threadHelper.Nullify();
mWorkerPrivate->ScheduleDeletion(WorkerPrivate::WorkerRan);
// It is no longer safe to touch mWorkerPrivate.
mWorkerPrivate = nullptr;
// Now recycle this thread.
nsCOMPtr<nsIThread> mainThread = do_GetMainThread();