Bug 1373914. P1 - add a static to track the life cycle of MediaShutdownManager. draft
authorJW Wang <jwwang@mozilla.com>
Mon, 19 Jun 2017 17:09:56 +0800
changeset 597115 980d77c9a2e15d289b0d10c9972138a386595fb6
parent 597061 7332d8076ec36179547fade023eab511b1c317d9
child 597116 2f00b9a01f563807965779bcded05f5c8742099a
push id64841
push userjwwang@mozilla.com
push dateTue, 20 Jun 2017 06:34:46 +0000
bugs1373914
milestone56.0a1
Bug 1373914. P1 - add a static to track the life cycle of MediaShutdownManager. MozReview-Commit-ID: GRonPU7cVFV
dom/media/MediaShutdownManager.cpp
dom/media/MediaShutdownManager.h
--- a/dom/media/MediaShutdownManager.cpp
+++ b/dom/media/MediaShutdownManager.cpp
@@ -19,27 +19,30 @@ extern LazyLogModule gMediaDecoderLog;
 #define DECODER_LOG(type, msg) MOZ_LOG(gMediaDecoderLog, type, msg)
 #define LOGW(...) NS_WARNING(nsPrintfCString(__VA_ARGS__).get())
 
 NS_IMPL_ISUPPORTS(MediaShutdownManager, nsIAsyncShutdownBlocker)
 
 MediaShutdownManager::MediaShutdownManager()
 {
   MOZ_ASSERT(NS_IsMainThread());
+  MOZ_DIAGNOSTIC_ASSERT(sInitPhase == NotInited);
 }
 
 MediaShutdownManager::~MediaShutdownManager()
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 // Note that we don't use ClearOnShutdown() on this StaticRefPtr, as that
 // may interfere with our shutdown listener.
 StaticRefPtr<MediaShutdownManager> MediaShutdownManager::sInstance;
 
+MediaShutdownManager::InitPhase MediaShutdownManager::sInitPhase = MediaShutdownManager::NotInited;
+
 MediaShutdownManager&
 MediaShutdownManager::Instance()
 {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_DIAGNOSTIC_ASSERT(sInstance);
   return *sInstance;
 }
 
@@ -60,54 +63,56 @@ GetShutdownBarrier()
   MOZ_RELEASE_ASSERT(barrier);
   return barrier.forget();
 }
 
 void
 MediaShutdownManager::InitStatics()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  static bool sInitDone = false;
-  if (sInitDone) {
+  if (sInitPhase != NotInited) {
     return;
   }
 
-  sInitDone = true;
   sInstance = new MediaShutdownManager();
+  MOZ_DIAGNOSTIC_ASSERT(sInstance);
 
   nsresult rv = GetShutdownBarrier()->AddBlocker(
     sInstance, NS_LITERAL_STRING(__FILE__), __LINE__,
     NS_LITERAL_STRING("MediaShutdownManager shutdown"));
   if (NS_FAILED(rv)) {
     LOGW("Failed to add shutdown blocker! rv=%x", uint32_t(rv));
-    sInstance->mError = rv;
+    sInitPhase = InitFailed;
+    return;
   }
+  sInitPhase = InitSucceeded;
 }
 
 void
 MediaShutdownManager::RemoveBlocker()
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(mIsDoingXPCOMShutDown);
+  MOZ_DIAGNOSTIC_ASSERT(sInitPhase == XPCOMShutdownStarted);
   MOZ_ASSERT(mDecoders.Count() == 0);
   GetShutdownBarrier()->RemoveBlocker(this);
   // Clear our singleton reference. This will probably delete
   // this instance, so don't deref |this| clearing sInstance.
+  sInitPhase = XPCOMShutdownEnded;
   sInstance = nullptr;
   DECODER_LOG(LogLevel::Debug, ("MediaShutdownManager::BlockShutdown() end."));
 }
 
 nsresult
 MediaShutdownManager::Register(MediaDecoder* aDecoder)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  if (NS_FAILED(mError)) {
+  if (sInitPhase == InitFailed) {
     return NS_ERROR_NOT_INITIALIZED;
   }
-  if (mIsDoingXPCOMShutDown) {
+  if (sInitPhase == XPCOMShutdownStarted) {
     return NS_ERROR_ABORT;
   }
   // Don't call Register() after you've Unregistered() all the decoders,
   // that's not going to work.
   MOZ_ASSERT(!mDecoders.Contains(aDecoder));
   mDecoders.PutEntry(aDecoder);
   MOZ_ASSERT(mDecoders.Contains(aDecoder));
   MOZ_ASSERT(mDecoders.Count() > 0);
@@ -117,17 +122,17 @@ MediaShutdownManager::Register(MediaDeco
 void
 MediaShutdownManager::Unregister(MediaDecoder* aDecoder)
 {
   MOZ_ASSERT(NS_IsMainThread());
   if (!mDecoders.Contains(aDecoder)) {
     return;
   }
   mDecoders.RemoveEntry(aDecoder);
-  if (mIsDoingXPCOMShutDown && mDecoders.Count() == 0) {
+  if (sInitPhase == XPCOMShutdownStarted && mDecoders.Count() == 0) {
     RemoveBlocker();
   }
 }
 
 NS_IMETHODIMP
 MediaShutdownManager::GetName(nsAString& aName)
 {
   aName = NS_LITERAL_STRING("MediaShutdownManager: shutdown");
@@ -139,22 +144,23 @@ MediaShutdownManager::GetState(nsIProper
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
 MediaShutdownManager::BlockShutdown(nsIAsyncShutdownClient*)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_ASSERT(sInstance);
+  MOZ_DIAGNOSTIC_ASSERT(sInitPhase == InitSucceeded);
+  MOZ_DIAGNOSTIC_ASSERT(sInstance);
 
   DECODER_LOG(LogLevel::Debug, ("MediaShutdownManager::BlockShutdown() start..."));
 
   // Set this flag to ensure no Register() is allowed when Shutdown() begins.
-  mIsDoingXPCOMShutDown = true;
+  sInitPhase = XPCOMShutdownStarted;
 
   auto oldCount = mDecoders.Count();
   if (oldCount == 0) {
     RemoveBlocker();
     return NS_OK;
   }
 
   // Iterate over the decoders and shut them down.
--- a/dom/media/MediaShutdownManager.h
+++ b/dom/media/MediaShutdownManager.h
@@ -65,16 +65,26 @@ public:
   nsresult Register(MediaDecoder* aDecoder);
 
   // Notifies the MediaShutdownManager that a MediaDecoder that it was
   // tracking has shutdown, and it no longer needs to be shutdown in the
   // xpcom-shutdown listener.
   void Unregister(MediaDecoder* aDecoder);
 
 private:
+  enum InitPhase
+  {
+    NotInited,
+    InitSucceeded,
+    InitFailed,
+    XPCOMShutdownStarted,
+    XPCOMShutdownEnded
+  };
+
+  static InitPhase sInitPhase;
 
   MediaShutdownManager();
   virtual ~MediaShutdownManager();
   void RemoveBlocker();
 
   static StaticRefPtr<MediaShutdownManager> sInstance;
 
   // References to the MediaDecoder. The decoders unregister themselves