From a8ea1ff3e3519dae326dc96ce8be110385322cd0 Mon Sep 17 00:00:00 2001 From: Aaron Klotz Date: Mon, 19 Oct 2015 14:34:27 -0400 Subject: [PATCH] Bug 1208059: Make nsNPAPIPluginInstance support WeakPtr and modify PluginAsyncSurrogate to use it; r=jimm --- dom/plugins/base/nsNPAPIPluginInstance.h | 3 ++ dom/plugins/ipc/PluginAsyncSurrogate.cpp | 56 ++++++++++++++++-------- dom/plugins/ipc/PluginAsyncSurrogate.h | 4 +- 3 files changed, 42 insertions(+), 21 deletions(-) diff --git a/dom/plugins/base/nsNPAPIPluginInstance.h b/dom/plugins/base/nsNPAPIPluginInstance.h index 4289053c673..fe41729dba6 100644 --- a/dom/plugins/base/nsNPAPIPluginInstance.h +++ b/dom/plugins/base/nsNPAPIPluginInstance.h @@ -31,6 +31,7 @@ class SharedPluginTexture; #include "mozilla/TimeStamp.h" #include "mozilla/PluginLibrary.h" +#include "mozilla/WeakPtr.h" class nsPluginStreamListenerPeer; // browser-initiated stream class class nsNPAPIPluginStreamListener; // plugin-initiated stream class @@ -76,11 +77,13 @@ public: }; class nsNPAPIPluginInstance final : public nsIAudioChannelAgentCallback + , public mozilla::SupportsWeakPtr { private: typedef mozilla::PluginLibrary PluginLibrary; public: + MOZ_DECLARE_WEAKREFERENCE_TYPENAME(nsNPAPIPluginInstance) NS_DECL_THREADSAFE_ISUPPORTS NS_DECL_NSIAUDIOCHANNELAGENTCALLBACK diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.cpp b/dom/plugins/ipc/PluginAsyncSurrogate.cpp index 69120b58873..da07116ccd5 100644 --- a/dom/plugins/ipc/PluginAsyncSurrogate.cpp +++ b/dom/plugins/ipc/PluginAsyncSurrogate.cpp @@ -101,7 +101,6 @@ bool RecursionGuard::sHasEntered = false; PluginAsyncSurrogate::PluginAsyncSurrogate(PluginModuleParent* aParent) : mParent(aParent) - , mInstance(nullptr) , mMode(0) , mWindow(nullptr) , mAcceptCalls(false) @@ -123,7 +122,10 @@ PluginAsyncSurrogate::Init(NPMIMEType aPluginType, NPP aInstance, uint16_t aMode int16_t aArgc, char* aArgn[], char* aArgv[]) { mMimeType = aPluginType; - mInstance = aInstance; + nsNPAPIPluginInstance* instance = + static_cast(aInstance->ndata); + MOZ_ASSERT(instance); + mInstance = instance; mMode = aMode; for (int i = 0; i < aArgc; ++i) { mNames.AppendElement(NullableString(aArgn[i])); @@ -162,7 +164,11 @@ PluginAsyncSurrogate::Cast(NPP aInstance) nsresult PluginAsyncSurrogate::NPP_New(NPError* aError) { - nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), mInstance, + if (!mInstance) { + return NS_ERROR_NULL_POINTER; + } + + nsresult rv = mParent->NPP_NewInternal(mMimeType.BeginWriting(), GetNPP(), mMode, mNames, mValues, nullptr, aError); if (NS_FAILED(rv)) { @@ -199,11 +205,21 @@ PluginAsyncSurrogate::NotifyDestroyPending(NPP aInstance) surrogate->NotifyDestroyPending(); } +NPP +PluginAsyncSurrogate::GetNPP() +{ + MOZ_ASSERT(mInstance); + NPP npp; + DebugOnly rv = mInstance->GetNPP(&npp); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + return npp; +} + void PluginAsyncSurrogate::NotifyDestroyPending() { mDestroyPending = true; - nsJSNPRuntime::OnPluginDestroyPending(mInstance); + nsJSNPRuntime::OnPluginDestroyPending(GetNPP()); } NPError @@ -213,7 +229,7 @@ PluginAsyncSurrogate::NPP_Destroy(NPSavedData** aSave) if (!WaitForInit()) { return NPERR_GENERIC_ERROR; } - return PluginModuleParent::NPP_Destroy(mInstance, aSave); + return PluginModuleParent::NPP_Destroy(GetNPP(), aSave); } NPError @@ -223,12 +239,13 @@ PluginAsyncSurrogate::NPP_GetValue(NPPVariable aVariable, void* aRetval) if (!WaitForInit()) { return NPERR_GENERIC_ERROR; } - PluginInstanceParent* instance = PluginInstanceParent::Cast(mInstance); + + PluginInstanceParent* instance = PluginInstanceParent::Cast(GetNPP()); MOZ_ASSERT(instance); return instance->NPP_GetValue(aVariable, aRetval); } - NPObject* npobject = parent::_createobject(mInstance, + NPObject* npobject = parent::_createobject(GetNPP(), const_cast(GetClass())); MOZ_ASSERT(npobject); MOZ_ASSERT(npobject->_class == GetClass()); @@ -243,7 +260,7 @@ PluginAsyncSurrogate::NPP_SetValue(NPNVariable aVariable, void* aValue) if (!WaitForInit()) { return NPERR_GENERIC_ERROR; } - return PluginModuleParent::NPP_SetValue(mInstance, aVariable, aValue); + return PluginModuleParent::NPP_SetValue(GetNPP(), aVariable, aValue); } NPError @@ -429,7 +446,10 @@ PluginAsyncSurrogate::DestroyAsyncStream(NPStream* aStream) // streamListener was suspended during async init. We must resume the stream // request prior to calling _destroystream for cleanup to work correctly. streamListener->ResumeRequest(); - parent::_destroystream(mInstance, aStream, NPRES_DONE); + if (!mInstance) { + return; + } + parent::_destroystream(GetNPP(), aStream, NPRES_DONE); } /* static */ bool @@ -569,12 +589,10 @@ PluginAsyncSurrogate::NotifyAsyncInitFailed() // we'll be perma-blocked mInitCancelled = true; - nsNPAPIPluginInstance* inst = - static_cast(mInstance->ndata); - if (!inst) { + if (!mInstance) { return; } - nsPluginInstanceOwner* owner = inst->GetOwner(); + nsPluginInstanceOwner* owner = mInstance->GetOwner(); if (owner) { owner->NotifyHostAsyncInitFailed(); } @@ -663,11 +681,11 @@ PluginAsyncSurrogate::ScriptableHasMethod(NPObject* aObject, // initialization, we should try again. const NPNetscapeFuncs* npn = object->mSurrogate->mParent->GetNetscapeFuncs(); NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(object->mSurrogate->mInstance, + NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(), NPNVPluginElementNPObject, (void*)&pluginObject); if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(object->mSurrogate->mInstance); + NPPAutoPusher nppPusher(object->mSurrogate->GetNPP()); result = pluginObject->_class->hasMethod(pluginObject, aName); npn->releaseobject(pluginObject); NPUTF8* idstr = npn->utf8fromidentifier(aName); @@ -716,10 +734,10 @@ PluginAsyncSurrogate::GetPropertyHelper(NPObject* aObject, NPIdentifier aName, if (!success) { const NPNetscapeFuncs* npn = mParent->GetNetscapeFuncs(); NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(mInstance, NPNVPluginElementNPObject, + NPError nperror = npn->getvalue(GetNPP(), NPNVPluginElementNPObject, (void*)&pluginObject); if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(mInstance); + NPPAutoPusher nppPusher(GetNPP()); bool hasProperty = nsJSObjWrapper::HasOwnProperty(pluginObject, aName); NPUTF8* idstr = npn->utf8fromidentifier(aName); npn->memfree(idstr); @@ -824,11 +842,11 @@ PluginAsyncSurrogate::ScriptableHasProperty(NPObject* aObject, // object hadn't been set yet. Now that we're further along in // initialization, we should try again. NPObject* pluginObject = nullptr; - NPError nperror = npn->getvalue(object->mSurrogate->mInstance, + NPError nperror = npn->getvalue(object->mSurrogate->GetNPP(), NPNVPluginElementNPObject, (void*)&pluginObject); if (nperror == NPERR_NO_ERROR) { - NPPAutoPusher nppPusher(object->mSurrogate->mInstance); + NPPAutoPusher nppPusher(object->mSurrogate->GetNPP()); result = nsJSObjWrapper::HasOwnProperty(pluginObject, aName); npn->releaseobject(pluginObject); idstr = npn->utf8fromidentifier(aName); diff --git a/dom/plugins/ipc/PluginAsyncSurrogate.h b/dom/plugins/ipc/PluginAsyncSurrogate.h index f33d26b43f3..b1dc0e2f612 100644 --- a/dom/plugins/ipc/PluginAsyncSurrogate.h +++ b/dom/plugins/ipc/PluginAsyncSurrogate.h @@ -60,7 +60,7 @@ public: virtual PluginInstanceParent* GetInstance() { return nullptr; } - NPP GetNPP() { return mInstance; } + NPP GetNPP(); bool GetPropertyHelper(NPObject* aObject, NPIdentifier aName, bool* aHasProperty, bool* aHasMethod, @@ -141,7 +141,7 @@ private: PluginModuleParent* mParent; // These values are used to construct the plugin instance nsCString mMimeType; - NPP mInstance; + mozilla::WeakPtr mInstance; uint16_t mMode; InfallibleTArray mNames; InfallibleTArray mValues;