Improve nsNPAPIPluginInstance's stream management. Streams shouldn't keep strong references to their instances. Replace ugly linked list storage. b=554524 r=jst

This commit is contained in:
Josh Aas 2010-04-07 16:30:32 -04:00
Родитель 44ccd6e3d8
Коммит f4e225e160
3 изменённых файлов: 17 добавлений и 89 удалений

Просмотреть файл

@ -204,30 +204,10 @@ nsNPAPIPluginStreamListener::nsNPAPIPluginStreamListener(nsNPAPIPluginInstance*
mResponseHeaderBuf(nsnull) mResponseHeaderBuf(nsnull)
{ {
memset(&mNPStream, 0, sizeof(mNPStream)); memset(&mNPStream, 0, sizeof(mNPStream));
NS_IF_ADDREF(mInst);
} }
nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener(void) nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener()
{ {
// remove itself from the instance stream list
nsNPAPIPluginInstance *inst = mInst;
if (inst) {
nsInstanceStream * prev = nsnull;
for (nsInstanceStream *is = inst->mStreams; is != nsnull; is = is->mNext) {
if (is->mPluginStreamListener == this) {
if (!prev)
inst->mStreams = is->mNext;
else
prev->mNext = is->mNext;
delete is;
break;
}
prev = is;
}
}
// For those cases when NewStream is never called, we still may need // For those cases when NewStream is never called, we still may need
// to fire a notification callback. Return network error as fallback // to fire a notification callback. Return network error as fallback
// reason because for other cases, notify should have already been // reason because for other cases, notify should have already been
@ -240,8 +220,6 @@ nsNPAPIPluginStreamListener::~nsNPAPIPluginStreamListener(void)
mStreamBuffer=nsnull; mStreamBuffer=nsnull;
} }
NS_IF_RELEASE(inst);
if (mNotifyURL) if (mNotifyURL)
PL_strfree(mNotifyURL); PL_strfree(mNotifyURL);
@ -265,7 +243,7 @@ nsresult nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason)
if (NP_SEEK == mStreamType) if (NP_SEEK == mStreamType)
NS_RELEASE_THIS(); NS_RELEASE_THIS();
if (!mInst || !mInst->CanFireNotifications()) if (!mInst->CanFireNotifications())
return rv; return rv;
mStreamInfo = NULL; mStreamInfo = NULL;
@ -306,7 +284,7 @@ nsresult nsNPAPIPluginStreamListener::CleanUpStream(NPReason reason)
void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason) void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason)
{ {
if (!mCallNotify || !mInst || !mInst->CanFireNotifications()) if (!mCallNotify || !mInst->CanFireNotifications())
return; return;
PluginDestructionGuard guard(mInst); PluginDestructionGuard guard(mInst);
@ -319,7 +297,6 @@ void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason)
return; return;
if (callbacks->urlnotify) { if (callbacks->urlnotify) {
NPP npp; NPP npp;
mInst->GetNPP(&npp); mInst->GetNPP(&npp);
@ -334,9 +311,6 @@ void nsNPAPIPluginStreamListener::CallURLNotify(NPReason reason)
NS_IMETHODIMP NS_IMETHODIMP
nsNPAPIPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo) nsNPAPIPluginStreamListener::OnStartBinding(nsIPluginStreamInfo* pluginInfo)
{ {
if (!mInst)
return NS_ERROR_FAILURE;
PluginDestructionGuard guard(mInst); PluginDestructionGuard guard(mInst);
NPP npp; NPP npp;
@ -473,8 +447,8 @@ nsNPAPIPluginStreamListener::StopDataPump()
PRBool PRBool
nsNPAPIPluginStreamListener::PluginInitJSLoadInProgress() nsNPAPIPluginStreamListener::PluginInitJSLoadInProgress()
{ {
for (nsInstanceStream *is = mInst->mStreams; is; is = is->mNext) { for (unsigned int i = 0; i < mInst->mStreams.Length(); i++) {
if (is->mPluginStreamListener->mIsPluginInitJSStream) { if (mInst->mStreams[i]->mIsPluginInitJSStream) {
return PR_TRUE; return PR_TRUE;
} }
} }
@ -494,7 +468,7 @@ nsNPAPIPluginStreamListener::OnDataAvailable(nsIPluginStreamInfo* pluginInfo,
nsIInputStream* input, nsIInputStream* input,
PRUint32 length) PRUint32 length)
{ {
if (!mInst || !mInst->CanFireNotifications()) if (!mInst->CanFireNotifications())
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
PluginDestructionGuard guard(mInst); PluginDestructionGuard guard(mInst);
@ -759,7 +733,7 @@ NS_IMETHODIMP
nsNPAPIPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo, nsNPAPIPluginStreamListener::OnFileAvailable(nsIPluginStreamInfo* pluginInfo,
const char* fileName) const char* fileName)
{ {
if (!mInst || !mInst->CanFireNotifications()) if (!mInst->CanFireNotifications())
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
PluginDestructionGuard guard(mInst); PluginDestructionGuard guard(mInst);
@ -802,7 +776,7 @@ nsNPAPIPluginStreamListener::OnStopBinding(nsIPluginStreamInfo* pluginInfo,
} }
} }
if (!mInst || !mInst->CanFireNotifications()) if (!mInst->CanFireNotifications())
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
// check if the stream is of seekable type and later its destruction // check if the stream is of seekable type and later its destruction
@ -873,16 +847,6 @@ nsNPAPIPluginStreamListener::NewResponseHeader(const char* headerName,
return NS_OK; return NS_OK;
} }
nsInstanceStream::nsInstanceStream()
{
mNext = nsnull;
mPluginStreamListener = nsnull;
}
nsInstanceStream::~nsInstanceStream()
{
}
NS_IMPL_ISUPPORTS1(nsNPAPIPluginInstance, nsIPluginInstance) NS_IMPL_ISUPPORTS1(nsNPAPIPluginInstance, nsIPluginInstance)
nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks, nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks,
@ -918,17 +882,10 @@ nsNPAPIPluginInstance::nsNPAPIPluginInstance(NPPluginFuncs* callbacks,
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this)); PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance ctor: this=%p\n",this));
} }
nsNPAPIPluginInstance::~nsNPAPIPluginInstance(void) nsNPAPIPluginInstance::~nsNPAPIPluginInstance()
{ {
PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this)); PLUGIN_LOG(PLUGIN_LOG_BASIC, ("nsNPAPIPluginInstance dtor: this=%p\n",this));
// clean the stream list if any
for (nsInstanceStream *is = mStreams; is != nsnull;) {
nsInstanceStream * next = is->mNext;
delete is;
is = next;
}
if (mMIMEType) { if (mMIMEType) {
PR_Free((void *)mMIMEType); PR_Free((void *)mMIMEType);
mMIMEType = nsnull; mMIMEType = nsnull;
@ -1004,19 +961,10 @@ NS_IMETHODIMP nsNPAPIPluginInstance::Stop()
OnPluginDestroy(&mNPP); OnPluginDestroy(&mNPP);
// clean up open streams // clean up open streams
for (nsInstanceStream *is = mStreams; is != nsnull;) { for (unsigned int i = 0; i < mStreams.Length(); i++) {
nsRefPtr<nsNPAPIPluginStreamListener> listener = is->mPluginStreamListener; mStreams[i]->CleanUpStream(NPRES_USER_BREAK);
nsInstanceStream *next = is->mNext;
delete is;
is = next;
mStreams = is;
// Clean up our stream after removing it from the list because
// it may be released and destroyed at this point.
if (listener)
listener->CleanUpStream(NPRES_USER_BREAK);
} }
mStreams.Clear();
NPError error = NPERR_GENERIC_ERROR; NPError error = NPERR_GENERIC_ERROR;
if (mCallbacks->destroy) { if (mCallbacks->destroy) {
@ -1296,23 +1244,11 @@ nsresult nsNPAPIPluginInstance::NewNotifyStream(nsIPluginStreamListener** listen
nsNPAPIPluginStreamListener* stream = new nsNPAPIPluginStreamListener(this, notifyData, aURL); nsNPAPIPluginStreamListener* stream = new nsNPAPIPluginStreamListener(this, notifyData, aURL);
NS_ENSURE_TRUE(stream, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(stream, NS_ERROR_OUT_OF_MEMORY);
// add it to the list mStreams.AppendElement(stream);
nsInstanceStream * is = new nsInstanceStream();
NS_ENSURE_TRUE(is, NS_ERROR_OUT_OF_MEMORY);
is->mNext = mStreams;
is->mPluginStreamListener = stream;
mStreams = is;
stream->SetCallNotify(aCallNotify); // set flag in stream to call URLNotify stream->SetCallNotify(aCallNotify); // set flag in stream to call URLNotify
NS_ADDREF(stream); // Stabilize return stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener);
nsresult res = stream->QueryInterface(kIPluginStreamListenerIID, (void**)listener);
// Destabilize and avoid leaks. Avoid calling delete <interface pointer>
NS_RELEASE(stream);
return res;
} }
NS_IMETHODIMP nsNPAPIPluginInstance::Print(NPPrint* platformPrint) NS_IMETHODIMP nsNPAPIPluginInstance::Print(NPPrint* platformPrint)

Просмотреть файл

@ -41,6 +41,7 @@
#define nsNPAPIPluginInstance_h_ #define nsNPAPIPluginInstance_h_
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsTArray.h" #include "nsTArray.h"
#include "nsIPlugin.h" #include "nsIPlugin.h"
#include "nsIPluginInstance.h" #include "nsIPluginInstance.h"
@ -56,15 +57,6 @@
class nsNPAPIPluginStreamListener; class nsNPAPIPluginStreamListener;
class nsPIDOMWindow; class nsPIDOMWindow;
struct nsInstanceStream
{
nsInstanceStream *mNext;
nsNPAPIPluginStreamListener *mPluginStreamListener;
nsInstanceStream();
~nsInstanceStream();
};
class nsNPAPITimer class nsNPAPITimer
{ {
public: public:
@ -180,7 +172,7 @@ public:
// True while creating the plugin, or calling NPP_SetWindow() on it. // True while creating the plugin, or calling NPP_SetWindow() on it.
PRPackedBool mInPluginInitCall; PRPackedBool mInPluginInitCall;
PluginLibrary* mLibrary; PluginLibrary* mLibrary;
nsInstanceStream *mStreams; nsTArray< nsRefPtr<nsNPAPIPluginStreamListener> > mStreams;
private: private:
nsTArray<PopupControlState> mPopupStates; nsTArray<PopupControlState> mPopupStates;

Просмотреть файл

@ -85,7 +85,7 @@ protected:
void* mNotifyData; void* mNotifyData;
char* mStreamBuffer; char* mStreamBuffer;
char* mNotifyURL; char* mNotifyURL;
nsNPAPIPluginInstance* mInst; nsNPAPIPluginInstance* mInst; // weak, must always be valid
NPStream mNPStream; NPStream mNPStream;
PRUint32 mStreamBufferSize; PRUint32 mStreamBufferSize;
PRInt32 mStreamBufferByteCount; PRInt32 mStreamBufferByteCount;