Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Bug 700835 - Restore plugin caching to work around bad crash in lates…

…t Apple Java updates. r=josh a=akeybl
  • Loading branch information...
commit 2741cc517a8a45ba8d286e4c5173c8160cbba927 1 parent d7d8529
@steven-michaud steven-michaud authored
View
5 dom/plugins/base/nsNPAPIPlugin.cpp
@@ -2480,9 +2480,8 @@ _setvalue(NPP npp, NPPVariable variable, void *result)
}
case NPPVpluginKeepLibraryInMemory: {
- // This variable is not supported any more but we'll pretend it is
- // so that plugins don't fail on an error return.
- return NS_OK;
+ NPBool bCached = (result != nsnull);
+ return inst->SetCached(bCached);
}
case NPPVpluginUsesDOMForCursorBool: {
View
21 dom/plugins/base/nsNPAPIPluginInstance.cpp
@@ -95,6 +95,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(nsNPAPIPlugin* plugin)
mWindowless(PR_FALSE),
mWindowlessLocal(PR_FALSE),
mTransparent(PR_FALSE),
+ mCached(PR_FALSE),
mUsesDOMForCursor(PR_FALSE),
mInPluginInitCall(PR_FALSE),
mPlugin(plugin),
@@ -142,6 +143,12 @@ nsNPAPIPluginInstance::Destroy()
mPlugin = nsnull;
}
+TimeStamp
+nsNPAPIPluginInstance::StopTime()
+{
+ return mStopTime;
+}
+
nsresult nsNPAPIPluginInstance::Initialize(nsIPluginInstanceOwner* aOwner, const char* aMIMEType)
{
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Initialize this=%p\n",this));
@@ -200,6 +207,7 @@ nsresult nsNPAPIPluginInstance::Stop()
{
AsyncCallbackAutoLock lock;
mRunning = DESTROYING;
+ mStopTime = TimeStamp::Now();
}
OnPluginDestroy(&mNPP);
@@ -874,6 +882,19 @@ nsNPAPIPluginInstance::DefineJavaProperties()
}
nsresult
+nsNPAPIPluginInstance::SetCached(PRBool aCache)
+{
+ mCached = aCache;
+ return NS_OK;
+}
+
+PRBool
+nsNPAPIPluginInstance::ShouldCache()
+{
+ return mCached;
+}
+
+nsresult
nsNPAPIPluginInstance::IsWindowless(PRBool* isWindowless)
{
#ifdef ANDROID
View
12 dom/plugins/base/nsNPAPIPluginInstance.h
@@ -95,6 +95,7 @@ class nsNPAPIPluginInstance : public nsISupports
nsresult IsRemoteDrawingCoreAnimation(PRBool* aDrawing);
nsresult GetJSObject(JSContext *cx, JSObject** outObject);
nsresult DefineJavaProperties();
+ PRBool ShouldCache();
nsresult IsWindowless(PRBool* isWindowless);
nsresult AsyncSetWindow(NPWindow* window);
nsresult GetImage(ImageContainer* aContainer, Image** aImage);
@@ -173,6 +174,12 @@ class nsNPAPIPluginInstance : public nsISupports
return mRunning == RUNNING || mRunning == DESTROYING;
}
+ // return is only valid when the plugin is not running
+ mozilla::TimeStamp StopTime();
+
+ // cache this NPAPI plugin
+ nsresult SetCached(PRBool aCache);
+
already_AddRefed<nsPIDOMWindow> GetDOMWindow();
nsresult PrivateModeStateChanged();
@@ -232,6 +239,7 @@ class nsNPAPIPluginInstance : public nsISupports
PRPackedBool mWindowless;
PRPackedBool mWindowlessLocal;
PRPackedBool mTransparent;
+ PRPackedBool mCached;
PRPackedBool mUsesDOMForCursor;
public:
@@ -260,6 +268,10 @@ class nsNPAPIPluginInstance : public nsISupports
// non-null during a HandleEvent call
void* mCurrentPluginEvent;
+ // Timestamp for the last time this plugin was stopped.
+ // This is only valid when the plugin is actually stopped!
+ mozilla::TimeStamp mStopTime;
+
nsCOMPtr<nsIURI> mURI;
PRPackedBool mUsePluginLayersPref;
View
67 dom/plugins/base/nsPluginHost.cpp
@@ -230,6 +230,10 @@ PRLogModuleInfo* nsPluginLogging::gPluginLog = nsnull;
#define BRAND_PROPERTIES_URL "chrome://branding/locale/brand.properties"
#define PLUGIN_PROPERTIES_URL "chrome://global/locale/downloadProgress.properties"
+// #defines for plugin cache and prefs
+#define NS_PREF_MAX_NUM_CACHED_INSTANCES "browser.plugins.max_num_cached_plugins"
+#define DEFAULT_NUMBER_OF_STOPPED_INSTANCES 10
+
#ifdef CALL_SAFETY_ON
// By default we run OOPP, so we don't want to cover up crashes.
PRBool gSkipPluginSafeCalls = PR_TRUE;
@@ -3198,13 +3202,34 @@ nsPluginHost::StopPluginInstance(nsNPAPIPluginInstance* aInstance)
return NS_OK;
}
- nsPluginTag* pluginTag = TagForPlugin(aInstance->GetPlugin());
-
aInstance->Stop();
- aInstance->Destroy();
- mInstances.RemoveElement(aInstance);
- OnPluginInstanceDestroyed(pluginTag);
+ // if the instance does not want to be 'cached' just remove it
+ PRBool doCache = aInstance->ShouldCache();
+ if (doCache) {
+ // try to get the max cached instances from a pref or use default
+ PRUint32 cachedInstanceLimit;
+ nsresult rv = NS_ERROR_FAILURE;
+ if (mPrefService)
+ rv = mPrefService->GetIntPref(NS_PREF_MAX_NUM_CACHED_INSTANCES, (int*)&cachedInstanceLimit);
+ if (NS_FAILED(rv))
+ cachedInstanceLimit = DEFAULT_NUMBER_OF_STOPPED_INSTANCES;
+
+ if (StoppedInstanceCount() >= cachedInstanceLimit) {
+ nsNPAPIPluginInstance *oldestInstance = FindOldestStoppedInstance();
+ if (oldestInstance) {
+ nsPluginTag* pluginTag = TagForPlugin(oldestInstance->GetPlugin());
+ oldestInstance->Destroy();
+ mInstances.RemoveElement(oldestInstance);
+ OnPluginInstanceDestroyed(pluginTag);
+ }
+ }
+ } else {
+ nsPluginTag* pluginTag = TagForPlugin(aInstance->GetPlugin());
+ aInstance->Destroy();
+ mInstances.RemoveElement(aInstance);
+ OnPluginInstanceDestroyed(pluginTag);
+ }
return NS_OK;
}
@@ -3930,6 +3955,38 @@ nsPluginHost::FindInstance(const char *mimetype)
return nsnull;
}
+nsNPAPIPluginInstance*
+nsPluginHost::FindOldestStoppedInstance()
+{
+ nsNPAPIPluginInstance *oldestInstance = nsnull;
+ TimeStamp oldestTime = TimeStamp::Now();
+ for (PRUint32 i = 0; i < mInstances.Length(); i++) {
+ nsNPAPIPluginInstance *instance = mInstances[i];
+ if (instance->IsRunning())
+ continue;
+
+ TimeStamp time = instance->StopTime();
+ if (time < oldestTime) {
+ oldestTime = time;
+ oldestInstance = instance;
+ }
+ }
+
+ return oldestInstance;
+}
+
+PRUint32
+nsPluginHost::StoppedInstanceCount()
+{
+ PRUint32 stoppedCount = 0;
+ for (PRUint32 i = 0; i < mInstances.Length(); i++) {
+ nsNPAPIPluginInstance *instance = mInstances[i];
+ if (!instance->IsRunning())
+ stoppedCount++;
+ }
+ return stoppedCount;
+}
+
nsTArray< nsRefPtr<nsNPAPIPluginInstance> >*
nsPluginHost::InstanceArray()
{
View
2  dom/plugins/base/nsPluginHost.h
@@ -205,6 +205,8 @@ class nsPluginHost : public nsIPluginHost,
const nsAString& browserDumpID);
nsNPAPIPluginInstance *FindInstance(const char *mimetype);
+ nsNPAPIPluginInstance *FindOldestStoppedInstance();
+ PRUint32 StoppedInstanceCount();
nsTArray< nsRefPtr<nsNPAPIPluginInstance> > *InstanceArray();
Please sign in to comment.
Something went wrong with that request. Please try again.