Bug 621260. Don't run StopPluginInstance multiple times on the same instance. Also, let StopPluginInstance do the call to instance->Stop(). r+a=josh
authorRobert O'Callahan <robert@ocallahan.org>
Mon, 20 Dec 2010 14:37:43 +1300
changeset 59756 bbb7cd978802863fba71108ed4773db0261f24eb
parent 59755 804aa1c428d2ecc51472618bf6d6afe434bee596
child 59757 a05e91710adb88a0247db7c1a009062c6ded659e
push id1
push userroot
push dateTue, 26 Apr 2011 22:38:44 +0000
treeherdermozilla-beta@bfdb6e623a36 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs621260
milestone2.0b9pre
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 621260. Don't run StopPluginInstance multiple times on the same instance. Also, let StopPluginInstance do the call to instance->Stop(). r+a=josh
layout/generic/nsObjectFrame.cpp
modules/plugin/base/src/nsNPAPIPluginInstance.h
modules/plugin/base/src/nsPluginHost.cpp
--- a/layout/generic/nsObjectFrame.cpp
+++ b/layout/generic/nsObjectFrame.cpp
@@ -2518,21 +2518,19 @@ DoStopPlugin(nsPluginInstanceOwner *aIns
     
     if (DoDelayedStop(aInstanceOwner, aDelayedStop))
       return;
 
 #if defined(XP_MACOSX)
     aInstanceOwner->HidePluginWindow();
 #endif
 
-    inst->Stop();
-
     nsCOMPtr<nsIPluginHost> pluginHost = do_GetService(MOZ_PLUGIN_HOST_CONTRACTID);
-    if (pluginHost)
-      pluginHost->StopPluginInstance(inst);
+    NS_ASSERTION(pluginHost, "Without a pluginHost, how can we have an instance to destroy?");
+    pluginHost->StopPluginInstance(inst);
 
     // the frame is going away along with its widget so tell the
     // window to forget its widget too
     if (window)
       window->SetPluginWidget(nsnull);
   }
 
   aInstanceOwner->Destroy();
--- a/modules/plugin/base/src/nsNPAPIPluginInstance.h
+++ b/modules/plugin/base/src/nsNPAPIPluginInstance.h
@@ -104,16 +104,19 @@ public:
   // To be called when an instance becomes orphaned, when
   // it's plugin is no longer guaranteed to be around.
   void Destroy();
 
   // Indicates whether the plugin is running normally.
   bool IsRunning() {
     return RUNNING == mRunning;
   }
+  bool HasStartedDestroying() {
+    return mRunning >= DESTROYING;
+  }
 
   // Indicates whether the plugin is running normally or being shut down
   bool CanFireNotifications() {
     return mRunning == RUNNING || mRunning == DESTROYING;
   }
 
   // return is only valid when the plugin is not running
   mozilla::TimeStamp LastStopTime();
--- a/modules/plugin/base/src/nsPluginHost.cpp
+++ b/modules/plugin/base/src/nsPluginHost.cpp
@@ -1213,17 +1213,17 @@ nsPluginHost::TagForPlugin(nsNPAPIPlugin
 {
   nsPluginTag* pluginTag;
   for (pluginTag = mPlugins; pluginTag; pluginTag = pluginTag->mNext) {
     if (pluginTag->mEntryPoint == aPlugin) {
       return pluginTag;
     }
   }
   // a plugin should never exist without a corresponding tag
-  NS_ASSERTION(PR_FALSE, "TagForPlugin has failed");
+  NS_ERROR("TagForPlugin has failed");
   return nsnull;
 }
 
 nsresult nsPluginHost::FindStoppedPluginForURL(nsIURI* aURL,
                                                nsIPluginInstanceOwner *aOwner)
 {
   nsCAutoString url;
   if (!aURL)
@@ -3211,20 +3211,22 @@ nsPluginHost::StopPluginInstance(nsIPlug
 {
   if (PluginDestructionGuard::DelayDestroy(aInstance)) {
     return NS_OK;
   }
 
   PLUGIN_LOG(PLUGIN_LOG_NORMAL,
   ("nsPluginHost::StopPluginInstance called instance=%p\n",aInstance));
 
+  nsNPAPIPluginInstance* instance = static_cast<nsNPAPIPluginInstance*>(aInstance);
+  if (instance->HasStartedDestroying())
+    return NS_OK;
+
   aInstance->Stop();
 
-  nsNPAPIPluginInstance* instance = static_cast<nsNPAPIPluginInstance*>(aInstance);
-
   // if the plugin does not want to be 'cached' just remove it
   PRBool doCache = PR_TRUE;
   aInstance->ShouldCache(&doCache);
   if (doCache) {
     // try to get the max cached plugins from a pref or use default
     PRUint32 cachedPluginLimit;
     nsresult rv = NS_ERROR_FAILURE;
     if (mPrefService)