Bug 1416643. P2 - always access mDidNotifyDataEnded within the lock. draft
authorJW Wang <jwwang@mozilla.com>
Wed, 15 Nov 2017 15:24:26 +0800
changeset 698743 cf1a992a320237c7bb93c55e60cd911b91ee9cf2
parent 698742 e5f5e3ba99e1f86b2953abe9cd6e325743518d9b
child 698889 f09d72cc922c8dd9ebfa1c7a791b3439d2feb3b2
push id89347
push userjwwang@mozilla.com
push dateThu, 16 Nov 2017 02:42:58 +0000
bugs1416643
milestone59.0a1
Bug 1416643. P2 - always access mDidNotifyDataEnded within the lock. MozReview-Commit-ID: 3us659lCEZE
dom/media/MediaCache.cpp
dom/media/MediaCache.h
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -476,17 +476,16 @@ MediaCacheFlusher::Observe(nsISupports *
   }
   return NS_OK;
 }
 
 MediaCacheStream::MediaCacheStream(ChannelMediaResource* aClient,
                                    bool aIsPrivateBrowsing)
   : mMediaCache(nullptr)
   , mClient(aClient)
-  , mDidNotifyDataEnded(false)
   , mIsTransportSeekable(false)
   , mCacheSuspended(false)
   , mChannelEnded(false)
   , mStreamOffset(0)
   , mPlaybackBytesPerSecond(10000)
   , mPinCount(0)
   , mCurrentMode(MODE_PLAYBACK)
   , mMetadataInPartialBlockBuffer(false)
@@ -2699,33 +2698,33 @@ MediaCacheStream::Init(int64_t aContentL
 
 nsresult
 MediaCacheStream::InitAsClone(MediaCacheStream* aOriginal)
 {
   MOZ_ASSERT(aOriginal->IsAvailableForSharing());
   MOZ_ASSERT(!mMediaCache, "Has been initialized.");
   MOZ_ASSERT(aOriginal->mMediaCache, "Don't clone an uninitialized stream.");
 
+  ReentrantMonitorAutoEnter mon(aOriginal->mMediaCache->GetReentrantMonitor());
+
   if (aOriginal->mDidNotifyDataEnded &&
       NS_FAILED(aOriginal->mNotifyDataEndedStatus)) {
     // Streams that ended abnormally are ineligible for cloning.
     return NS_ERROR_FAILURE;
   }
 
   // This needs to be done before OpenStream() to avoid data race.
   mClientSuspended = true;
 
   // Use the same MediaCache as our clone.
   mMediaCache = aOriginal->mMediaCache;
 
   mResourceID = aOriginal->mResourceID;
 
   // Grab cache blocks from aOriginal as readahead blocks for our stream
-  ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
-
   mPrincipal = aOriginal->mPrincipal;
   mStreamLength = aOriginal->mStreamLength;
   mIsTransportSeekable = aOriginal->mIsTransportSeekable;
 
   // Cloned streams are initially suspended, since there is no channel open
   // initially for a clone.
   mCacheSuspended = true;
   mChannelEnded = true;
--- a/dom/media/MediaCache.h
+++ b/dom/media/MediaCache.h
@@ -448,18 +448,16 @@ private:
 
   // Instance of MediaCache to use with this MediaCacheStream.
   RefPtr<MediaCache> mMediaCache;
 
   ChannelMediaResource* const mClient;
 
   // These fields are main-thread-only.
   nsCOMPtr<nsIPrincipal> mPrincipal;
-  // True if CacheClientNotifyDataEnded has been called for this stream.
-  bool                   mDidNotifyDataEnded;
 
   // The following fields must be written holding the cache's monitor and
   // only on the main thread, thus can be read either on the main thread
   // or while holding the cache's monitor.
 
   // Set to true when the stream has been closed either explicitly or
   // due to an internal cache error
   bool mClosed = false;
@@ -498,16 +496,18 @@ private:
   BlockList         mMetadataBlocks;
   // The list of played-back blocks; the first block is the most recently used
   BlockList         mPlayedBlocks;
   // The last reported estimate of the decoder's playback rate
   uint32_t          mPlaybackBytesPerSecond;
   // The number of times this stream has been Pinned without a
   // corresponding Unpin
   uint32_t          mPinCount;
+  // True if CacheClientNotifyDataEnded has been called for this stream.
+  bool              mDidNotifyDataEnded = false;
   // The status used when we did CacheClientNotifyDataEnded. Only valid
   // when mDidNotifyDataEnded is true.
   nsresult          mNotifyDataEndedStatus;
   // The last reported read mode
   ReadMode          mCurrentMode;
   // True if some data in mPartialBlockBuffer has been read as metadata
   bool              mMetadataInPartialBlockBuffer;
   // The load ID of the current channel. Used to check whether the data is