diff --git a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp index ba96d01e30e..c0a6a84c983 100644 --- a/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp +++ b/mozilla/modules/plugin/base/src/nsPluginHostImpl.cpp @@ -466,11 +466,7 @@ void nsActivePluginList::shut() for(nsActivePlugin * plugin = mFirst; plugin != nsnull;) { nsActivePlugin * next = plugin->mNext; - - PRBool unloadLibLater = PR_FALSE; - remove(plugin, &unloadLibLater); - NS_ASSERTION(!unloadLibLater, "Plugin doesn't want to be unloaded"); - + remove(plugin); plugin = next; } mFirst = nsnull; @@ -517,7 +513,7 @@ PRBool nsActivePluginList::IsLastInstance(nsActivePlugin * plugin) //////////////////////////////////////////////////////////////////////// -PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * aUnloadLibraryLater) +PRBool nsActivePluginList::remove(nsActivePlugin * plugin) { if(mFirst == nsnull) return PR_FALSE; @@ -548,19 +544,7 @@ PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * aUnloadLibra delete p; // plugin instance is destroyed here if(pluginTag) - { - // xpconnected plugins from the old world should postpone unloading library - // to avoid crash check, if so add library to the list of unloaded libraries - if(pluginTag->mXPConnected && (pluginTag->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL)) - { - pluginTag->mCanUnloadLibrary = PR_FALSE; - - if(aUnloadLibraryLater) - *aUnloadLibraryLater = PR_TRUE; - } - pluginTag->TryUnloadPlugin(); - } else NS_ASSERTION(pluginTag, "pluginTag was not set, plugin not shutdown"); @@ -623,12 +607,7 @@ void nsActivePluginList::removeAllStopped() next = p->mNext; if(p->mStopped) - { - // we don't care about unloading library problem for - // plugins that are already in the 'stop' state - PRBool unloadLibLater = PR_FALSE; - remove(p, &unloadLibLater); - } + remove(p); p = next; } @@ -750,25 +729,10 @@ nsActivePlugin * nsActivePluginList::findOldestStopped() return res; } - -//////////////////////////////////////////////////////////////////////// -nsUnusedLibrary::nsUnusedLibrary(PRLibrary * aLibrary) -{ - mLibrary = aLibrary; -} - - -//////////////////////////////////////////////////////////////////////// -nsUnusedLibrary::~nsUnusedLibrary() -{ - if(mLibrary) - PostPluginUnloadEvent(mLibrary); -} - - //////////////////////////////////////////////////////////////////////// nsPluginTag::nsPluginTag() { + mPluginHost = nsnull; mNext = nsnull; mName = nsnull; mDescription = nsnull; @@ -802,6 +766,7 @@ inline char* new_str(const char* str) //////////////////////////////////////////////////////////////////////// nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag) { + mPluginHost = nsnull; mNext = nsnull; mName = new_str(aPluginTag->mName); mDescription = new_str(aPluginTag->mDescription); @@ -845,6 +810,7 @@ nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag) //////////////////////////////////////////////////////////////////////// nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo) { + mPluginHost = nsnull; mNext = nsnull; mName = new_str(aPluginInfo->fName); mDescription = new_str(aPluginInfo->fDescription); @@ -914,6 +880,7 @@ nsPluginTag::nsPluginTag(const char* aName, mXPConnected(PR_FALSE), mLastModifiedTime(aLastModifiedTime) { + mPluginHost = nsnull; mName = new_str(aName); mDescription = new_str(aDescription); mFileName = new_str(aFileName); @@ -984,6 +951,11 @@ nsPluginTag::~nsPluginTag() } +void nsPluginTag::SetHost(nsPluginHostImpl * aHost) +{ + mPluginHost = aHost; +} + //---------------------------------------------------------------------- // helper struct for asynchronous handeling of plugin unloading struct nsPluginUnloadEvent: public PLEvent { @@ -1058,8 +1030,17 @@ void nsPluginTag::TryUnloadPlugin(PRBool aForceShutdown) // before we unload check if we are allowed to, see bug #61388 // also, never unload an XPCOM plugin library - if (mLibrary && mCanUnloadLibrary && !isXPCOM) - PostPluginUnloadEvent(mLibrary); // unload the plugin asynchronously by posting a PLEvent + if (mLibrary && mCanUnloadLibrary && !isXPCOM) { + // NPAPI plugins can be unloaded now if they don't use XPConnect + if (!mXPConnected) + // unload the plugin asynchronously by posting a PLEvent + PostPluginUnloadEvent(mLibrary); + else { + // add library to the unused library list to handle it later + if (mPluginHost) + mPluginHost->AddUnusedLibrary(mLibrary); + } + } // we should zero it anyway, it is going to be unloaded by // CleanUnsedLibraries before we need to call the library @@ -1068,7 +1049,6 @@ void nsPluginTag::TryUnloadPlugin(PRBool aForceShutdown) mLibrary = nsnull; } - //////////////////////////////////////////////////////////////////////// PRBool nsPluginTag::Equals(nsPluginTag *aPluginTag) { @@ -2562,9 +2542,9 @@ nsPluginHostImpl::nsPluginHostImpl() mPluginsLoaded = PR_FALSE; mDontShowBadPluginMessage = PR_FALSE; mIsDestroyed = PR_FALSE; - mUnusedLibraries = nsnull; mOverrideInternalTypes = PR_FALSE; mAllowAlienStarHandler = PR_FALSE; + mUnusedLibraries.Clear(); // check to see if pref is set at startup to let plugins take over in // full page mode for certain image mime types that we handle internally @@ -2683,38 +2663,6 @@ PRBool nsPluginHostImpl::IsRunningPlugin(nsPluginTag * plugin) return PR_FALSE; } - -//////////////////////////////////////////////////////////////////////// -void nsPluginHostImpl::AddToUnusedLibraryList(PRLibrary * aLibrary) -{ - NS_ASSERTION(aLibrary, "nsPluginHostImpl::AddToUnusedLibraryList: Nothing to add"); - if(!aLibrary) - return; - - nsUnusedLibrary * unusedLibrary = new nsUnusedLibrary(aLibrary); - if(unusedLibrary) { - unusedLibrary->mNext = mUnusedLibraries; - mUnusedLibraries = unusedLibrary; - } -} - - -//////////////////////////////////////////////////////////////////////// -// this will unload loaded but no longer needed libs which are -// gathered in mUnusedLibraries list, see bug #61388 -void nsPluginHostImpl::CleanUnusedLibraries() -{ - if(!mUnusedLibraries) - return; - - while (nsnull != mUnusedLibraries) { - nsUnusedLibrary *temp = mUnusedLibraries->mNext; - delete mUnusedLibraries; - mUnusedLibraries = temp; - } -} - - //////////////////////////////////////////////////////////////////////// nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages) { @@ -2744,17 +2692,7 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages) return NS_ERROR_PLUGINS_PLUGINSNOTCHANGED; if(reloadPages) { - // if we have currently running plugins we should set a flag not to - // unload them from memory, see bug #61388 - // and form a list of libs to be unloaded later - for(nsPluginTag * p = mPlugins; p != nsnull; p = p->mNext) { - if(IsRunningPlugin(p) && (p->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL)) { - p->mCanUnloadLibrary = PR_FALSE; - AddToUnusedLibraryList(p->mLibrary); - } - } - - // then stop any running plugins + // stop any running plugins mActivePluginList.stopRunning(); } @@ -3346,8 +3284,6 @@ NS_IMETHODIMP nsPluginHostImpl::Destroy(void) mCachedPlugins = next; } - CleanUnusedLibraries(); - // Lets remove any of the temporary files that we created. nsCOMPtr pluginTmp; nsresult rv = NS_GetSpecialDirectory(NS_OS_TEMP_DIR, getter_AddRefs(pluginTmp)); @@ -3366,6 +3302,14 @@ NS_IMETHODIMP nsPluginHostImpl::Destroy(void) mPrivateDirServiceProvider = nsnull; } + // unload any remaining plugin libraries from memory + for (PRInt32 i = 0; i < mUnusedLibraries.Count(); i++) { + PRLibrary * library = (PRLibrary *)mUnusedLibraries[i]; + if (library) + PostPluginUnloadEvent(library); + } + mUnusedLibraries.Clear(); + return NS_OK; } @@ -4494,9 +4438,6 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi if(!aMimeType) return NS_ERROR_ILLEGAL_VALUE; - // unload any libs that can remain after plugins.refresh(1), see #61388 - CleanUnusedLibraries(); - // If plugins haven't been scanned yet, do so now LoadPlugins(); @@ -4527,6 +4468,10 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi if (pluginFile.LoadPlugin(pluginLibrary) != NS_OK || pluginLibrary == NULL) return NS_ERROR_FAILURE; + // remove from unused lib list, if it is there + if (mUnusedLibraries.IndexOf(pluginLibrary) > -1) + mUnusedLibraries.RemoveElement(pluginLibrary); + pluginTag->mLibrary = pluginLibrary; } @@ -4730,6 +4675,7 @@ static nsresult FixUpPluginInfo(nsPluginInfo &aInfo, nsPluginFile &aPluginFile) return NS_ERROR_FAILURE; NP_GETMIMEDESCRIPTION pf = (NP_GETMIMEDESCRIPTION)PR_FindSymbol(library, "NP_GetMIMEDescription"); + if (pf) { // if we found it, this is the default plugin, return char * mimedescription = pf(); @@ -4927,6 +4873,7 @@ nsresult nsPluginHostImpl::ScanPluginsDirectory(nsIFile * pluginsDir, // so if we still want it -- do it if(bAddIt) { + pluginTag->SetHost(this); pluginTag->mNext = mPlugins; mPlugins = pluginTag; @@ -5509,6 +5456,7 @@ nsPluginHostImpl::LoadXPCOMPlugins(nsIComponentManager* aComponentManager, nsIFi continue; } + tag->SetHost(this); tag->mNext = mPlugins; mPlugins = tag; @@ -5581,6 +5529,8 @@ nsPluginHostImpl::LoadCachedPluginsInfo(nsIRegistry* registry) if (NS_FAILED(rv)) continue; + tag->SetHost(this); + // Mark plugin as loaded from cache tag->Mark(NS_PLUGIN_FLAG_FROMCACHE); PR_LOG(nsPluginLogging::gPluginLog, PLUGIN_LOG_BASIC, @@ -5908,11 +5858,7 @@ nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance) if(plugin->mPluginTag) library = plugin->mPluginTag->mLibrary; - PRBool unloadLibLater = PR_FALSE; - mActivePluginList.remove(plugin, &unloadLibLater); - - if(unloadLibLater) - AddToUnusedLibraryList(library); + mActivePluginList.remove(plugin); } else { // if it is allowed to be cached simply stop it, but first we should check @@ -5929,12 +5875,7 @@ nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance) nsActivePlugin * oldest = mActivePluginList.findOldestStopped(); if(oldest != nsnull) { PRLibrary * library = oldest->mPluginTag->mLibrary; - - PRBool unloadLibLater = PR_FALSE; - mActivePluginList.remove(oldest, &unloadLibLater); - - if(unloadLibLater) - AddToUnusedLibraryList(library); + mActivePluginList.remove(oldest); } } } @@ -6575,6 +6516,7 @@ nsPluginHostImpl::ScanForRealInComponentsFolder(nsIComponentManager * aCompManag if (info.fMimeTypeArray) { nsPluginTag *pluginTag = new nsPluginTag(&info); if (pluginTag) { + pluginTag->SetHost(this); pluginTag->mNext = mPlugins; mPlugins = pluginTag; @@ -6592,6 +6534,14 @@ nsPluginHostImpl::ScanForRealInComponentsFolder(nsIComponentManager * aCompManag return rv; } +nsresult nsPluginHostImpl::AddUnusedLibrary(PRLibrary * aLibrary) +{ + if (mUnusedLibraries.IndexOf(aLibrary) == -1) // don't add duplicates + mUnusedLibraries.AppendElement(aLibrary); + + return NS_OK; +} + //////////////////////////////////////////////////////////////////////////////////// nsresult nsPluginStreamListenerPeer::ServeStreamAsFile(nsIRequest *request, nsISupports* aContext) diff --git a/mozilla/modules/plugin/base/src/nsPluginHostImpl.h b/mozilla/modules/plugin/base/src/nsPluginHostImpl.h index 928f5c97519..6f06ddbe61c 100644 --- a/mozilla/modules/plugin/base/src/nsPluginHostImpl.h +++ b/mozilla/modules/plugin/base/src/nsPluginHostImpl.h @@ -60,6 +60,7 @@ class nsIComponentManager; class nsIFile; class nsIChannel; class nsIRegistry; +class nsPluginHostImpl; /** * A linked-list of plugin information that is used for @@ -86,11 +87,13 @@ public: ~nsPluginTag(); + void SetHost(nsPluginHostImpl * aHost); void TryUnloadPlugin(PRBool aForceShutdown = PR_FALSE); void Mark(PRUint32 mask) { mFlags |= mask; } PRBool Equals(nsPluginTag* aPluginTag); nsPluginTag *mNext; + nsPluginHostImpl *mPluginHost; char *mName; char *mDescription; PRInt32 mVariants; @@ -141,7 +144,7 @@ public: void shut(); PRBool add(nsActivePlugin * plugin); - PRBool remove(nsActivePlugin * plugin, PRBool * aUnloadLibraryLater); + PRBool remove(nsActivePlugin * plugin); nsActivePlugin * find(nsIPluginInstance* instance); nsActivePlugin * find(const char * mimetype); nsActivePlugin * findStopped(const char * url); @@ -152,22 +155,6 @@ public: PRBool IsLastInstance(nsActivePlugin * plugin); }; -// The purpose of this list is to keep track of unloaded plugin libs -// we need to keep some libs in memory when we destroy mPlugins list -// during refresh with reload if the plugin is currently running -// on the page. They should be unloaded later, see bug #61388 -// There could also be other reasons to have this list. XPConnected -// plugins e.g. may still be held at the time we normally unload the library -class nsUnusedLibrary -{ -public: - nsUnusedLibrary *mNext; - PRLibrary *mLibrary; - - nsUnusedLibrary(PRLibrary * aLibrary); - ~nsUnusedLibrary(); -}; - #define NS_PLUGIN_FLAG_ENABLED 0x0001 //is this plugin enabled? #define NS_PLUGIN_FLAG_OLDSCHOOL 0x0002 //is this a pre-xpcom plugin? #define NS_PLUGIN_FLAG_FROMCACHE 0x0004 // this plugintag info was loaded from cache @@ -391,6 +378,9 @@ public: NS_IMETHOD StopPluginInstance(nsIPluginInstance* aInstance); + NS_IMETHOD + AddUnusedLibrary(PRLibrary * aLibrary); + private: NS_IMETHOD TrySetUpPluginInstance(const char *aMimeType, nsIURI *aURL, nsIPluginInstanceOwner *aOwner); @@ -441,8 +431,6 @@ private: PRBool checkForUnwantedPlugins = PR_FALSE); PRBool IsRunningPlugin(nsPluginTag * plugin); - void AddToUnusedLibraryList(PRLibrary * aLibrary); - void CleanUnusedLibraries(); // Loads all cached plugins info into mCachedPlugins nsresult LoadCachedPluginsInfo(nsIRegistry* registry); @@ -481,7 +469,7 @@ private: PRBool mAllowAlienStarHandler; // set by pref plugin.allow_alien_star_handler nsActivePluginList mActivePluginList; - nsUnusedLibrary *mUnusedLibraries; + nsVoidArray mUnusedLibraries; nsCOMPtr mPrivateDirServiceProvider; nsWeakPtr mCurrentDocument; // weak reference, we use it only to id document