Bug 1412204 - add a member to ChannelMediaResource to indicate Close() has been called. r=gerald
authorJW Wang <jwwang@mozilla.com>
Fri, 27 Oct 2017 13:46:44 +0800
changeset 389391 97154c6aa834ebff81bcd92ddcc99f2790458ebe
parent 389390 eff1051ec9410198933b1ab2783cf8db96cfa5cd
child 389392 a74a0791fbb85c1374c3267652b51b74219519b1
push id96855
push userarchaeopteryx@coole-files.de
push dateTue, 31 Oct 2017 23:40:37 +0000
treeherdermozilla-inbound@285362745f60 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgerald
bugs1412204
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 1412204 - add a member to ChannelMediaResource to indicate Close() has been called. r=gerald So we can check this member without calling mCacheStream.IsClosed() which need to acquire the lock and might block the main thread. MozReview-Commit-ID: 4SPooaprrOw
dom/media/ChannelMediaResource.cpp
dom/media/ChannelMediaResource.h
--- a/dom/media/ChannelMediaResource.cpp
+++ b/dom/media/ChannelMediaResource.cpp
@@ -45,16 +45,17 @@ ChannelMediaResource::ChannelMediaResour
   , mCacheStream(this, /* aIsPrivateBrowsing = */ false)
   , mChannelStatistics(aStatistics)
   , mSuspendAgent(mChannel)
 {
 }
 
 ChannelMediaResource::~ChannelMediaResource()
 {
+  MOZ_ASSERT(mClosed);
   MOZ_ASSERT(!mChannel);
   MOZ_ASSERT(!mListener);
 }
 
 // ChannelMediaResource::Listener just observes the channel and
 // forwards notifications to the ChannelMediaResource. We use multiple
 // listener objects so that when we open a new stream for a seek we can
 // disconnect the old listener from the ChannelMediaResource and hook up
@@ -156,17 +157,17 @@ IsPayloadCompressed(nsIHttpChannel* aCha
   return encoding.Length() > 0;
 }
 
 nsresult
 ChannelMediaResource::OnStartRequest(nsIRequest* aRequest,
                                      int64_t aRequestOffset)
 {
   NS_ASSERTION(mChannel.get() == aRequest, "Wrong channel!");
-  MOZ_DIAGNOSTIC_ASSERT(!mCacheStream.IsClosed());
+  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
 
   MediaDecoderOwner* owner = mCallback->GetMediaOwner();
   NS_ENSURE_TRUE(owner, NS_ERROR_FAILURE);
   dom::HTMLMediaElement* element = owner->GetMediaElement();
   NS_ENSURE_TRUE(element, NS_ERROR_FAILURE);
   nsresult status;
   nsresult rv = aRequest->GetStatus(&status);
   NS_ENSURE_SUCCESS(rv, rv);
@@ -367,17 +368,17 @@ ChannelMediaResource::ParseContentRangeH
 }
 
 nsresult
 ChannelMediaResource::OnStopRequest(nsIRequest* aRequest, nsresult aStatus)
 {
   NS_ASSERTION(mChannel.get() == aRequest, "Wrong channel!");
   NS_ASSERTION(!mSuspendAgent.IsSuspended(),
                "How can OnStopRequest fire while we're suspended?");
-  MOZ_DIAGNOSTIC_ASSERT(!mCacheStream.IsClosed());
+  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
 
   mChannelStatistics.Stop();
 
   // Note that aStatus might have succeeded --- this might be a normal close
   // --- even in situations where the server cut us off because we were
   // suspended. So we need to "reopen on error" in that case too. The only
   // cases where we don't need to reopen are when *we* closed the stream.
   // But don't reopen if we need to seek and we don't think we can... that would
@@ -500,17 +501,17 @@ ChannelMediaResource::Open(nsIStreamList
   NS_ADDREF(*aStreamListener);
   return NS_OK;
 }
 
 nsresult
 ChannelMediaResource::OpenChannel(int64_t aOffset)
 {
   MOZ_ASSERT(NS_IsMainThread());
-  MOZ_DIAGNOSTIC_ASSERT(!mCacheStream.IsClosed());
+  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
   MOZ_ASSERT(mChannel);
   MOZ_ASSERT(!mListener, "Listener should have been removed by now");
 
   mListener = new Listener(this, aOffset, ++mLoadID);
   nsresult rv = mChannel->SetNotificationCallbacks(mListener.get());
   NS_ENSURE_SUCCESS(rv, rv);
 
   rv = SetupChannelHeaders(aOffset);
@@ -526,17 +527,17 @@ ChannelMediaResource::OpenChannel(int64_
   element->DownloadResumed();
 
   return NS_OK;
 }
 
 nsresult
 ChannelMediaResource::SetupChannelHeaders(int64_t aOffset)
 {
-  MOZ_DIAGNOSTIC_ASSERT(!mCacheStream.IsClosed());
+  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
 
   // Always use a byte range request even if we're reading from the start
   // of the resource.
   // This enables us to detect if the stream supports byte range
   // requests, and therefore seeking, early.
   nsCOMPtr<nsIHttpChannel> hc = do_QueryInterface(mChannel);
   if (hc) {
     // Use |mOffset| if seeking in a complete file download.
@@ -559,18 +560,21 @@ ChannelMediaResource::SetupChannelHeader
   }
   return NS_OK;
 }
 
 nsresult ChannelMediaResource::Close()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
-  CloseChannel();
-  mCacheStream.Close();
+  if (!mClosed) {
+    CloseChannel();
+    mCacheStream.Close();
+    mClosed = true;
+  }
   return NS_OK;
 }
 
 already_AddRefed<nsIPrincipal>
 ChannelMediaResource::GetCurrentPrincipal()
 {
   NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
 
@@ -667,17 +671,17 @@ nsresult ChannelMediaResource::GetCached
   return mCacheStream.GetCachedRanges(aRanges);
 }
 
 void
 ChannelMediaResource::Suspend(bool aCloseImmediately)
 {
   NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
 
-  if (mCacheStream.IsClosed()) {
+  if (mClosed) {
     // Nothing to do when we are closed.
     return;
   }
 
   MediaDecoderOwner* owner = mCallback->GetMediaOwner();
   if (!owner) {
     // Shutting down; do nothing.
     return;
@@ -701,17 +705,17 @@ ChannelMediaResource::Suspend(bool aClos
   }
 }
 
 void
 ChannelMediaResource::Resume()
 {
   NS_ASSERTION(NS_IsMainThread(), "Don't call on non-main thread");
 
-  if (mCacheStream.IsClosed()) {
+  if (mClosed) {
     // Nothing to do when we are closed.
     return;
   }
 
   MediaDecoderOwner* owner = mCallback->GetMediaOwner();
   if (!owner) {
     // Shutting down; do nothing.
     return;
@@ -748,17 +752,17 @@ ChannelMediaResource::Resume()
       }
     }
   }
 }
 
 nsresult
 ChannelMediaResource::RecreateChannel()
 {
-  MOZ_DIAGNOSTIC_ASSERT(!mCacheStream.IsClosed());
+  MOZ_DIAGNOSTIC_ASSERT(!mClosed);
 
   nsLoadFlags loadFlags =
     nsICachingChannel::LOAD_BYPASS_LOCAL_CACHE_IF_BUSY |
     nsIChannel::LOAD_CLASSIFY_URI |
     (mLoadInBackground ? nsIRequest::LOAD_BACKGROUND : 0);
 
   MediaDecoderOwner* owner = mCallback->GetMediaOwner();
   if (!owner) {
@@ -874,17 +878,17 @@ ChannelMediaResource::CacheClientNotifyS
     IsSuspendedByCache()));
 }
 
 nsresult
 ChannelMediaResource::Seek(int64_t aOffset, bool aResume)
 {
   MOZ_ASSERT(NS_IsMainThread());
 
-  if (mCacheStream.IsClosed()) {
+  if (mClosed) {
     // Nothing to do when we are closed.
     return NS_OK;
   }
 
   LOG("Seek requested for aOffset [%" PRId64 "]", aOffset);
 
   CloseChannel();
 
--- a/dom/media/ChannelMediaResource.h
+++ b/dom/media/ChannelMediaResource.h
@@ -239,16 +239,18 @@ protected:
   static nsresult CopySegmentToCache(nsIInputStream* aInStream,
                                      void* aClosure,
                                      const char* aFromSegment,
                                      uint32_t aToOffset,
                                      uint32_t aCount,
                                      uint32_t* aWriteCount);
 
   // Main thread access only
+  // True if Close() has been called.
+  bool mClosed = false;
   RefPtr<Listener> mListener;
   // A mono-increasing integer to uniquely identify the channel we are loading.
   uint32_t mLoadID = 0;
   // When this flag is set, if we get a network error we should silently
   // reopen the stream.
   bool               mReopenOnError;
 
   // Any thread access