Bug 982726 - Patch 1.4 - Fix second crash scenario caused by a race in PromiseHolder. r=baku
authorCatalin Badea <catalin.badea392@gmail.com>
Thu, 30 Oct 2014 16:13:00 +0100
changeset 214027 5f914e69229c6cd0935e4e27790364cdf9070d19
parent 214026 7fabdf3714a5fb2ffa9318a0e9a051d50eeb1e36
child 214028 a1a0c1573df1c8960cf866bae6b9b7663ac98363
push id51397
push usercbook@mozilla.com
push dateWed, 05 Nov 2014 07:42:01 +0000
treeherdermozilla-inbound@a1a0c1573df1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbaku
bugs982726
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 982726 - Patch 1.4 - Fix second crash scenario caused by a race in PromiseHolder. r=baku
dom/workers/ServiceWorkerClients.cpp
--- a/dom/workers/ServiceWorkerClients.cpp
+++ b/dom/workers/ServiceWorkerClients.cpp
@@ -155,16 +155,44 @@ public:
 
     // release the reference on the worker thread.
     mPromiseHolder->Clean();
 
     return true;
   }
 };
 
+class ReleasePromiseRunnable MOZ_FINAL : public MainThreadWorkerControlRunnable
+{
+  nsRefPtr<PromiseHolder> mPromiseHolder;
+
+public:
+  ReleasePromiseRunnable(WorkerPrivate* aWorkerPrivate,
+                         PromiseHolder* aPromiseHolder)
+    : MainThreadWorkerControlRunnable(aWorkerPrivate),
+      mPromiseHolder(aPromiseHolder)
+  { }
+
+private:
+  ~ReleasePromiseRunnable()
+  { }
+
+  bool
+  WorkerRun(JSContext* aCx, WorkerPrivate* aWorkerPrivate)
+  {
+    MOZ_ASSERT(aWorkerPrivate);
+    aWorkerPrivate->AssertIsOnWorkerThread();
+
+    mPromiseHolder->Clean();
+
+    return true;
+  }
+
+};
+
 class GetServicedRunnable MOZ_FINAL : public nsRunnable
 {
   WorkerPrivate* mWorkerPrivate;
   nsRefPtr<PromiseHolder> mPromiseHolder;
   nsCString mScope;
 public:
   GetServicedRunnable(WorkerPrivate* aWorkerPrivate,
                       PromiseHolder* aPromiseHolder,
@@ -191,17 +219,29 @@ public:
     nsRefPtr<ServiceWorkerManager> swm = ServiceWorkerManager::GetInstance();
     nsAutoPtr<nsTArray<uint64_t>> result(new nsTArray<uint64_t>());
 
     swm->GetServicedClients(mScope, result);
     nsRefPtr<ResolvePromiseWorkerRunnable> r =
       new ResolvePromiseWorkerRunnable(mWorkerPrivate, mPromiseHolder, result);
 
     AutoSafeJSContext cx;
-    r->Dispatch(cx);
+    if (r->Dispatch(cx)) {
+      return NS_OK;
+    }
+
+    // Dispatch to worker thread failed because the worker is shutting down.
+    // Use a control runnable to release the runnable on the worker thread.
+    nsRefPtr<ReleasePromiseRunnable> releaseRunnable =
+      new ReleasePromiseRunnable(mWorkerPrivate, mPromiseHolder);
+
+    if (!releaseRunnable->Dispatch(cx)) {
+      NS_RUNTIMEABORT("Failed to dispatch PromiseHolder control runnable.");
+    }
+
     return NS_OK;
   }
 };
 
 } // anonymous namespace
 
 already_AddRefed<Promise>
 ServiceWorkerClients::GetServiced(ErrorResult& aRv)