mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Improve plugin instance stopped/started state management. b=535660 r=roc
This commit is contained in:
parent
f59fcf5bcb
commit
ac8d51b495
@ -889,7 +889,7 @@ nsPluginThreadRunnable::nsPluginThreadRunnable(NPP instance,
|
||||
nsAutoLock lock(sPluginThreadAsyncCallLock);
|
||||
|
||||
nsNPAPIPluginInstance *inst = (nsNPAPIPluginInstance *)instance->ndata;
|
||||
if (!inst || !inst->IsStarted()) {
|
||||
if (!inst || !inst->IsRunning()) {
|
||||
// The plugin was stopped, ignore this async call.
|
||||
mFunc = nsnull;
|
||||
|
||||
|
@ -58,6 +58,7 @@
|
||||
#include "nsJSNPRuntime.h"
|
||||
|
||||
using namespace mozilla::plugins::parent;
|
||||
using mozilla::TimeStamp;
|
||||
|
||||
static NS_DEFINE_IID(kIPluginStreamListenerIID, NS_IPLUGINSTREAMLISTENER_IID);
|
||||
|
||||
@ -255,7 +256,7 @@ nsresult nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason)
|
||||
if (mStreamCleanedUp)
|
||||
return NS_OK;
|
||||
|
||||
if (!mInst || !mInst->IsStarted())
|
||||
if (!mInst || !mInst->IsRunning())
|
||||
return rv;
|
||||
|
||||
PluginDestructionGuard guard(mInst);
|
||||
@ -297,7 +298,7 @@ nsresult nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason)
|
||||
|
||||
void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason)
|
||||
{
|
||||
if (!mCallNotify || !mInst || !mInst->IsStarted())
|
||||
if (!mCallNotify || !mInst || !mInst->IsRunning())
|
||||
return;
|
||||
|
||||
PluginDestructionGuard guard(mInst);
|
||||
@ -336,7 +337,7 @@ nsNPAPIPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
|
||||
mInst->GetCallbacks(&callbacks);
|
||||
mInst->GetNPP(&npp);
|
||||
|
||||
if (!callbacks || !mInst->IsStarted())
|
||||
if (!callbacks || !mInst->IsRunning())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PRBool seekable;
|
||||
@ -479,7 +480,7 @@ nsNPAPIPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
nsIInputStream* input,
|
||||
PRUint32 length)
|
||||
{
|
||||
if (!mInst || !mInst->IsStarted())
|
||||
if (!mInst || !mInst->IsRunning())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PluginDestructionGuard guard(mInst);
|
||||
@ -744,7 +745,7 @@ NS_IMETHODIMP
|
||||
nsNPAPIPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo,
|
||||
const char* fileName)
|
||||
{
|
||||
if (!mInst || !mInst->IsStarted())
|
||||
if (!mInst || !mInst->IsRunning())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
PluginDestructionGuard guard(mInst);
|
||||
@ -787,7 +788,7 @@ nsNPAPIPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo,
|
||||
}
|
||||
}
|
||||
|
||||
if (!mInst || !mInst->IsStarted())
|
||||
if (!mInst || !mInst->IsRunning())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// check if the stream is of seekable type and later its destruction
|
||||
@ -889,7 +890,7 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks,
|
||||
mWindowless(PR_FALSE),
|
||||
mWindowlessLocal(PR_FALSE),
|
||||
mTransparent(PR_FALSE),
|
||||
mStarted(PR_FALSE),
|
||||
mRunning(PR_FALSE),
|
||||
mCached(PR_FALSE),
|
||||
mWantsAllNetworkStreams(PR_FALSE),
|
||||
mInPluginInitCall(PR_FALSE),
|
||||
@ -927,9 +928,15 @@ nsNPAPIPluginInstance::~nsNPAPIPluginInstance(void)
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsNPAPIPluginInstance::IsStarted(void)
|
||||
nsNPAPIPluginInstance::IsRunning()
|
||||
{
|
||||
return mStarted;
|
||||
return mRunning;
|
||||
}
|
||||
|
||||
TimeStamp
|
||||
nsNPAPIPluginInstance::LastStopTime()
|
||||
{
|
||||
return mStopTime;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::Initialize(nsIPluginInstanceOwner* aOwner, const char* aMIMEType)
|
||||
@ -948,17 +955,17 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Initialize(nsIPluginInstanceOwner* aOwner,
|
||||
return InitializePlugin();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::Start(void)
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::Start()
|
||||
{
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Start this=%p\n",this));
|
||||
|
||||
if (mStarted)
|
||||
if (mRunning)
|
||||
return NS_OK;
|
||||
|
||||
return InitializePlugin();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::Stop(void)
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::Stop()
|
||||
{
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance::Stop this=%p\n",this));
|
||||
|
||||
@ -973,7 +980,7 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Stop(void)
|
||||
}
|
||||
}
|
||||
|
||||
if (!mStarted) {
|
||||
if (!mRunning) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -987,10 +994,11 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Stop(void)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Make sure we lock while we're writing to mStarted after we've
|
||||
// Make sure we lock while we're writing to mRunning after we've
|
||||
// started as other threads might be checking that inside a lock.
|
||||
EnterAsyncPluginThreadCallLock();
|
||||
mStarted = PR_FALSE;
|
||||
mRunning = PR_FALSE;
|
||||
mStopTime = TimeStamp::Now();
|
||||
ExitAsyncPluginThreadCallLock();
|
||||
|
||||
OnPluginDestroy(&mNPP);
|
||||
@ -1188,10 +1196,10 @@ nsNPAPIPluginInstance::InitializePlugin()
|
||||
}
|
||||
}
|
||||
|
||||
// Mark this instance as started before calling NPP_New because the plugin may
|
||||
// Mark this instance as running before calling NPP_New because the plugin may
|
||||
// call other NPAPI functions, like NPN_GetURLNotify, that assume this is set
|
||||
// before returning. If the plugin returns failure, we'll clear it out below.
|
||||
mStarted = PR_TRUE;
|
||||
mRunning = PR_TRUE;
|
||||
|
||||
PRBool oldVal = mInPluginInitCall;
|
||||
mInPluginInitCall = PR_TRUE;
|
||||
@ -1200,8 +1208,10 @@ nsNPAPIPluginInstance::InitializePlugin()
|
||||
// the plugin may make could fail (NPN_HasProperty, for example).
|
||||
NPPAutoPusher autopush(&mNPP);
|
||||
nsresult newResult = mLibrary->NPP_New((char*)mimetype, &mNPP, (PRUint16)mode, count, (char**)names, (char**)values, NULL, &error);
|
||||
if (NS_FAILED(newResult))
|
||||
if (NS_FAILED(newResult)) {
|
||||
mRunning = PR_FALSE;
|
||||
return newResult;
|
||||
}
|
||||
|
||||
mInPluginInitCall = oldVal;
|
||||
|
||||
@ -1210,7 +1220,7 @@ nsNPAPIPluginInstance::InitializePlugin()
|
||||
this, &mNPP, mimetype, mode, count, error));
|
||||
|
||||
if (error != NPERR_NO_ERROR) {
|
||||
mStarted = PR_FALSE;
|
||||
mRunning = PR_FALSE;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -1220,7 +1230,7 @@ nsNPAPIPluginInstance::InitializePlugin()
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::SetWindow(NPWindow* window)
|
||||
{
|
||||
// NPAPI plugins don't want a SetWindow(NULL).
|
||||
if (!window || !mStarted)
|
||||
if (!window || !mRunning)
|
||||
return NS_OK;
|
||||
|
||||
#if defined(MOZ_WIDGET_GTK2)
|
||||
@ -1352,7 +1362,7 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Print(NPPrint* platformPrint)
|
||||
|
||||
NS_IMETHODIMP nsNPAPIPluginInstance::HandleEvent(void* event, PRBool* handled)
|
||||
{
|
||||
if (!mStarted)
|
||||
if (!mRunning)
|
||||
return NS_OK;
|
||||
|
||||
if (!event)
|
||||
@ -1391,7 +1401,7 @@ NS_IMETHODIMP nsNPAPIPluginInstance::GetValueFromPlugin(NPPVariable variable, vo
|
||||
}
|
||||
#endif
|
||||
nsresult res = NS_OK;
|
||||
if (mCallbacks->getvalue && mStarted) {
|
||||
if (mCallbacks->getvalue && mRunning) {
|
||||
PluginDestructionGuard guard(this);
|
||||
|
||||
NS_TRY_SAFE_CALL_RETURN(res, (*mCallbacks->getvalue)(&mNPP, variable, value), mLibrary, this);
|
||||
@ -1651,7 +1661,7 @@ nsNPAPIPluginInstance::GetPluginAPIVersion(PRUint16* version)
|
||||
nsresult
|
||||
nsNPAPIPluginInstance::PrivateModeStateChanged()
|
||||
{
|
||||
if (!mStarted)
|
||||
if (!mRunning)
|
||||
return NS_OK;
|
||||
|
||||
PLUGIN_LOG(PLUGIN_LOG_NORMAL, ("nsNPAPIPluginInstance informing plugin of private mode state change this=%p\n",this));
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIPluginInstanceOwner.h"
|
||||
#include "nsITimer.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#include "npfunctions.h"
|
||||
#include "mozilla/PluginLibrary.h"
|
||||
@ -111,7 +112,10 @@ public:
|
||||
virtual ~nsNPAPIPluginInstance();
|
||||
|
||||
// returns the state of mStarted
|
||||
PRBool IsStarted();
|
||||
PRBool IsRunning();
|
||||
|
||||
// return is only valid when the plugin is not running
|
||||
mozilla::TimeStamp LastStopTime();
|
||||
|
||||
// cache this NPAPI plugin
|
||||
nsresult SetCached(PRBool aCache);
|
||||
@ -155,7 +159,7 @@ protected:
|
||||
PRPackedBool mWindowless;
|
||||
PRPackedBool mWindowlessLocal;
|
||||
PRPackedBool mTransparent;
|
||||
PRPackedBool mStarted;
|
||||
PRPackedBool mRunning;
|
||||
PRPackedBool mCached;
|
||||
PRPackedBool mWantsAllNetworkStreams;
|
||||
|
||||
@ -178,6 +182,10 @@ private:
|
||||
|
||||
// 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;
|
||||
};
|
||||
|
||||
#endif // nsNPAPIPluginInstance_h_
|
||||
|
@ -1799,7 +1799,7 @@ PRBool nsPluginHost::IsRunningPlugin(nsPluginTag * plugin)
|
||||
|
||||
for (int i = 0; i < plugin->mVariants; i++) {
|
||||
nsPluginInstanceTag * p = mPluginInstanceTagList.find(plugin->mMimeTypeArray[i]);
|
||||
if (p && !p->mStopped)
|
||||
if (p && p->mInstance->IsRunning())
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
@ -2571,7 +2571,7 @@ NS_IMETHODIMP nsPluginHost::InstantiateFullPagePlugin(const char *aMimeType,
|
||||
}
|
||||
|
||||
nsresult nsPluginHost::FindStoppedPluginForURL(nsIURI* aURL,
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
nsIPluginInstanceOwner *aOwner)
|
||||
{
|
||||
nsCAutoString url;
|
||||
if (!aURL)
|
||||
@ -2579,13 +2579,13 @@ nsresult nsPluginHost::FindStoppedPluginForURL(nsIURI* aURL,
|
||||
|
||||
aURL->GetAsciiSpec(url);
|
||||
|
||||
nsPluginInstanceTag * plugin = mPluginInstanceTagList.findStopped(url.get());
|
||||
nsPluginInstanceTag *instanceTag = mPluginInstanceTagList.findStopped(url.get());
|
||||
|
||||
if (plugin && plugin->mStopped) {
|
||||
nsIPluginInstance* instance = plugin->mInstance;
|
||||
if (instanceTag && !instanceTag->mInstance->IsRunning()) {
|
||||
NPWindow* window = nsnull;
|
||||
aOwner->GetWindow(window);
|
||||
|
||||
nsIPluginInstance* instance = static_cast<nsIPluginInstance*>(instanceTag->mInstance);
|
||||
aOwner->SetInstance(instance);
|
||||
instance->SetOwner(aOwner);
|
||||
|
||||
@ -2598,7 +2598,6 @@ nsresult nsPluginHost::FindStoppedPluginForURL(nsIURI* aURL,
|
||||
((nsPluginNativeWindow*)window)->CallSetWindow(inst);
|
||||
}
|
||||
|
||||
plugin->setStopped(PR_FALSE);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -2608,7 +2607,6 @@ nsresult nsPluginHost::AddInstanceToActiveList(nsCOMPtr<nsIPlugin> aPlugin,
|
||||
nsIPluginInstance* aInstance,
|
||||
nsIURI* aURL,
|
||||
PRBool aDefaultPlugin)
|
||||
|
||||
{
|
||||
nsCAutoString url;
|
||||
// It's OK to not have a URL here, as is the case with the dummy
|
||||
@ -4538,8 +4536,6 @@ nsPluginHost::StopPluginInstance(nsIPluginInstance* aInstance)
|
||||
nsPluginInstanceTag * plugin = mPluginInstanceTagList.find(aInstance);
|
||||
|
||||
if (plugin) {
|
||||
plugin->setStopped(PR_TRUE); // be sure we set the "stop" bit
|
||||
|
||||
// if the plugin does not want to be 'cached' just remove it
|
||||
PRBool doCache = PR_TRUE;
|
||||
aInstance->ShouldCache(&doCache);
|
||||
|
@ -54,6 +54,9 @@
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsPluginLogging.h"
|
||||
#include "nsICategoryManager.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
using mozilla::TimeStamp;
|
||||
|
||||
inline char* new_str(const char* str)
|
||||
{
|
||||
@ -564,40 +567,31 @@ nsPluginInstanceTag::nsPluginInstanceTag(nsPluginTag* aPluginTag,
|
||||
const char * url,
|
||||
PRBool aDefaultPlugin)
|
||||
{
|
||||
NS_ASSERTION(aInstance, "Must have a valid plugin instance when creating an nsPluginInstanceTag");
|
||||
NS_ADDREF(aInstance);
|
||||
mInstance = static_cast<nsNPAPIPluginInstance*>(aInstance);
|
||||
|
||||
mNext = nsnull;
|
||||
mPluginTag = aPluginTag;
|
||||
|
||||
mURL = PL_strdup(url);
|
||||
mInstance = aInstance;
|
||||
if (aInstance)
|
||||
NS_ADDREF(aInstance);
|
||||
|
||||
mDefaultPlugin = aDefaultPlugin;
|
||||
mStopped = PR_FALSE;
|
||||
mllStopTime = LL_ZERO;
|
||||
}
|
||||
|
||||
nsPluginInstanceTag::~nsPluginInstanceTag()
|
||||
{
|
||||
mPluginTag = nsnull;
|
||||
if (mInstance) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
mInstance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner)
|
||||
owner->SetInstance(nsnull);
|
||||
mInstance->InvalidateOwner();
|
||||
|
||||
NS_RELEASE(mInstance);
|
||||
}
|
||||
PL_strfree(mURL);
|
||||
}
|
||||
|
||||
void nsPluginInstanceTag::setStopped(PRBool stopped)
|
||||
{
|
||||
mStopped = stopped;
|
||||
if (mStopped) // plugin instance is told to stop
|
||||
mllStopTime = PR_Now();
|
||||
else
|
||||
mllStopTime = LL_ZERO;
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
mInstance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner)
|
||||
owner->SetInstance(nsnull);
|
||||
mInstance->InvalidateOwner();
|
||||
|
||||
NS_RELEASE(mInstance);
|
||||
|
||||
PL_strfree(mURL);
|
||||
}
|
||||
|
||||
/* nsPluginInstanceTagList */
|
||||
@ -719,16 +713,14 @@ void nsPluginInstanceTagList::stopRunning(nsISupportsArray* aReloadDocs,
|
||||
return;
|
||||
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!p->mStopped && p->mInstance &&
|
||||
(!aPluginTag || aPluginTag == p->mPluginTag)) {
|
||||
if (p->mInstance->IsRunning() && (!aPluginTag || aPluginTag == p->mPluginTag)) {
|
||||
p->mInstance->SetWindow(nsnull);
|
||||
p->mInstance->Stop();
|
||||
p->setStopped(PR_TRUE);
|
||||
|
||||
// If we've been passed an array to return, lets collect all our documents,
|
||||
// removing duplicates. These will be reframed (embedded) or reloaded (full-page) later
|
||||
// to kickstart our instances.
|
||||
if (aReloadDocs && p->mInstance) {
|
||||
if (aReloadDocs) {
|
||||
nsCOMPtr<nsIPluginInstanceOwner> owner;
|
||||
p->mInstance->GetOwner(getter_AddRefs(owner));
|
||||
if (owner) {
|
||||
@ -752,7 +744,7 @@ void nsPluginInstanceTagList::removeAllStopped()
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull;) {
|
||||
next = p->mNext;
|
||||
|
||||
if (p->mStopped)
|
||||
if (!p->mInstance->IsRunning())
|
||||
remove(p);
|
||||
|
||||
p = next;
|
||||
@ -796,7 +788,7 @@ nsPluginInstanceTag * nsPluginInstanceTagList::find(const char * mimetype)
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::findStopped(const char * url)
|
||||
{
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!PL_strcmp(url, p->mURL) && p->mStopped)
|
||||
if (!PL_strcmp(url, p->mURL) && !p->mInstance->IsRunning())
|
||||
return p;
|
||||
}
|
||||
return nsnull;
|
||||
@ -806,7 +798,7 @@ PRUint32 nsPluginInstanceTagList::getStoppedCount()
|
||||
{
|
||||
PRUint32 stoppedCount = 0;
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (p->mStopped)
|
||||
if (!p->mInstance->IsRunning())
|
||||
stoppedCount++;
|
||||
}
|
||||
return stoppedCount;
|
||||
@ -815,13 +807,14 @@ PRUint32 nsPluginInstanceTagList::getStoppedCount()
|
||||
nsPluginInstanceTag * nsPluginInstanceTagList::findOldestStopped()
|
||||
{
|
||||
nsPluginInstanceTag * res = nsnull;
|
||||
PRInt64 llTime = LL_MAXINT;
|
||||
TimeStamp oldestTime = TimeStamp::Now();
|
||||
for (nsPluginInstanceTag * p = mFirst; p != nsnull; p = p->mNext) {
|
||||
if (!p->mStopped)
|
||||
if (p->mInstance->IsRunning())
|
||||
continue;
|
||||
|
||||
if (LL_CMP(p->mllStopTime, <, llTime)) {
|
||||
llTime = p->mllStopTime;
|
||||
|
||||
TimeStamp time = p->mInstance->LastStopTime();
|
||||
if (time < oldestTime) {
|
||||
oldestTime = time;
|
||||
res = p;
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIPluginTag.h"
|
||||
#include "nsIPlugin.h"
|
||||
#include "nsIPluginInstance.h"
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
#include "nsISupportsArray.h"
|
||||
|
||||
class nsPluginHost;
|
||||
@ -128,9 +128,7 @@ struct nsPluginInstanceTag
|
||||
nsPluginInstanceTag* mNext;
|
||||
char* mURL;
|
||||
nsRefPtr<nsPluginTag> mPluginTag;
|
||||
nsIPluginInstance* mInstance;
|
||||
PRTime mllStopTime;
|
||||
PRPackedBool mStopped;
|
||||
nsNPAPIPluginInstance* mInstance; // this must always be valid
|
||||
PRPackedBool mDefaultPlugin;
|
||||
// Array holding all opened stream listeners for this entry
|
||||
nsCOMPtr <nsISupportsArray> mStreams;
|
||||
@ -140,8 +138,6 @@ struct nsPluginInstanceTag
|
||||
const char * url,
|
||||
PRBool aDefaultPlugin);
|
||||
~nsPluginInstanceTag();
|
||||
|
||||
void setStopped(PRBool stopped);
|
||||
};
|
||||
|
||||
class nsPluginInstanceTagList
|
||||
|
Loading…
Reference in New Issue
Block a user