Bug 687610 - QuickTime can't play media from the network cache when running OOP. r=bsmedberg

This commit is contained in:
Steven Michaud 2011-10-19 09:46:24 -05:00
parent 23a020f385
commit bb455c2aad
7 changed files with 61 additions and 6 deletions

View File

@ -578,6 +578,29 @@ nsNPAPIPlugin::Shutdown()
return NS_OK;
}
nsresult
nsNPAPIPlugin::RetainStream(NPStream *pstream, nsISupports **aRetainedPeer)
{
if (!aRetainedPeer)
return NS_ERROR_NULL_POINTER;
*aRetainedPeer = NULL;
if (!pstream || !pstream->ndata)
return NPERR_INVALID_PARAM;
nsNPAPIPluginStreamListener* listener =
static_cast<nsNPAPIPluginStreamListener*>(pstream->ndata);
nsPluginStreamListenerPeer* peer = listener->GetStreamListenerPeer();
if (!peer)
return NPERR_GENERIC_ERROR;
*aRetainedPeer = (nsISupports*) peer;
NS_ADDREF(*aRetainedPeer);
return NS_OK;
}
// Create a new NPP GET or POST (given in the type argument) url
// stream that may have a notify callback
NPError

View File

@ -106,6 +106,8 @@ public:
nsresult CreatePluginInstance(nsNPAPIPluginInstance **aResult);
nsresult Shutdown();
static nsresult RetainStream(NPStream *pstream, nsISupports **aRetainedPeer);
protected:
NPPluginFuncs mPluginFuncs;
PluginLibrary* mLibrary;

View File

@ -56,6 +56,7 @@ BrowserStreamChild::BrowserStreamChild(PluginInstanceChild* instance,
, mStreamStatus(kStreamOpen)
, mDestroyPending(NOT_DESTROYED)
, mNotifyPending(false)
, mStreamAsFilePending(false)
, mInstanceDying(false)
, mState(CONSTRUCTING)
, mURL(url)
@ -140,7 +141,7 @@ BrowserStreamChild::RecvWrite(const int32_t& offset,
}
bool
BrowserStreamChild::AnswerNPP_StreamAsFile(const nsCString& fname)
BrowserStreamChild::RecvNPP_StreamAsFile(const nsCString& fname)
{
PLUGIN_LOG_DEBUG(("%s (fname=%s)", FULLFUNCTION, fname.get()));
@ -152,8 +153,10 @@ BrowserStreamChild::AnswerNPP_StreamAsFile(const nsCString& fname)
if (kStreamOpen != mStreamStatus)
return true;
mInstance->mPluginIface->asfile(&mInstance->mData, &mStream,
fname.get());
mStreamAsFilePending = true;
mStreamAsFileName = fname;
EnsureDeliveryPending();
return true;
}
@ -238,6 +241,19 @@ BrowserStreamChild::Deliver()
"Exit out of the data-delivery loop with pending data");
mPendingData.Clear();
// NPP_StreamAsFile() is documented (at MDN) to be called "when the stream
// is complete" -- i.e. after all calls to NPP_WriteReady() and NPP_Write()
// have finished. We make these calls asynchronously (from
// DeliverPendingData()). So we need to make sure all the "pending data"
// has been "delivered" before calling NPP_StreamAsFile() (also
// asynchronously). Doing this resolves bug 687610, bug 670036 and possibly
// also other bugs.
if (mStreamAsFilePending) {
mInstance->mPluginIface->asfile(&mInstance->mData, &mStream,
mStreamAsFileName.get());
mStreamAsFilePending = false;
}
if (DESTROY_PENDING == mDestroyPending) {
mDestroyPending = DESTROYED;
if (mState != DYING)

View File

@ -72,7 +72,7 @@ public:
virtual bool RecvWrite(const int32_t& offset,
const Buffer& data,
const uint32_t& newsize);
virtual bool AnswerNPP_StreamAsFile(const nsCString& fname);
virtual bool RecvNPP_StreamAsFile(const nsCString& fname);
virtual bool RecvNPP_DestroyStream(const NPReason& reason);
virtual bool Recv__delete__();
@ -166,6 +166,8 @@ private:
DESTROYED // NPP_DestroyStream delivered, NPP_URLNotify may still be pending
} mDestroyPending;
bool mNotifyPending;
bool mStreamAsFilePending;
nsCString mStreamAsFileName;
// When NPP_Destroy is called for our instance (manager), this flag is set
// cancels the stream and avoids sending StreamDestroyed.

View File

@ -2,6 +2,7 @@
#include "BrowserStreamParent.h"
#include "PluginInstanceParent.h"
#include "nsNPAPIPlugin.h"
#include "mozilla/unused.h"
@ -97,6 +98,8 @@ BrowserStreamParent::RecvStreamDestroyed()
return false;
}
mStreamPeer = NULL;
mState = DELETING;
return Send__delete__(this);
}
@ -134,7 +137,15 @@ BrowserStreamParent::StreamAsFile(const char* fname)
NS_ASSERTION(ALIVE == mState,
"Calling streamasfile after NPP_DestroyStream?");
unused << CallNPP_StreamAsFile(nsCString(fname));
// Make sure our stream survives until the plugin process tells us we've
// been destroyed (until RecvStreamDestroyed() is called). Since we retain
// mStreamPeer at most once, we won't get in trouble if StreamAsFile() is
// called more than once.
if (!mStreamPeer) {
nsNPAPIPlugin::RetainStream(mStream, getter_AddRefs(mStreamPeer));
}
unused << SendNPP_StreamAsFile(nsCString(fname));
return;
}

View File

@ -76,6 +76,7 @@ private:
PluginInstanceParent* mNPP;
NPStream* mStream;
nsCOMPtr<nsISupports> mStreamPeer;
enum {
ALIVE,

View File

@ -59,7 +59,7 @@ rpc protocol PBrowserStream
child:
async Write(int32_t offset, Buffer data,
uint32_t newlength);
rpc NPP_StreamAsFile(nsCString fname);
async NPP_StreamAsFile(nsCString fname);
/**
* NPP_DestroyStream may race with other messages: the child acknowledges