Bug 1268559 - Wait to finish nested event loops before shutdown. r=bsmedberg, a=gchang
☠☠ backed out by 676a32cdd41f ☠ ☠
authorBill McCloskey <billm@mozilla.com>
Fri, 03 Jun 2016 17:22:08 -0700
changeset 320779 9c18d3b6998ccb565c52bc5738dedbc28f14a86e
parent 320778 35e0d7dd7cd7bff301b75756361b36b275102404
child 320780 5fa507fc453c3fbfa704a3769025a96475310ed0
push id6125
push userkwierso@gmail.com
push dateMon, 27 Jun 2016 21:20:43 +0000
treeherdermozilla-esr52@9c18d3b6998c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbsmedberg, gchang
bugs1268559
milestone48.0
Bug 1268559 - Wait to finish nested event loops before shutdown. r=bsmedberg, a=gchang
dom/ipc/ContentChild.cpp
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -3038,16 +3038,34 @@ ContentChild::StartForceKillTimer()
 ContentChild::ForceKillTimerCallback(nsITimer* aTimer, void* aClosure)
 {
   ProcessChild::QuickExit();
 }
 
 bool
 ContentChild::RecvShutdown()
 {
+  // If we receive the shutdown message from within a nested event loop, we want
+  // to wait for that event loop to finish. Otherwise we could prematurely
+  // terminate an "unload" or "pagehide" event handler (which might be doing a
+  // sync XHR, for example).
+  nsCOMPtr<nsIThread> thread;
+  nsresult rv = NS_GetMainThread(getter_AddRefs(thread));
+  if (NS_SUCCEEDED(rv) && thread) {
+    RefPtr<nsThread> mainThread(thread.forget().downcast<nsThread>());
+    if (mainThread->RecursionDepth() > 1) {
+      // We're in a nested event loop. Let's delay for an arbitrary period of
+      // time (100ms) in the hopes that the event loop will have finished by
+      // then.
+      MessageLoop::current()->PostDelayedTask(
+        NewRunnableMethod(this, &ContentChild::RecvShutdown), 100);
+      return true;
+    }
+  }
+
   if (mPolicy) {
     mPolicy->Deactivate();
     mPolicy = nullptr;
   }
 
   nsCOMPtr<nsIObserverService> os = services::GetObserverService();
   if (os) {
     os->NotifyObservers(static_cast<nsIContentChild*>(this),