зеркало из https://github.com/mozilla/pjs.git
Fixing 74485, making shutdown procedures for plugins cleaner, r=sean@beatnik.com, sr=wateson
This commit is contained in:
Родитель
77c84016e1
Коммит
24c981fc83
|
@ -299,14 +299,14 @@ void DisplayNoDefaultPluginDialog(const char *mimeType)
|
|||
return;
|
||||
}
|
||||
|
||||
nsActivePlugin::nsActivePlugin(nsCOMPtr<nsIPlugin> aPlugin,
|
||||
nsActivePlugin::nsActivePlugin(nsPluginTag* aPluginTag,
|
||||
nsIPluginInstance* aInstance,
|
||||
char * url,
|
||||
PRBool aDefaultPlugin)
|
||||
{
|
||||
mNext = nsnull;
|
||||
mPeer = nsnull;
|
||||
mPlugin = aPlugin;
|
||||
mPluginTag = aPluginTag;
|
||||
|
||||
mURL = PL_strdup(url);
|
||||
mInstance = aInstance;
|
||||
|
@ -323,7 +323,7 @@ nsActivePlugin::nsActivePlugin(nsCOMPtr<nsIPlugin> aPlugin,
|
|||
|
||||
nsActivePlugin::~nsActivePlugin()
|
||||
{
|
||||
mPlugin = nsnull;
|
||||
mPluginTag = nsnull;
|
||||
if(mInstance != nsnull)
|
||||
{
|
||||
mInstance->Destroy();
|
||||
|
@ -364,7 +364,11 @@ void nsActivePluginList::shut()
|
|||
for(nsActivePlugin * plugin = mFirst; plugin != nsnull;)
|
||||
{
|
||||
nsActivePlugin * next = plugin->mNext;
|
||||
remove(plugin);
|
||||
|
||||
PRBool unloadLibLater = PR_FALSE;
|
||||
remove(plugin, &unloadLibLater);
|
||||
NS_ASSERTION(!unloadLibLater, "Plugin doesn't want to be unloaded");
|
||||
|
||||
plugin = next;
|
||||
}
|
||||
mFirst = nsnull;
|
||||
|
@ -394,15 +398,18 @@ PRBool nsActivePluginList::IsLastInstance(nsActivePlugin * plugin)
|
|||
if(!plugin)
|
||||
return PR_FALSE;
|
||||
|
||||
if(!plugin->mPluginTag)
|
||||
return PR_FALSE;
|
||||
|
||||
for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
|
||||
{
|
||||
if((p->mPlugin.get() == plugin->mPlugin.get()) && (p != plugin))
|
||||
if((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * lastInstance)
|
||||
PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * aUnloadLibraryLater)
|
||||
{
|
||||
if(mFirst == nsnull)
|
||||
return PR_FALSE;
|
||||
|
@ -412,6 +419,8 @@ PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * lastInstance
|
|||
{
|
||||
if(p == plugin)
|
||||
{
|
||||
PRBool lastInstance = IsLastInstance(p);
|
||||
|
||||
if(p == mFirst)
|
||||
mFirst = p->mNext;
|
||||
else
|
||||
|
@ -421,19 +430,32 @@ PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * lastInstance
|
|||
mLast = prev;
|
||||
|
||||
// see if this is going to be the last instance of a plugin
|
||||
PRBool lastinst = IsLastInstance(p);
|
||||
|
||||
// if so we should perform nsIPlugin::Shutdown and unload the library
|
||||
// by calling nsPluginTag::TryUnloadPlugin()
|
||||
if(lastInstance)
|
||||
*lastInstance = lastinst;
|
||||
|
||||
if(lastinst)
|
||||
{
|
||||
nsIPlugin *nsiplugin = p->mPlugin.get();
|
||||
// cache some things as we are going to destroy it right now
|
||||
nsPluginTag *pluginTag = p->mPluginTag;
|
||||
|
||||
delete p; // plugin instance is destroyed here
|
||||
|
||||
if(nsiplugin)
|
||||
nsiplugin->Shutdown();
|
||||
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");
|
||||
|
||||
}
|
||||
else
|
||||
delete p;
|
||||
|
@ -467,7 +489,6 @@ void nsActivePluginList::removeAllStopped()
|
|||
if(mFirst == nsnull)
|
||||
return;
|
||||
|
||||
nsActivePlugin * prev = nsnull;
|
||||
nsActivePlugin * next = nsnull;
|
||||
|
||||
for(nsActivePlugin * p = mFirst; p != nsnull;)
|
||||
|
@ -476,20 +497,12 @@ void nsActivePluginList::removeAllStopped()
|
|||
|
||||
if(p->mStopped)
|
||||
{
|
||||
if(p == mFirst)
|
||||
mFirst = next;
|
||||
else
|
||||
prev->mNext = next;
|
||||
|
||||
if(p == mLast)
|
||||
mLast = prev;
|
||||
|
||||
delete p;
|
||||
mCount--;
|
||||
p = next;
|
||||
continue;
|
||||
// we don't care about unloading library problem for
|
||||
// plugins that are already in the 'stop' state
|
||||
PRBool unloadLibLater = PR_FALSE;
|
||||
remove(p, &unloadLibLater);
|
||||
}
|
||||
prev = p;
|
||||
|
||||
p = next;
|
||||
}
|
||||
return;
|
||||
|
@ -602,12 +615,12 @@ nsActivePlugin * nsActivePluginList::findOldestStopped()
|
|||
return res;
|
||||
}
|
||||
|
||||
nsUnloadedLibrary::nsUnloadedLibrary(PRLibrary * aLibrary)
|
||||
nsUnusedLibrary::nsUnusedLibrary(PRLibrary * aLibrary)
|
||||
{
|
||||
mLibrary = aLibrary;
|
||||
}
|
||||
|
||||
nsUnloadedLibrary::~nsUnloadedLibrary()
|
||||
nsUnusedLibrary::~nsUnusedLibrary()
|
||||
{
|
||||
if(mLibrary)
|
||||
PR_UnloadLibrary(mLibrary);
|
||||
|
@ -626,6 +639,7 @@ nsPluginTag::nsPluginTag()
|
|||
mCanUnloadLibrary = PR_TRUE;
|
||||
mEntryPoint = nsnull;
|
||||
mFlags = NS_PLUGIN_FLAG_ENABLED;
|
||||
mXPConnected = PR_FALSE;
|
||||
mFileName = nsnull;
|
||||
}
|
||||
|
||||
|
@ -676,6 +690,7 @@ nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
|
|||
mCanUnloadLibrary = PR_TRUE;
|
||||
mEntryPoint = nsnull;
|
||||
mFlags = NS_PLUGIN_FLAG_ENABLED;
|
||||
mXPConnected = PR_FALSE;
|
||||
mFileName = new_str(aPluginTag->mFileName);
|
||||
}
|
||||
|
||||
|
@ -717,6 +732,7 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
|
|||
mCanUnloadLibrary = PR_TRUE;
|
||||
mEntryPoint = nsnull;
|
||||
mFlags = NS_PLUGIN_FLAG_ENABLED;
|
||||
mXPConnected = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -735,7 +751,9 @@ nsPluginTag::nsPluginTag(const char* aName,
|
|||
mLibrary(nsnull),
|
||||
mCanUnloadLibrary(PR_TRUE),
|
||||
mEntryPoint(nsnull),
|
||||
mFlags(0)
|
||||
mFlags(0),
|
||||
mXPConnected(PR_FALSE)
|
||||
|
||||
{
|
||||
mName = new_str(aName);
|
||||
mDescription = new_str(aDescription);
|
||||
|
@ -756,7 +774,7 @@ nsPluginTag::nsPluginTag(const char* aName,
|
|||
|
||||
nsPluginTag::~nsPluginTag()
|
||||
{
|
||||
NS_IF_RELEASE(mEntryPoint);
|
||||
TryUnloadPlugin();
|
||||
|
||||
if (nsnull != mName) {
|
||||
delete[] (mName);
|
||||
|
@ -792,13 +810,6 @@ nsPluginTag::~nsPluginTag()
|
|||
mExtensionsArray = nsnull;
|
||||
}
|
||||
|
||||
if ((nsnull != mLibrary) && mCanUnloadLibrary)
|
||||
{
|
||||
// before we unload check if we are allowed to, see bug #61388
|
||||
PR_UnloadLibrary(mLibrary);
|
||||
mLibrary = nsnull;
|
||||
}
|
||||
|
||||
if(nsnull != mFileName)
|
||||
{
|
||||
delete [] mFileName;
|
||||
|
@ -806,6 +817,26 @@ nsPluginTag::~nsPluginTag()
|
|||
}
|
||||
}
|
||||
|
||||
void nsPluginTag::TryUnloadPlugin()
|
||||
{
|
||||
if (mEntryPoint)
|
||||
{
|
||||
mEntryPoint->Shutdown();
|
||||
mEntryPoint->Release();
|
||||
mEntryPoint = nsnull;
|
||||
}
|
||||
|
||||
// before we unload check if we are allowed to, see bug #61388
|
||||
if (mLibrary && mCanUnloadLibrary)
|
||||
PR_UnloadLibrary(mLibrary);
|
||||
|
||||
// we should zero it anyway, it is going to be unloaded by
|
||||
// CleanUnsedLibraries before we need to call the library
|
||||
// again so the calling code should not be fooled and reload
|
||||
// the library fresh
|
||||
mLibrary = nsnull;
|
||||
}
|
||||
|
||||
class nsPluginStreamInfo : public nsIPluginStreamInfo
|
||||
{
|
||||
public:
|
||||
|
@ -1705,7 +1736,7 @@ nsPluginHostImpl::nsPluginHostImpl()
|
|||
mPluginsLoaded = PR_FALSE;
|
||||
mDontShowBadPluginMessage = PR_FALSE;
|
||||
mIsDestroyed = PR_FALSE;
|
||||
mUnloadedLibraries = nsnull;
|
||||
mUnusedLibraries = nsnull;
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
if (obsService)
|
||||
|
@ -1798,31 +1829,40 @@ PRBool nsPluginHostImpl::IsRunningPlugin(nsPluginTag * plugin)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// this will unload loaded but no longer needed libs which are
|
||||
// gathered in mUnloadedLibraries list, see bug #61388
|
||||
void nsPluginHostImpl::CleanUnloadedLibraries()
|
||||
void nsPluginHostImpl::AddToUnusedLibraryList(PRLibrary * aLibrary)
|
||||
{
|
||||
if(!mUnloadedLibraries)
|
||||
NS_ASSERTION(aLibrary, "nsPluginHostImpl::AddToUnusedLibraryList: Nothing to add");
|
||||
if(!aLibrary)
|
||||
return;
|
||||
|
||||
while (nsnull != mUnloadedLibraries)
|
||||
nsUnusedLibrary * unusedLibrary = new nsUnusedLibrary(aLibrary);
|
||||
if(unusedLibrary)
|
||||
{
|
||||
nsUnloadedLibrary *temp = mUnloadedLibraries->mNext;
|
||||
delete mUnloadedLibraries;
|
||||
mUnloadedLibraries = temp;
|
||||
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)
|
||||
{
|
||||
// XXX don't we want to nuke the old mPlugins right now?
|
||||
// we should. Otherwise LoadPlugins will add the same plugins to the list
|
||||
// XXX for new-style plugins, we should also call nsIComponentManager::AutoRegister()
|
||||
|
||||
// we are re-scanning plugins. New plugins may have been added, also some
|
||||
// plugins may have been removed, so we should probably shut everything down
|
||||
// but don't touch running (active and not stopped) plugins
|
||||
|
||||
if(reloadPages)
|
||||
{
|
||||
// if we have currently running plugins we should set a flag not to
|
||||
|
@ -1830,15 +1870,10 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
|
|||
// and form a list of libs to be unloaded later
|
||||
for(nsPluginTag * p = mPlugins; p != nsnull; p = p->mNext)
|
||||
{
|
||||
if(IsRunningPlugin(p))
|
||||
if(IsRunningPlugin(p) && (p->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL))
|
||||
{
|
||||
p->mCanUnloadLibrary = PR_FALSE;
|
||||
nsUnloadedLibrary * unloadedLibrary = new nsUnloadedLibrary(p->mLibrary);
|
||||
if(unloadedLibrary)
|
||||
{
|
||||
unloadedLibrary->mNext = mUnloadedLibraries;
|
||||
mUnloadedLibraries = unloadedLibrary;
|
||||
}
|
||||
AddToUnusedLibraryList(p->mLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1864,9 +1899,6 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
|
|||
else
|
||||
prev->mNext = next;
|
||||
|
||||
if(p->mEntryPoint)
|
||||
p->mEntryPoint->Shutdown();
|
||||
|
||||
delete p;
|
||||
p = next;
|
||||
continue;
|
||||
|
@ -2393,26 +2425,17 @@ NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
|
|||
{
|
||||
nsPluginTag *temp = mPlugins->mNext;
|
||||
|
||||
// while walking through the list of the plugins see if we still have anything to shutdown
|
||||
// some plugins may have never created an instance but still expect a shutdown call
|
||||
// see bugzilla bug 73071
|
||||
if(mPlugins->mEntryPoint != nsnull)
|
||||
{
|
||||
mPlugins->mEntryPoint->Shutdown();
|
||||
mPlugins->mEntryPoint = nsnull;
|
||||
}
|
||||
|
||||
if ((nsnull != mPlugins->mLibrary) && mPlugins->mCanUnloadLibrary)
|
||||
{
|
||||
PR_UnloadLibrary(mPlugins->mLibrary);
|
||||
mPlugins->mLibrary = nsnull;
|
||||
}
|
||||
// while walking through the list of the plugins see if we still have anything
|
||||
// to shutdown some plugins may have never created an instance but still expect
|
||||
// the shutdown call see bugzilla bug 73071
|
||||
// with current logic, no need to do anything special as nsIPlugin::Shutdown
|
||||
// will be performed in the destructor
|
||||
|
||||
delete mPlugins;
|
||||
mPlugins = temp;
|
||||
}
|
||||
|
||||
CleanUnloadedLibraries();
|
||||
CleanUnusedLibraries();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2706,10 +2729,6 @@ void nsPluginHostImpl::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
|
|||
PRBool aDefaultPlugin)
|
||||
|
||||
{
|
||||
// first, determine if the plugin wants to be cached
|
||||
// Code moved to StopPluginInstance as we still need running
|
||||
// plugins to be present in the 'active' list
|
||||
|
||||
char* url;
|
||||
|
||||
if(!aURL)
|
||||
|
@ -2717,7 +2736,30 @@ void nsPluginHostImpl::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
|
|||
|
||||
(void)aURL->GetSpec(&url);
|
||||
|
||||
nsActivePlugin * plugin = new nsActivePlugin(aPlugin, aInstance, url, aDefaultPlugin);
|
||||
// find corresponding plugin tag
|
||||
// this is legal for xpcom plugins not to have nsIPlugin implemented
|
||||
nsPluginTag * pluginTag = nsnull;
|
||||
if(aPlugin)
|
||||
{
|
||||
for(pluginTag = mPlugins; pluginTag != nsnull; pluginTag = pluginTag->mNext)
|
||||
{
|
||||
if(pluginTag->mEntryPoint == aPlugin)
|
||||
break;
|
||||
}
|
||||
NS_ASSERTION(pluginTag, "Plugin tag not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
// we don't need it for xpcom plugins because the only purpose to have it
|
||||
// is to be able to postpone unloading library dll in some circumstances
|
||||
// which we don't do for xpcom plugins. In case we need it in the future
|
||||
// we can probably use the following
|
||||
/*
|
||||
FindPluginEnabledForType(mimetype, pluginTag);
|
||||
*/
|
||||
}
|
||||
|
||||
nsActivePlugin * plugin = new nsActivePlugin(pluginTag, aInstance, url, aDefaultPlugin);
|
||||
|
||||
if(plugin == nsnull)
|
||||
return;
|
||||
|
@ -3233,7 +3275,7 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
|
|||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
// unload any libs that can remain after plugins.refresh(1), see #61388
|
||||
CleanUnloadedLibraries();
|
||||
CleanUnusedLibraries();
|
||||
|
||||
// If plugins haven't been scanned yet, do so now
|
||||
LoadPlugins();
|
||||
|
@ -4130,42 +4172,25 @@ nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance)
|
|||
aInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCache);
|
||||
|
||||
// we also do that for 4x plugin, shall we? Let's see if it is
|
||||
nsPluginTag * pluginTag = nsnull;
|
||||
PRBool oldSchool = PR_FALSE;
|
||||
for(pluginTag = mPlugins; pluginTag != nsnull; pluginTag = pluginTag->mNext)
|
||||
{
|
||||
if(pluginTag->mEntryPoint == plugin->mPlugin)
|
||||
{
|
||||
oldSchool = pluginTag->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL ? PR_TRUE : PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PRBool oldSchool = PR_TRUE;
|
||||
if(plugin->mPluginTag)
|
||||
oldSchool = plugin->mPluginTag->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL ? PR_TRUE : PR_FALSE;
|
||||
|
||||
if (!doCache || oldSchool)
|
||||
{
|
||||
PRBool lastInstance = PR_FALSE;
|
||||
PRBool xpConnected = plugin->mXPConnected;
|
||||
|
||||
mActivePluginList.remove(plugin, &lastInstance);
|
||||
|
||||
// and if this was the last instance we should unload the library
|
||||
// and clear mEntryPoint and mLibrary member of the pluginTag
|
||||
if(lastInstance)
|
||||
{
|
||||
pluginTag->mEntryPoint = nsnull;
|
||||
PRLibrary * library = plugin->mPluginTag->mLibrary;
|
||||
|
||||
if(xpConnected)
|
||||
pluginTag->mCanUnloadLibrary = PR_FALSE;
|
||||
PRBool unloadLibLater = PR_FALSE;
|
||||
mActivePluginList.remove(plugin, &unloadLibLater);
|
||||
|
||||
if ((nsnull != pluginTag->mLibrary) && pluginTag->mCanUnloadLibrary)
|
||||
{
|
||||
PR_UnloadLibrary(pluginTag->mLibrary);
|
||||
pluginTag->mLibrary = nsnull;
|
||||
if(unloadLibLater)
|
||||
AddToUnusedLibraryList(library);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if it is allowed to be cached simply stop it, but first we should check
|
||||
// if we haven't exceeded the maximum allowed number of cached instances
|
||||
|
||||
// try to get the max cached plugins from a pref or use default
|
||||
PRUint32 max_num;
|
||||
nsresult rv;
|
||||
|
@ -4177,8 +4202,17 @@ nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance)
|
|||
{
|
||||
nsActivePlugin * oldest = mActivePluginList.findOldestStopped();
|
||||
if(oldest != nsnull)
|
||||
mActivePluginList.remove(oldest);
|
||||
{
|
||||
PRLibrary * library = oldest->mPluginTag->mLibrary;
|
||||
|
||||
PRBool unloadLibLater = PR_FALSE;
|
||||
mActivePluginList.remove(oldest, &unloadLibLater);
|
||||
|
||||
if(unloadLibLater)
|
||||
AddToUnusedLibraryList(library);
|
||||
}
|
||||
}
|
||||
|
||||
plugin->setStopped(PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -4372,6 +4406,9 @@ nsPluginHostImpl::SetIsScriptableInstance(nsCOMPtr<nsIPluginInstance> aPluginIns
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
p->mXPConnected = aScriptable;
|
||||
if(p->mPluginTag)
|
||||
p->mPluginTag->mXPConnected = aScriptable;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
|
||||
~nsPluginTag();
|
||||
|
||||
void TryUnloadPlugin();
|
||||
|
||||
nsPluginTag *mNext;
|
||||
char *mName;
|
||||
char *mDescription;
|
||||
|
@ -75,6 +77,7 @@ public:
|
|||
PRBool mCanUnloadLibrary;
|
||||
nsIPlugin *mEntryPoint;
|
||||
PRUint32 mFlags;
|
||||
PRBool mXPConnected;
|
||||
char *mFileName;
|
||||
};
|
||||
|
||||
|
@ -83,14 +86,14 @@ struct nsActivePlugin
|
|||
nsActivePlugin* mNext;
|
||||
char* mURL;
|
||||
nsIPluginInstancePeer* mPeer;
|
||||
nsCOMPtr<nsIPlugin> mPlugin;
|
||||
nsPluginTag* mPluginTag;
|
||||
nsIPluginInstance* mInstance;
|
||||
PRBool mStopped;
|
||||
PRTime mllStopTime;
|
||||
PRBool mDefaultPlugin;
|
||||
PRBool mXPConnected;
|
||||
|
||||
nsActivePlugin(nsCOMPtr<nsIPlugin> aPlugin,
|
||||
nsActivePlugin(nsPluginTag* aPluginTag,
|
||||
nsIPluginInstance* aInstance,
|
||||
char * url,
|
||||
PRBool aDefaultPlugin);
|
||||
|
@ -111,7 +114,7 @@ public:
|
|||
|
||||
void shut();
|
||||
PRBool add(nsActivePlugin * plugin);
|
||||
PRBool remove(nsActivePlugin * plugin, PRBool * lastInstance = nsnull);
|
||||
PRBool remove(nsActivePlugin * plugin, PRBool * aUnloadLibraryLater);
|
||||
nsActivePlugin * find(nsIPluginInstance* instance);
|
||||
nsActivePlugin * find(char * mimetype);
|
||||
nsActivePlugin * findStopped(char * url);
|
||||
|
@ -126,17 +129,16 @@ public:
|
|||
// 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
|
||||
// The list is only created during plugins.refresh(1) and should
|
||||
// go away when we hit a page with a plugin again. It should not
|
||||
// exist under any other circumstances
|
||||
class nsUnloadedLibrary
|
||||
// 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:
|
||||
nsUnloadedLibrary *mNext;
|
||||
nsUnusedLibrary *mNext;
|
||||
PRLibrary *mLibrary;
|
||||
|
||||
nsUnloadedLibrary(PRLibrary * aLibrary);
|
||||
~nsUnloadedLibrary();
|
||||
nsUnusedLibrary(PRLibrary * aLibrary);
|
||||
~nsUnusedLibrary();
|
||||
};
|
||||
|
||||
#define NS_PLUGIN_FLAG_ENABLED 0x0001 //is this plugin enabled?
|
||||
|
@ -406,7 +408,8 @@ private:
|
|||
PRBool checkForUnwantedPlugins = PR_FALSE);
|
||||
|
||||
PRBool IsRunningPlugin(nsPluginTag * plugin);
|
||||
void CleanUnloadedLibraries();
|
||||
void AddToUnusedLibraryList(PRLibrary * aLibrary);
|
||||
void CleanUnusedLibraries();
|
||||
|
||||
char *mPluginPath;
|
||||
nsPluginTag *mPlugins;
|
||||
|
@ -415,7 +418,7 @@ private:
|
|||
PRBool mIsDestroyed;
|
||||
|
||||
nsActivePluginList mActivePluginList;
|
||||
nsUnloadedLibrary *mUnloadedLibraries;
|
||||
nsUnusedLibrary *mUnusedLibraries;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -299,14 +299,14 @@ void DisplayNoDefaultPluginDialog(const char *mimeType)
|
|||
return;
|
||||
}
|
||||
|
||||
nsActivePlugin::nsActivePlugin(nsCOMPtr<nsIPlugin> aPlugin,
|
||||
nsActivePlugin::nsActivePlugin(nsPluginTag* aPluginTag,
|
||||
nsIPluginInstance* aInstance,
|
||||
char * url,
|
||||
PRBool aDefaultPlugin)
|
||||
{
|
||||
mNext = nsnull;
|
||||
mPeer = nsnull;
|
||||
mPlugin = aPlugin;
|
||||
mPluginTag = aPluginTag;
|
||||
|
||||
mURL = PL_strdup(url);
|
||||
mInstance = aInstance;
|
||||
|
@ -323,7 +323,7 @@ nsActivePlugin::nsActivePlugin(nsCOMPtr<nsIPlugin> aPlugin,
|
|||
|
||||
nsActivePlugin::~nsActivePlugin()
|
||||
{
|
||||
mPlugin = nsnull;
|
||||
mPluginTag = nsnull;
|
||||
if(mInstance != nsnull)
|
||||
{
|
||||
mInstance->Destroy();
|
||||
|
@ -364,7 +364,11 @@ void nsActivePluginList::shut()
|
|||
for(nsActivePlugin * plugin = mFirst; plugin != nsnull;)
|
||||
{
|
||||
nsActivePlugin * next = plugin->mNext;
|
||||
remove(plugin);
|
||||
|
||||
PRBool unloadLibLater = PR_FALSE;
|
||||
remove(plugin, &unloadLibLater);
|
||||
NS_ASSERTION(!unloadLibLater, "Plugin doesn't want to be unloaded");
|
||||
|
||||
plugin = next;
|
||||
}
|
||||
mFirst = nsnull;
|
||||
|
@ -394,15 +398,18 @@ PRBool nsActivePluginList::IsLastInstance(nsActivePlugin * plugin)
|
|||
if(!plugin)
|
||||
return PR_FALSE;
|
||||
|
||||
if(!plugin->mPluginTag)
|
||||
return PR_FALSE;
|
||||
|
||||
for(nsActivePlugin * p = mFirst; p != nsnull; p = p->mNext)
|
||||
{
|
||||
if((p->mPlugin.get() == plugin->mPlugin.get()) && (p != plugin))
|
||||
if((p->mPluginTag == plugin->mPluginTag) && (p != plugin))
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * lastInstance)
|
||||
PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * aUnloadLibraryLater)
|
||||
{
|
||||
if(mFirst == nsnull)
|
||||
return PR_FALSE;
|
||||
|
@ -412,6 +419,8 @@ PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * lastInstance
|
|||
{
|
||||
if(p == plugin)
|
||||
{
|
||||
PRBool lastInstance = IsLastInstance(p);
|
||||
|
||||
if(p == mFirst)
|
||||
mFirst = p->mNext;
|
||||
else
|
||||
|
@ -421,19 +430,32 @@ PRBool nsActivePluginList::remove(nsActivePlugin * plugin, PRBool * lastInstance
|
|||
mLast = prev;
|
||||
|
||||
// see if this is going to be the last instance of a plugin
|
||||
PRBool lastinst = IsLastInstance(p);
|
||||
|
||||
// if so we should perform nsIPlugin::Shutdown and unload the library
|
||||
// by calling nsPluginTag::TryUnloadPlugin()
|
||||
if(lastInstance)
|
||||
*lastInstance = lastinst;
|
||||
|
||||
if(lastinst)
|
||||
{
|
||||
nsIPlugin *nsiplugin = p->mPlugin.get();
|
||||
// cache some things as we are going to destroy it right now
|
||||
nsPluginTag *pluginTag = p->mPluginTag;
|
||||
|
||||
delete p; // plugin instance is destroyed here
|
||||
|
||||
if(nsiplugin)
|
||||
nsiplugin->Shutdown();
|
||||
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");
|
||||
|
||||
}
|
||||
else
|
||||
delete p;
|
||||
|
@ -467,7 +489,6 @@ void nsActivePluginList::removeAllStopped()
|
|||
if(mFirst == nsnull)
|
||||
return;
|
||||
|
||||
nsActivePlugin * prev = nsnull;
|
||||
nsActivePlugin * next = nsnull;
|
||||
|
||||
for(nsActivePlugin * p = mFirst; p != nsnull;)
|
||||
|
@ -476,20 +497,12 @@ void nsActivePluginList::removeAllStopped()
|
|||
|
||||
if(p->mStopped)
|
||||
{
|
||||
if(p == mFirst)
|
||||
mFirst = next;
|
||||
else
|
||||
prev->mNext = next;
|
||||
|
||||
if(p == mLast)
|
||||
mLast = prev;
|
||||
|
||||
delete p;
|
||||
mCount--;
|
||||
p = next;
|
||||
continue;
|
||||
// we don't care about unloading library problem for
|
||||
// plugins that are already in the 'stop' state
|
||||
PRBool unloadLibLater = PR_FALSE;
|
||||
remove(p, &unloadLibLater);
|
||||
}
|
||||
prev = p;
|
||||
|
||||
p = next;
|
||||
}
|
||||
return;
|
||||
|
@ -602,12 +615,12 @@ nsActivePlugin * nsActivePluginList::findOldestStopped()
|
|||
return res;
|
||||
}
|
||||
|
||||
nsUnloadedLibrary::nsUnloadedLibrary(PRLibrary * aLibrary)
|
||||
nsUnusedLibrary::nsUnusedLibrary(PRLibrary * aLibrary)
|
||||
{
|
||||
mLibrary = aLibrary;
|
||||
}
|
||||
|
||||
nsUnloadedLibrary::~nsUnloadedLibrary()
|
||||
nsUnusedLibrary::~nsUnusedLibrary()
|
||||
{
|
||||
if(mLibrary)
|
||||
PR_UnloadLibrary(mLibrary);
|
||||
|
@ -626,6 +639,7 @@ nsPluginTag::nsPluginTag()
|
|||
mCanUnloadLibrary = PR_TRUE;
|
||||
mEntryPoint = nsnull;
|
||||
mFlags = NS_PLUGIN_FLAG_ENABLED;
|
||||
mXPConnected = PR_FALSE;
|
||||
mFileName = nsnull;
|
||||
}
|
||||
|
||||
|
@ -676,6 +690,7 @@ nsPluginTag::nsPluginTag(nsPluginTag* aPluginTag)
|
|||
mCanUnloadLibrary = PR_TRUE;
|
||||
mEntryPoint = nsnull;
|
||||
mFlags = NS_PLUGIN_FLAG_ENABLED;
|
||||
mXPConnected = PR_FALSE;
|
||||
mFileName = new_str(aPluginTag->mFileName);
|
||||
}
|
||||
|
||||
|
@ -717,6 +732,7 @@ nsPluginTag::nsPluginTag(nsPluginInfo* aPluginInfo)
|
|||
mCanUnloadLibrary = PR_TRUE;
|
||||
mEntryPoint = nsnull;
|
||||
mFlags = NS_PLUGIN_FLAG_ENABLED;
|
||||
mXPConnected = PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
@ -735,7 +751,9 @@ nsPluginTag::nsPluginTag(const char* aName,
|
|||
mLibrary(nsnull),
|
||||
mCanUnloadLibrary(PR_TRUE),
|
||||
mEntryPoint(nsnull),
|
||||
mFlags(0)
|
||||
mFlags(0),
|
||||
mXPConnected(PR_FALSE)
|
||||
|
||||
{
|
||||
mName = new_str(aName);
|
||||
mDescription = new_str(aDescription);
|
||||
|
@ -756,7 +774,7 @@ nsPluginTag::nsPluginTag(const char* aName,
|
|||
|
||||
nsPluginTag::~nsPluginTag()
|
||||
{
|
||||
NS_IF_RELEASE(mEntryPoint);
|
||||
TryUnloadPlugin();
|
||||
|
||||
if (nsnull != mName) {
|
||||
delete[] (mName);
|
||||
|
@ -792,13 +810,6 @@ nsPluginTag::~nsPluginTag()
|
|||
mExtensionsArray = nsnull;
|
||||
}
|
||||
|
||||
if ((nsnull != mLibrary) && mCanUnloadLibrary)
|
||||
{
|
||||
// before we unload check if we are allowed to, see bug #61388
|
||||
PR_UnloadLibrary(mLibrary);
|
||||
mLibrary = nsnull;
|
||||
}
|
||||
|
||||
if(nsnull != mFileName)
|
||||
{
|
||||
delete [] mFileName;
|
||||
|
@ -806,6 +817,26 @@ nsPluginTag::~nsPluginTag()
|
|||
}
|
||||
}
|
||||
|
||||
void nsPluginTag::TryUnloadPlugin()
|
||||
{
|
||||
if (mEntryPoint)
|
||||
{
|
||||
mEntryPoint->Shutdown();
|
||||
mEntryPoint->Release();
|
||||
mEntryPoint = nsnull;
|
||||
}
|
||||
|
||||
// before we unload check if we are allowed to, see bug #61388
|
||||
if (mLibrary && mCanUnloadLibrary)
|
||||
PR_UnloadLibrary(mLibrary);
|
||||
|
||||
// we should zero it anyway, it is going to be unloaded by
|
||||
// CleanUnsedLibraries before we need to call the library
|
||||
// again so the calling code should not be fooled and reload
|
||||
// the library fresh
|
||||
mLibrary = nsnull;
|
||||
}
|
||||
|
||||
class nsPluginStreamInfo : public nsIPluginStreamInfo
|
||||
{
|
||||
public:
|
||||
|
@ -1705,7 +1736,7 @@ nsPluginHostImpl::nsPluginHostImpl()
|
|||
mPluginsLoaded = PR_FALSE;
|
||||
mDontShowBadPluginMessage = PR_FALSE;
|
||||
mIsDestroyed = PR_FALSE;
|
||||
mUnloadedLibraries = nsnull;
|
||||
mUnusedLibraries = nsnull;
|
||||
|
||||
nsCOMPtr<nsIObserverService> obsService = do_GetService(NS_OBSERVERSERVICE_CONTRACTID);
|
||||
if (obsService)
|
||||
|
@ -1798,31 +1829,40 @@ PRBool nsPluginHostImpl::IsRunningPlugin(nsPluginTag * plugin)
|
|||
return PR_FALSE;
|
||||
}
|
||||
|
||||
// this will unload loaded but no longer needed libs which are
|
||||
// gathered in mUnloadedLibraries list, see bug #61388
|
||||
void nsPluginHostImpl::CleanUnloadedLibraries()
|
||||
void nsPluginHostImpl::AddToUnusedLibraryList(PRLibrary * aLibrary)
|
||||
{
|
||||
if(!mUnloadedLibraries)
|
||||
NS_ASSERTION(aLibrary, "nsPluginHostImpl::AddToUnusedLibraryList: Nothing to add");
|
||||
if(!aLibrary)
|
||||
return;
|
||||
|
||||
while (nsnull != mUnloadedLibraries)
|
||||
nsUnusedLibrary * unusedLibrary = new nsUnusedLibrary(aLibrary);
|
||||
if(unusedLibrary)
|
||||
{
|
||||
nsUnloadedLibrary *temp = mUnloadedLibraries->mNext;
|
||||
delete mUnloadedLibraries;
|
||||
mUnloadedLibraries = temp;
|
||||
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)
|
||||
{
|
||||
// XXX don't we want to nuke the old mPlugins right now?
|
||||
// we should. Otherwise LoadPlugins will add the same plugins to the list
|
||||
// XXX for new-style plugins, we should also call nsIComponentManager::AutoRegister()
|
||||
|
||||
// we are re-scanning plugins. New plugins may have been added, also some
|
||||
// plugins may have been removed, so we should probably shut everything down
|
||||
// but don't touch running (active and not stopped) plugins
|
||||
|
||||
if(reloadPages)
|
||||
{
|
||||
// if we have currently running plugins we should set a flag not to
|
||||
|
@ -1830,15 +1870,10 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
|
|||
// and form a list of libs to be unloaded later
|
||||
for(nsPluginTag * p = mPlugins; p != nsnull; p = p->mNext)
|
||||
{
|
||||
if(IsRunningPlugin(p))
|
||||
if(IsRunningPlugin(p) && (p->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL))
|
||||
{
|
||||
p->mCanUnloadLibrary = PR_FALSE;
|
||||
nsUnloadedLibrary * unloadedLibrary = new nsUnloadedLibrary(p->mLibrary);
|
||||
if(unloadedLibrary)
|
||||
{
|
||||
unloadedLibrary->mNext = mUnloadedLibraries;
|
||||
mUnloadedLibraries = unloadedLibrary;
|
||||
}
|
||||
AddToUnusedLibraryList(p->mLibrary);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1864,9 +1899,6 @@ nsresult nsPluginHostImpl::ReloadPlugins(PRBool reloadPages)
|
|||
else
|
||||
prev->mNext = next;
|
||||
|
||||
if(p->mEntryPoint)
|
||||
p->mEntryPoint->Shutdown();
|
||||
|
||||
delete p;
|
||||
p = next;
|
||||
continue;
|
||||
|
@ -2393,26 +2425,17 @@ NS_IMETHODIMP nsPluginHostImpl::Destroy(void)
|
|||
{
|
||||
nsPluginTag *temp = mPlugins->mNext;
|
||||
|
||||
// while walking through the list of the plugins see if we still have anything to shutdown
|
||||
// some plugins may have never created an instance but still expect a shutdown call
|
||||
// see bugzilla bug 73071
|
||||
if(mPlugins->mEntryPoint != nsnull)
|
||||
{
|
||||
mPlugins->mEntryPoint->Shutdown();
|
||||
mPlugins->mEntryPoint = nsnull;
|
||||
}
|
||||
|
||||
if ((nsnull != mPlugins->mLibrary) && mPlugins->mCanUnloadLibrary)
|
||||
{
|
||||
PR_UnloadLibrary(mPlugins->mLibrary);
|
||||
mPlugins->mLibrary = nsnull;
|
||||
}
|
||||
// while walking through the list of the plugins see if we still have anything
|
||||
// to shutdown some plugins may have never created an instance but still expect
|
||||
// the shutdown call see bugzilla bug 73071
|
||||
// with current logic, no need to do anything special as nsIPlugin::Shutdown
|
||||
// will be performed in the destructor
|
||||
|
||||
delete mPlugins;
|
||||
mPlugins = temp;
|
||||
}
|
||||
|
||||
CleanUnloadedLibraries();
|
||||
CleanUnusedLibraries();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -2706,10 +2729,6 @@ void nsPluginHostImpl::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
|
|||
PRBool aDefaultPlugin)
|
||||
|
||||
{
|
||||
// first, determine if the plugin wants to be cached
|
||||
// Code moved to StopPluginInstance as we still need running
|
||||
// plugins to be present in the 'active' list
|
||||
|
||||
char* url;
|
||||
|
||||
if(!aURL)
|
||||
|
@ -2717,7 +2736,30 @@ void nsPluginHostImpl::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
|
|||
|
||||
(void)aURL->GetSpec(&url);
|
||||
|
||||
nsActivePlugin * plugin = new nsActivePlugin(aPlugin, aInstance, url, aDefaultPlugin);
|
||||
// find corresponding plugin tag
|
||||
// this is legal for xpcom plugins not to have nsIPlugin implemented
|
||||
nsPluginTag * pluginTag = nsnull;
|
||||
if(aPlugin)
|
||||
{
|
||||
for(pluginTag = mPlugins; pluginTag != nsnull; pluginTag = pluginTag->mNext)
|
||||
{
|
||||
if(pluginTag->mEntryPoint == aPlugin)
|
||||
break;
|
||||
}
|
||||
NS_ASSERTION(pluginTag, "Plugin tag not found");
|
||||
}
|
||||
else
|
||||
{
|
||||
// we don't need it for xpcom plugins because the only purpose to have it
|
||||
// is to be able to postpone unloading library dll in some circumstances
|
||||
// which we don't do for xpcom plugins. In case we need it in the future
|
||||
// we can probably use the following
|
||||
/*
|
||||
FindPluginEnabledForType(mimetype, pluginTag);
|
||||
*/
|
||||
}
|
||||
|
||||
nsActivePlugin * plugin = new nsActivePlugin(pluginTag, aInstance, url, aDefaultPlugin);
|
||||
|
||||
if(plugin == nsnull)
|
||||
return;
|
||||
|
@ -3233,7 +3275,7 @@ NS_IMETHODIMP nsPluginHostImpl::GetPluginFactory(const char *aMimeType, nsIPlugi
|
|||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
|
||||
// unload any libs that can remain after plugins.refresh(1), see #61388
|
||||
CleanUnloadedLibraries();
|
||||
CleanUnusedLibraries();
|
||||
|
||||
// If plugins haven't been scanned yet, do so now
|
||||
LoadPlugins();
|
||||
|
@ -4130,42 +4172,25 @@ nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance)
|
|||
aInstance->GetValue(nsPluginInstanceVariable_DoCacheBool, (void *) &doCache);
|
||||
|
||||
// we also do that for 4x plugin, shall we? Let's see if it is
|
||||
nsPluginTag * pluginTag = nsnull;
|
||||
PRBool oldSchool = PR_FALSE;
|
||||
for(pluginTag = mPlugins; pluginTag != nsnull; pluginTag = pluginTag->mNext)
|
||||
{
|
||||
if(pluginTag->mEntryPoint == plugin->mPlugin)
|
||||
{
|
||||
oldSchool = pluginTag->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL ? PR_TRUE : PR_FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PRBool oldSchool = PR_TRUE;
|
||||
if(plugin->mPluginTag)
|
||||
oldSchool = plugin->mPluginTag->mFlags & NS_PLUGIN_FLAG_OLDSCHOOL ? PR_TRUE : PR_FALSE;
|
||||
|
||||
if (!doCache || oldSchool)
|
||||
{
|
||||
PRBool lastInstance = PR_FALSE;
|
||||
PRBool xpConnected = plugin->mXPConnected;
|
||||
|
||||
mActivePluginList.remove(plugin, &lastInstance);
|
||||
|
||||
// and if this was the last instance we should unload the library
|
||||
// and clear mEntryPoint and mLibrary member of the pluginTag
|
||||
if(lastInstance)
|
||||
{
|
||||
pluginTag->mEntryPoint = nsnull;
|
||||
PRLibrary * library = plugin->mPluginTag->mLibrary;
|
||||
|
||||
if(xpConnected)
|
||||
pluginTag->mCanUnloadLibrary = PR_FALSE;
|
||||
PRBool unloadLibLater = PR_FALSE;
|
||||
mActivePluginList.remove(plugin, &unloadLibLater);
|
||||
|
||||
if ((nsnull != pluginTag->mLibrary) && pluginTag->mCanUnloadLibrary)
|
||||
{
|
||||
PR_UnloadLibrary(pluginTag->mLibrary);
|
||||
pluginTag->mLibrary = nsnull;
|
||||
if(unloadLibLater)
|
||||
AddToUnusedLibraryList(library);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if it is allowed to be cached simply stop it, but first we should check
|
||||
// if we haven't exceeded the maximum allowed number of cached instances
|
||||
|
||||
// try to get the max cached plugins from a pref or use default
|
||||
PRUint32 max_num;
|
||||
nsresult rv;
|
||||
|
@ -4177,8 +4202,17 @@ nsPluginHostImpl::StopPluginInstance(nsIPluginInstance* aInstance)
|
|||
{
|
||||
nsActivePlugin * oldest = mActivePluginList.findOldestStopped();
|
||||
if(oldest != nsnull)
|
||||
mActivePluginList.remove(oldest);
|
||||
{
|
||||
PRLibrary * library = oldest->mPluginTag->mLibrary;
|
||||
|
||||
PRBool unloadLibLater = PR_FALSE;
|
||||
mActivePluginList.remove(oldest, &unloadLibLater);
|
||||
|
||||
if(unloadLibLater)
|
||||
AddToUnusedLibraryList(library);
|
||||
}
|
||||
}
|
||||
|
||||
plugin->setStopped(PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
@ -4372,6 +4406,9 @@ nsPluginHostImpl::SetIsScriptableInstance(nsCOMPtr<nsIPluginInstance> aPluginIns
|
|||
return NS_ERROR_FAILURE;
|
||||
|
||||
p->mXPConnected = aScriptable;
|
||||
if(p->mPluginTag)
|
||||
p->mPluginTag->mXPConnected = aScriptable;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
|
||||
~nsPluginTag();
|
||||
|
||||
void TryUnloadPlugin();
|
||||
|
||||
nsPluginTag *mNext;
|
||||
char *mName;
|
||||
char *mDescription;
|
||||
|
@ -75,6 +77,7 @@ public:
|
|||
PRBool mCanUnloadLibrary;
|
||||
nsIPlugin *mEntryPoint;
|
||||
PRUint32 mFlags;
|
||||
PRBool mXPConnected;
|
||||
char *mFileName;
|
||||
};
|
||||
|
||||
|
@ -83,14 +86,14 @@ struct nsActivePlugin
|
|||
nsActivePlugin* mNext;
|
||||
char* mURL;
|
||||
nsIPluginInstancePeer* mPeer;
|
||||
nsCOMPtr<nsIPlugin> mPlugin;
|
||||
nsPluginTag* mPluginTag;
|
||||
nsIPluginInstance* mInstance;
|
||||
PRBool mStopped;
|
||||
PRTime mllStopTime;
|
||||
PRBool mDefaultPlugin;
|
||||
PRBool mXPConnected;
|
||||
|
||||
nsActivePlugin(nsCOMPtr<nsIPlugin> aPlugin,
|
||||
nsActivePlugin(nsPluginTag* aPluginTag,
|
||||
nsIPluginInstance* aInstance,
|
||||
char * url,
|
||||
PRBool aDefaultPlugin);
|
||||
|
@ -111,7 +114,7 @@ public:
|
|||
|
||||
void shut();
|
||||
PRBool add(nsActivePlugin * plugin);
|
||||
PRBool remove(nsActivePlugin * plugin, PRBool * lastInstance = nsnull);
|
||||
PRBool remove(nsActivePlugin * plugin, PRBool * aUnloadLibraryLater);
|
||||
nsActivePlugin * find(nsIPluginInstance* instance);
|
||||
nsActivePlugin * find(char * mimetype);
|
||||
nsActivePlugin * findStopped(char * url);
|
||||
|
@ -126,17 +129,16 @@ public:
|
|||
// 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
|
||||
// The list is only created during plugins.refresh(1) and should
|
||||
// go away when we hit a page with a plugin again. It should not
|
||||
// exist under any other circumstances
|
||||
class nsUnloadedLibrary
|
||||
// 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:
|
||||
nsUnloadedLibrary *mNext;
|
||||
nsUnusedLibrary *mNext;
|
||||
PRLibrary *mLibrary;
|
||||
|
||||
nsUnloadedLibrary(PRLibrary * aLibrary);
|
||||
~nsUnloadedLibrary();
|
||||
nsUnusedLibrary(PRLibrary * aLibrary);
|
||||
~nsUnusedLibrary();
|
||||
};
|
||||
|
||||
#define NS_PLUGIN_FLAG_ENABLED 0x0001 //is this plugin enabled?
|
||||
|
@ -406,7 +408,8 @@ private:
|
|||
PRBool checkForUnwantedPlugins = PR_FALSE);
|
||||
|
||||
PRBool IsRunningPlugin(nsPluginTag * plugin);
|
||||
void CleanUnloadedLibraries();
|
||||
void AddToUnusedLibraryList(PRLibrary * aLibrary);
|
||||
void CleanUnusedLibraries();
|
||||
|
||||
char *mPluginPath;
|
||||
nsPluginTag *mPlugins;
|
||||
|
@ -415,7 +418,7 @@ private:
|
|||
PRBool mIsDestroyed;
|
||||
|
||||
nsActivePluginList mActivePluginList;
|
||||
nsUnloadedLibrary *mUnloadedLibraries;
|
||||
nsUnusedLibrary *mUnusedLibraries;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче