Bug 934774 - Intermittent exception is killing mochitests (primarily browser_pluginnotification.js) because we're dispatching an event to a document which is already dead. Check it's aliveness before dispatching, r=johns
authorBenjamin Smedberg <benjamin@smedbergs.us>
Thu, 07 Nov 2013 10:18:24 -0500
changeset 167385 6f20a758c877eb4923c396d63d6349b9664b22f0
parent 167384 82c4cd6c3b932c5479fb9268060850627ef279fa
child 167386 8da8761dab7d944828ff034a6d10c3cf9ae8f96f
push id428
push userbbajaj@mozilla.com
push dateTue, 28 Jan 2014 00:16:25 +0000
treeherdermozilla-release@cd72a7ff3a75 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjohns
bugs934774
milestone27.0a2
Bug 934774 - Intermittent exception is killing mochitests (primarily browser_pluginnotification.js) because we're dispatching an event to a document which is already dead. Check it's aliveness before dispatching, r=johns
content/base/src/nsObjectLoadingContent.cpp
--- a/content/base/src/nsObjectLoadingContent.cpp
+++ b/content/base/src/nsObjectLoadingContent.cpp
@@ -222,42 +222,46 @@ CheckPluginStopEvent::Run()
  */
 class nsSimplePluginEvent : public nsRunnable {
 public:
   nsSimplePluginEvent(nsIContent* aTarget, const nsAString &aEvent)
     : mTarget(aTarget)
     , mDocument(aTarget->GetCurrentDoc())
     , mEvent(aEvent)
   {
+    MOZ_ASSERT(aTarget && mDocument);
   }
 
   nsSimplePluginEvent(nsIDocument* aTarget, const nsAString& aEvent)
     : mTarget(aTarget)
     , mDocument(aTarget)
     , mEvent(aEvent)
   {
+    MOZ_ASSERT(aTarget);
   }
 
   ~nsSimplePluginEvent() {}
 
   NS_IMETHOD Run();
 
 private:
   nsCOMPtr<nsISupports> mTarget;
   nsCOMPtr<nsIDocument> mDocument;
   nsString mEvent;
 };
 
 NS_IMETHODIMP
 nsSimplePluginEvent::Run()
 {
-  LOG(("OBJLC [%p]: nsSimplePluginEvent firing event \"%s\"", mTarget.get(),
-       mEvent.get()));
-  nsContentUtils::DispatchTrustedEvent(mDocument, mTarget,
-                                       mEvent, true, true);
+  if (mDocument->IsActive()) {
+    LOG(("OBJLC [%p]: nsSimplePluginEvent firing event \"%s\"", mTarget.get(),
+         NS_ConvertUTF16toUTF8(mEvent).get()));
+    nsContentUtils::DispatchTrustedEvent(mDocument, mTarget,
+                                         mEvent, true, true);
+  }
   return NS_OK;
 }
 
 /**
  * A task for firing PluginCrashed DOM Events.
  */
 class nsPluginCrashedEvent : public nsRunnable {
 public:
@@ -705,19 +709,22 @@ nsObjectLoadingContent::UnbindFromTree(b
     QueueCheckPluginStopEvent();
   } else if (mType != eType_Image) {
     // nsImageLoadingContent handles the image case.
     // Reset state and clear pending events
     /// XXX(johns): The implementation for GenericFrame notes that ideally we
     ///             would keep the docshell around, but trash the frameloader
     UnloadObject();
   }
-  nsCOMPtr<nsIRunnable> ev = new nsSimplePluginEvent(thisContent->GetCurrentDoc(),
-                                           NS_LITERAL_STRING("PluginRemoved"));
-  NS_DispatchToCurrentThread(ev);
+  nsIDocument* doc = thisContent->GetCurrentDoc();
+  if (doc && doc->IsActive()) {
+    nsCOMPtr<nsIRunnable> ev = new nsSimplePluginEvent(doc,
+                                                       NS_LITERAL_STRING("PluginRemoved"));
+    NS_DispatchToCurrentThread(ev);
+  }
 }
 
 nsObjectLoadingContent::nsObjectLoadingContent()
   : mType(eType_Loading)
   , mFallbackType(eFallbackAlternate)
   , mChannelLoaded(false)
   , mInstantiating(false)
   , mNetworkCreated(true)