diff --git a/dom/plugins/BrowserStreamChild.cpp b/dom/plugins/BrowserStreamChild.cpp index 0d2a2bece98..6088179c3df 100644 --- a/dom/plugins/BrowserStreamChild.cpp +++ b/dom/plugins/BrowserStreamChild.cpp @@ -152,16 +152,6 @@ BrowserStreamChild::AnswerNPP_StreamAsFile(const nsCString& fname) return true; } -bool -BrowserStreamChild::Answer__delete__(const NPError& reason, - const bool& artificial) -{ - AssertPluginThread(); - if (!artificial) - NPP_DestroyStream(reason); - return true; -} - NPError BrowserStreamChild::NPN_RequestRead(NPByteRange* aRangeList) { @@ -180,18 +170,31 @@ BrowserStreamChild::NPN_RequestRead(NPByteRange* aRangeList) return result; } -void -BrowserStreamChild::NPP_DestroyStream(NPError reason) +bool +BrowserStreamChild::AnswerNPP_DestroyStream(const NPReason& reason, + NPError* err) { PLUGIN_LOG_DEBUG(("%s (reason=%i)", FULLFUNCTION, reason)); AssertPluginThread(); - if (mClosed) - return; + if (mClosed) { + NS_WARNING("NPP_DestroyStream on a closed stream"); + return true; + } - mInstance->mPluginIface->destroystream(&mInstance->mData, &mStream, reason); + *err = mInstance->mPluginIface->destroystream(&mInstance->mData, + &mStream, reason); mClosed = true; + return true; +} + +bool +BrowserStreamChild::Recv__delete__() +{ + if (!mClosed) + NS_WARNING("__delete__ on an open stream"); + return true; } } /* namespace plugins */ diff --git a/dom/plugins/BrowserStreamChild.h b/dom/plugins/BrowserStreamChild.h index 776e678a72d..06f2d04aaba 100644 --- a/dom/plugins/BrowserStreamChild.h +++ b/dom/plugins/BrowserStreamChild.h @@ -81,8 +81,12 @@ public: int32_t* consumed); virtual bool AnswerNPP_StreamAsFile(const nsCString& fname); - virtual bool Answer__delete__(const NPError& reason, - const bool& artificial); + + NS_OVERRIDE + virtual bool AnswerNPP_DestroyStream(const NPReason& reason, NPError* err); + + NS_OVERRIDE + virtual bool Recv__delete__(); void EnsureCorrectInstance(PluginInstanceChild* i) diff --git a/dom/plugins/BrowserStreamParent.cpp b/dom/plugins/BrowserStreamParent.cpp index e4406a7742a..36a67e859b6 100644 --- a/dom/plugins/BrowserStreamParent.cpp +++ b/dom/plugins/BrowserStreamParent.cpp @@ -2,6 +2,15 @@ #include "BrowserStreamParent.h" #include "PluginInstanceParent.h" +#include "PluginModuleParent.h" + +template<> +struct RunnableMethodTraits +{ + typedef mozilla::plugins::BrowserStreamParent Cls; + static void RetainCallee(Cls* obj) { } + static void ReleaseCallee(Cls* obj) { } +}; namespace mozilla { namespace plugins { @@ -10,12 +19,33 @@ BrowserStreamParent::BrowserStreamParent(PluginInstanceParent* npp, NPStream* stream) : mNPP(npp) , mStream(stream) + , mDeleteTask(nsnull) { mStream->pdata = static_cast(this); } BrowserStreamParent::~BrowserStreamParent() { + if (mDeleteTask) { + mDeleteTask->Cancel(); + // MessageLoop::current() owns this + mDeleteTask = nsnull; + } +} + +NPError +BrowserStreamParent::NPP_DestroyStream(NPReason reason) +{ + PLUGIN_LOG_DEBUG(("%s (reason=%i)", FULLFUNCTION, reason)); + + if (!mDeleteTask) { + mDeleteTask = NewRunnableMethod(this, &BrowserStreamParent::Delete); + MessageLoop::current()->PostTask(FROM_HERE, mDeleteTask); + } + + NPError err = NPERR_NO_ERROR; + CallNPP_DestroyStream(reason, &err); + return err; } bool @@ -42,15 +72,6 @@ BrowserStreamParent::AnswerNPN_RequestRead(const IPCByteRanges& ranges, return true; } -bool -BrowserStreamParent::Answer__delete__(const NPError& reason, - const bool& artificial) -{ - if (!artificial) - NPN_DestroyStream(reason); - return true; -} - int32_t BrowserStreamParent::WriteReady() { @@ -87,12 +108,21 @@ BrowserStreamParent::StreamAsFile(const char* fname) CallNPP_StreamAsFile(nsCString(fname)); } -NPError -BrowserStreamParent::NPN_DestroyStream(NPReason reason) +bool +BrowserStreamParent::AnswerNPN_DestroyStream(const NPReason& reason, + NPError* result) { PLUGIN_LOG_DEBUG_FUNCTION; - return mNPP->mNPNIface->destroystream(mNPP->mNPP, mStream, reason); + *result = mNPP->mNPNIface->destroystream(mNPP->mNPP, mStream, reason); + return true; +} + +void +BrowserStreamParent::Delete() +{ + PBrowserStreamParent::Send__delete__(this); + // |this| just got deleted } } // namespace plugins diff --git a/dom/plugins/BrowserStreamParent.h b/dom/plugins/BrowserStreamParent.h index fb28fdc9de0..3010243071b 100644 --- a/dom/plugins/BrowserStreamParent.h +++ b/dom/plugins/BrowserStreamParent.h @@ -44,6 +44,7 @@ namespace mozilla { namespace plugins { +class PluginModuleParent; class PluginInstanceParent; class BrowserStreamParent : public PBrowserStreamParent, public AStream @@ -56,23 +57,25 @@ public: NPStream* stream); virtual ~BrowserStreamParent(); + NPError NPP_DestroyStream(NPReason reason); + NS_OVERRIDE virtual bool IsBrowserStream() { return true; } virtual bool AnswerNPN_RequestRead(const IPCByteRanges& ranges, NPError* result); - virtual bool - Answer__delete__(const NPError& reason, const bool& artificial); + virtual bool AnswerNPN_DestroyStream(const NPReason& reason, NPError* result); int32_t WriteReady(); int32_t Write(int32_t offset, int32_t len, void* buffer); void StreamAsFile(const char* fname); private: - NPError NPN_DestroyStream(NPError reason); + void Delete(); PluginInstanceParent* mNPP; NPStream* mStream; + CancelableTask* mDeleteTask; }; } // namespace plugins diff --git a/dom/plugins/PBrowserStream.ipdl b/dom/plugins/PBrowserStream.ipdl index c0ef3ce5d9f..ca6cc88ec26 100644 --- a/dom/plugins/PBrowserStream.ipdl +++ b/dom/plugins/PBrowserStream.ipdl @@ -66,17 +66,17 @@ child: rpc NPP_StreamAsFile(nsCString fname); + rpc NPP_DestroyStream(NPReason reason) + returns (NPError error); + + async __delete__(); + parent: rpc NPN_RequestRead(IPCByteRanges ranges) returns (NPError result); -both: - /** - * ~PBrowserStream is for both NPN_DestroyStream and NPP_DestroyStream. - * @param artificial True when the stream is closed as a by-product of - * some other call (such as a failure in NPP_Write). - */ - rpc __delete__(NPReason reason, bool artificial); + rpc NPN_DestroyStream(NPReason reason) + returns (NPError error); }; } // namespace plugins diff --git a/dom/plugins/PluginInstanceParent.cpp b/dom/plugins/PluginInstanceParent.cpp index 7f40f43e348..ccadc1ed4a0 100644 --- a/dom/plugins/PluginInstanceParent.cpp +++ b/dom/plugins/PluginInstanceParent.cpp @@ -640,7 +640,7 @@ PluginInstanceParent::NPP_NewStream(NPMIMEType type, NPStream* stream, return NPERR_GENERIC_ERROR; if (NPERR_NO_ERROR != err) - PBrowserStreamParent::Call__delete__(bs, NPERR_GENERIC_ERROR, true); + bs->NPP_DestroyStream(NPERR_GENERIC_ERROR); return err; } @@ -658,8 +658,7 @@ PluginInstanceParent::NPP_DestroyStream(NPStream* stream, NPReason reason) if (sp->mNPP != this) NS_RUNTIMEABORT("Mismatched plugin data"); - PBrowserStreamParent::Call__delete__(sp, reason, false); - return NPERR_NO_ERROR; + return sp->NPP_DestroyStream(reason); } else { PluginStreamParent* sp = diff --git a/dom/plugins/PluginModuleChild.cpp b/dom/plugins/PluginModuleChild.cpp index 4de5d0cefe7..faa1f2c8c5f 100644 --- a/dom/plugins/PluginModuleChild.cpp +++ b/dom/plugins/PluginModuleChild.cpp @@ -898,7 +898,9 @@ _destroystream(NPP aNPP, if (s->IsBrowserStream()) { BrowserStreamChild* bs = static_cast(s); bs->EnsureCorrectInstance(p); - PBrowserStreamChild::Call__delete__(bs, aReason, false); + NPError err = NPERR_NO_ERROR; + bs->CallNPN_DestroyStream(aReason, &err); + return err; } else { PluginStreamChild* ps = static_cast(s);