Bug 1072024 - Destroy uninitialized GMP objects - r=cpearce
authorEdwin Flores <eflores@mozilla.com>
Tue, 14 Oct 2014 11:04:59 +1300
changeset 210243 85634997827efd7a5b330b27f1b48f7f2d806be5
parent 210242 7600cd87ae2091c4d599520bba48fa5e2dd6d5ae
child 210244 6dc9dc5e1b73cdd5ad704ecfbbfeb1fa1e32b903
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewerscpearce
bugs1072024
milestone35.0a1
Bug 1072024 - Destroy uninitialized GMP objects - r=cpearce
content/media/gmp/GMPAudioDecoderParent.cpp
content/media/gmp/GMPAudioDecoderParent.h
content/media/gmp/GMPDecryptorParent.cpp
content/media/gmp/GMPDecryptorParent.h
content/media/gmp/GMPVideoDecoderParent.cpp
content/media/gmp/GMPVideoDecoderParent.h
content/media/gmp/GMPVideoEncoderParent.cpp
content/media/gmp/GMPVideoEncoderParent.h
--- 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