Bug 1416643. P2 - always access mDidNotifyDataEnded within the lock.
MozReview-Commit-ID: 3us659lCEZE
--- 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