Bug 1396698 - Part2 - Dispatch to mainthread by ourself and do the synchronization to avoid race. r=kikuo
authorJames Cheng <jacheng@mozilla.com>
Fri, 03 Nov 2017 14:22:41 +0800
changeset 443240 183249d9d7f77f3c0f3ef13b7e5c18cb4feb40ec
parent 443239 b8fe495f5f4ba6510e08665031ae72da97b0de4c
child 443246 83fe273bfdf2c388359f7dfe66e1dedb09ebf53f
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskikuo
bugs1396698
milestone58.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1396698 - Part2 - Dispatch to mainthread by ourself and do the synchronization to avoid race. r=kikuo MozReview-Commit-ID: 6rA2TvESyEz
dom/media/hls/HLSDecoder.cpp
--- a/dom/media/hls/HLSDecoder.cpp
+++ b/dom/media/hls/HLSDecoder.cpp
@@ -14,16 +14,17 @@
 #include "HLSUtils.h"
 #include "MediaContainerType.h"
 #include "MediaDecoderStateMachine.h"
 #include "MediaFormatReader.h"
 #include "MediaPrefs.h"
 #include "MediaShutdownManager.h"
 #include "nsContentUtils.h"
 #include "nsNetUtil.h"
+#include "nsThreadUtils.h"
 
 using namespace mozilla::java;
 
 namespace mozilla {
 
 class HLSResourceCallbacksSupport
   : public GeckoHLSResourceWrapper::Callbacks::Natives<HLSResourceCallbacksSupport>
 {
@@ -35,52 +36,74 @@ public:
 
   HLSResourceCallbacksSupport(HLSDecoder* aResource);
   void Detach();
   void OnDataArrived();
   void OnError(int aErrorCode);
 
 private:
   ~HLSResourceCallbacksSupport() {}
+  Mutex mMutex;
   HLSDecoder* mDecoder;
 };
 
 HLSResourceCallbacksSupport::HLSResourceCallbacksSupport(HLSDecoder* aDecoder)
+  : mMutex("HLSResourceCallbacksSupport")
+  , mDecoder(aDecoder)
 {
-  MOZ_ASSERT(aDecoder);
-  mDecoder = aDecoder;
+  MOZ_ASSERT(mDecoder);
 }
 
 void
 HLSResourceCallbacksSupport::Detach()
 {
-  MOZ_ASSERT(NS_IsMainThread());
+  MutexAutoLock lock(mMutex);
   mDecoder = nullptr;
 }
 
 void
 HLSResourceCallbacksSupport::OnDataArrived()
 {
-  MOZ_ASSERT(NS_IsMainThread());
-  if (mDecoder) {
-    HLS_DEBUG("HLSResourceCallbacksSupport", "OnDataArrived");
-    mDecoder->NotifyDataArrived();
-  }
+  HLS_DEBUG("HLSResourceCallbacksSupport", "OnDataArrived.");
+  MutexAutoLock lock(mMutex);
+  if (!mDecoder) { return; }
+  RefPtr<HLSResourceCallbacksSupport> self = this;
+  NS_DispatchToMainThread(
+    NS_NewRunnableFunction(
+      "HLSResourceCallbacksSupport::OnDataArrived",
+      [self]() -> void {
+        MutexAutoLock lock(self->mMutex);
+        if (self->mDecoder) {
+          self->mDecoder->NotifyDataArrived();
+        }
+      }
+    )
+  );
 }
 
 void
 HLSResourceCallbacksSupport::OnError(int aErrorCode)
 {
-  MOZ_ASSERT(NS_IsMainThread());
-  if (mDecoder) {
-    HLS_DEBUG("HLSResourceCallbacksSupport", "onError(%d)", aErrorCode);
-    // Since HLS source should be from the Internet, we treat all resource errors
-    // from GeckoHlsPlayer as network errors.
-    mDecoder->NetworkError();
-  }
+  HLS_DEBUG("HLSResourceCallbacksSupport", "onError(%d)", aErrorCode);
+  MutexAutoLock lock(mMutex);
+  if (!mDecoder) { return; }
+  RefPtr<HLSResourceCallbacksSupport> self = this;
+  NS_DispatchToMainThread(
+    NS_NewRunnableFunction(
+      "HLSResourceCallbacksSupport::OnDataArrived",
+      [self]() -> void {
+        MutexAutoLock lock(self->mMutex);
+        if (self->mDecoder) {
+          // Since HLS source should be from the Internet, we treat all resource errors
+          // from GeckoHlsPlayer as network errors.
+          self->mDecoder->NetworkError();
+        }
+      }
+    )
+  );
 }
 
 HLSDecoder::HLSDecoder(MediaDecoderInit& aInit)
   : MediaDecoder(aInit)
 {
 }
 
 MediaDecoderStateMachine*
@@ -200,17 +223,16 @@ HLSDecoder::Resume()
 }
 
 void
 HLSDecoder::Shutdown()
 {
   HLS_DEBUG("HLSDecoder", "Shutdown");
   if (mCallbackSupport) {
     mCallbackSupport->Detach();
-    mCallbackSupport = nullptr;
   }
   if (mHLSResourceWrapper) {
     mHLSResourceWrapper->Destroy();
     mHLSResourceWrapper = nullptr;
   }
   if (mJavaCallbacks) {
     HLSResourceCallbacksSupport::DisposeNative(mJavaCallbacks);
     mJavaCallbacks = nullptr;