Bug 1072024 - Destroy uninitialized GMP objects - r=cpearce
--- a/content/media/gmp/GMPAudioDecoderParent.cpp
+++ b/content/media/gmp/GMPAudioDecoderParent.cpp
@@ -26,16 +26,17 @@ extern PRLogModuleInfo* GetGMPLog();
#define LOGD(msg)
#define LOG(level, msg)
#endif
namespace gmp {
GMPAudioDecoderParent::GMPAudioDecoderParent(GMPParent* aPlugin)
: mIsOpen(false)
+ , mShuttingDown(false)
, mPlugin(aPlugin)
, mCallback(nullptr)
{
MOZ_ASSERT(mPlugin);
}
GMPAudioDecoderParent::~GMPAudioDecoderParent()
{
@@ -156,27 +157,29 @@ GMPAudioDecoderParent::Close()
// Note: Consider keeping ActorDestroy sync'd up when making changes here.
nsresult
GMPAudioDecoderParent::Shutdown()
{
LOGD(("%s: %p", __FUNCTION__, this));
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
+ if (mShuttingDown) {
+ return NS_OK;
+ }
+ mShuttingDown = true;
+
// Notify client we're gone! Won't occur after Close()
if (mCallback) {
mCallback->Terminated();
mCallback = nullptr;
}
- if (mIsOpen) {
- // Don't send DecodingComplete if we died
- mIsOpen = false;
- unused << SendDecodingComplete();
- }
+ mIsOpen = false;
+ unused << SendDecodingComplete();
return NS_OK;
}
// Note: Keep this sync'd up with DecodingComplete
void
GMPAudioDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
{
--- a/content/media/gmp/GMPAudioDecoderParent.h
+++ b/content/media/gmp/GMPAudioDecoderParent.h
@@ -48,16 +48,17 @@ private:
virtual bool RecvDecoded(const GMPAudioDecodedSampleData& aDecoded) MOZ_OVERRIDE;
virtual bool RecvInputDataExhausted() MOZ_OVERRIDE;
virtual bool RecvDrainComplete() MOZ_OVERRIDE;
virtual bool RecvResetComplete() MOZ_OVERRIDE;
virtual bool RecvError(const GMPErr& aError) MOZ_OVERRIDE;
virtual bool Recv__delete__() MOZ_OVERRIDE;
bool mIsOpen;
+ bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
GMPAudioDecoderProxyCallback* mCallback;
};
} // namespace gmp
} // namespace mozilla
#endif // GMPAudioDecoderParent_h_
--- a/content/media/gmp/GMPDecryptorParent.cpp
+++ b/content/media/gmp/GMPDecryptorParent.cpp
@@ -8,16 +8,17 @@
#include "mp4_demuxer/DecoderData.h"
#include "mozilla/unused.h"
namespace mozilla {
namespace gmp {
GMPDecryptorParent::GMPDecryptorParent(GMPParent* aPlugin)
: mIsOpen(false)
+ , mShuttingDown(false)
, mPlugin(aPlugin)
, mCallback(nullptr)
{
MOZ_ASSERT(mPlugin);
}
GMPDecryptorParent::~GMPDecryptorParent()
{
@@ -323,26 +324,29 @@ GMPDecryptorParent::Close()
Shutdown();
}
void
GMPDecryptorParent::Shutdown()
{
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
+ if (mShuttingDown) {
+ return;
+ }
+ mShuttingDown = true;
+
// Notify client we're gone! Won't occur after Close()
if (mCallback) {
mCallback->Terminated();
mCallback = nullptr;
}
- if (mIsOpen) {
- mIsOpen = false;
- unused << SendDecryptingComplete();
- }
+ mIsOpen = false;
+ unused << SendDecryptingComplete();
}
// Note: Keep this sync'd up with Shutdown
void
GMPDecryptorParent::ActorDestroy(ActorDestroyReason aWhy)
{
mIsOpen = false;
if (mCallback) {
--- a/content/media/gmp/GMPDecryptorParent.h
+++ b/content/media/gmp/GMPDecryptorParent.h
@@ -101,16 +101,17 @@ private:
const nsTArray<uint8_t>& aBuffer) MOZ_OVERRIDE;
virtual bool RecvSetCaps(const uint64_t& aCaps) MOZ_OVERRIDE;
virtual void ActorDestroy(ActorDestroyReason aWhy) MOZ_OVERRIDE;
virtual bool Recv__delete__() MOZ_OVERRIDE;
bool mIsOpen;
+ bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
GMPDecryptorProxyCallback* mCallback;
};
} // namespace gmp
} // namespace mozilla
#endif // GMPDecryptorChild_h_
--- a/content/media/gmp/GMPVideoDecoderParent.cpp
+++ b/content/media/gmp/GMPVideoDecoderParent.cpp
@@ -40,16 +40,17 @@ namespace gmp {
// on Close -> Dead
// on ActorDestroy -> Dead
// on Shutdown -> Dead
// Dead: mIsOpen == false
GMPVideoDecoderParent::GMPVideoDecoderParent(GMPParent* aPlugin)
: GMPSharedMemManager(aPlugin)
, mIsOpen(false)
+ , mShuttingDown(false)
, mPlugin(aPlugin)
, mCallback(nullptr)
, mVideoHost(MOZ_THIS_IN_INITIALIZER_LIST())
{
MOZ_ASSERT(mPlugin);
}
GMPVideoDecoderParent::~GMPVideoDecoderParent()
@@ -182,28 +183,30 @@ GMPVideoDecoderParent::Drain()
// Note: Consider keeping ActorDestroy sync'd up when making changes here.
nsresult
GMPVideoDecoderParent::Shutdown()
{
LOGD(("%s: %p", __FUNCTION__, this));
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
+ if (mShuttingDown) {
+ return NS_OK;
+ }
+ mShuttingDown = true;
+
// Notify client we're gone! Won't occur after Close()
if (mCallback) {
mCallback->Terminated();
mCallback = nullptr;
}
mVideoHost.DoneWithAPI();
- if (mIsOpen) {
- // Don't send DecodingComplete if we died
- mIsOpen = false;
- unused << SendDecodingComplete();
- }
+ mIsOpen = false;
+ unused << SendDecodingComplete();
return NS_OK;
}
// Note: Keep this sync'd up with Shutdown
void
GMPVideoDecoderParent::ActorDestroy(ActorDestroyReason aWhy)
{
--- a/content/media/gmp/GMPVideoDecoderParent.h
+++ b/content/media/gmp/GMPVideoDecoderParent.h
@@ -72,16 +72,17 @@ private:
virtual bool RecvResetComplete() MOZ_OVERRIDE;
virtual bool RecvError(const GMPErr& aError) MOZ_OVERRIDE;
virtual bool RecvParentShmemForPool(Shmem& aEncodedBuffer) MOZ_OVERRIDE;
virtual bool AnswerNeedShmem(const uint32_t& aFrameBufferSize,
Shmem* aMem) MOZ_OVERRIDE;
virtual bool Recv__delete__() MOZ_OVERRIDE;
bool mIsOpen;
+ bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
GMPVideoDecoderCallbackProxy* mCallback;
GMPVideoHostImpl mVideoHost;
};
} // namespace gmp
} // namespace mozilla
--- a/content/media/gmp/GMPVideoEncoderParent.cpp
+++ b/content/media/gmp/GMPVideoEncoderParent.cpp
@@ -47,16 +47,17 @@ namespace gmp {
// on Close -> Dead
// on ActorDestroy -> Dead
// on Shutdown -> Dead
// Dead: mIsOpen == false
GMPVideoEncoderParent::GMPVideoEncoderParent(GMPParent *aPlugin)
: GMPSharedMemManager(aPlugin),
mIsOpen(false),
+ mShuttingDown(false),
mPlugin(aPlugin),
mCallback(nullptr),
mVideoHost(MOZ_THIS_IN_INITIALIZER_LIST())
{
MOZ_ASSERT(mPlugin);
nsresult rv = NS_NewNamedThread("GMPEncoded", getter_AddRefs(mEncodedThread));
if (NS_FAILED(rv)) {
@@ -215,27 +216,30 @@ GMPVideoEncoderParent::SetPeriodicKeyFra
// Note: Consider keeping ActorDestroy sync'd up when making changes here.
void
GMPVideoEncoderParent::Shutdown()
{
LOGD(("%s::%s: %p", __CLASS__, __FUNCTION__, this));
MOZ_ASSERT(mPlugin->GMPThread() == NS_GetCurrentThread());
+ if (mShuttingDown) {
+ return;
+ }
+ mShuttingDown = true;
+
// Notify client we're gone! Won't occur after Close()
if (mCallback) {
mCallback->Terminated();
mCallback = nullptr;
}
mVideoHost.DoneWithAPI();
- if (mIsOpen) {
- // Don't send EncodingComplete if we died
- mIsOpen = false;
- unused << SendEncodingComplete();
- }
+
+ mIsOpen = false;
+ unused << SendEncodingComplete();
}
static void
ShutdownEncodedThread(nsCOMPtr<nsIThread>& aThread)
{
aThread->Shutdown();
}
--- a/content/media/gmp/GMPVideoEncoderParent.h
+++ b/content/media/gmp/GMPVideoEncoderParent.h
@@ -69,16 +69,17 @@ private:
const nsTArray<uint8_t>& aCodecSpecificInfo) MOZ_OVERRIDE;
virtual bool RecvError(const GMPErr& aError) MOZ_OVERRIDE;
virtual bool RecvParentShmemForPool(Shmem& aFrameBuffer) MOZ_OVERRIDE;
virtual bool AnswerNeedShmem(const uint32_t& aEncodedBufferSize,
Shmem* aMem) MOZ_OVERRIDE;
virtual bool Recv__delete__() MOZ_OVERRIDE;
bool mIsOpen;
+ bool mShuttingDown;
nsRefPtr<GMPParent> mPlugin;
GMPVideoEncoderCallbackProxy* mCallback;
GMPVideoHostImpl mVideoHost;
nsCOMPtr<nsIThread> mEncodedThread;
};
} // namespace gmp
} // namespace mozilla