Bug 1418918. P2 - add thread/monitor assertions. r=bechen,gerald
authorJW Wang <jwwang@mozilla.com>
Mon, 20 Nov 2017 16:30:05 +0800
changeset 393766 7358a7b7676ba2d0081db032738d193a2214114b
parent 393765 89b125e739e43c0250d3437871f2a94a5d57421c
child 393767 1fb9066a67c910e1476c12d05094a69acdb8372e
push id56033
push userjwwang@mozilla.com
push dateMon, 27 Nov 2017 05:19:12 +0000
treeherderautoland@7358a7b7676b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbechen, gerald
bugs1418918
milestone59.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 1418918. P2 - add thread/monitor assertions. r=bechen,gerald MozReview-Commit-ID: 3J8pRFnpm77
dom/media/MediaCache.cpp
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -828,16 +828,17 @@ OffsetInBlock(int64_t aOffset)
   return int32_t(aOffset % MediaCache::BLOCK_SIZE);
 }
 
 int32_t
 MediaCache::FindBlockForIncomingData(TimeStamp aNow,
                                      MediaCacheStream* aStream,
                                      int32_t aStreamBlockIndex)
 {
+  MOZ_ASSERT(sThread->IsOnCurrentThread());
   mReentrantMonitor.AssertCurrentThreadIn();
 
   int32_t blockIndex =
     FindReusableBlock(aNow, aStream, aStreamBlockIndex, INT32_MAX);
 
   if (blockIndex < 0 || !IsBlockFree(blockIndex)) {
     // The block returned is already allocated.
     // Don't reuse it if a) there's room to expand the cache or
@@ -858,16 +859,18 @@ MediaCache::FindBlockForIncomingData(Tim
   }
 
   return blockIndex;
 }
 
 bool
 MediaCache::BlockIsReusable(int32_t aBlockIndex)
 {
+  mReentrantMonitor.AssertCurrentThreadIn();
+
   Block* block = &mIndex[aBlockIndex];
   for (uint32_t i = 0; i < block->mOwners.Length(); ++i) {
     MediaCacheStream* stream = block->mOwners[i].mStream;
     if (stream->mPinCount > 0 ||
         uint32_t(OffsetToBlockIndex(stream->mStreamOffset)) ==
           block->mOwners[i].mStreamBlock) {
       return false;
     }
@@ -899,16 +902,17 @@ MediaCache::AppendMostReusableBlock(Bloc
 }
 
 int32_t
 MediaCache::FindReusableBlock(TimeStamp aNow,
                                 MediaCacheStream* aForStream,
                                 int32_t aForStreamBlock,
                                 int32_t aMaxSearchBlockIndex)
 {
+  MOZ_ASSERT(sThread->IsOnCurrentThread());
   mReentrantMonitor.AssertCurrentThreadIn();
 
   uint32_t length = std::min(uint32_t(aMaxSearchBlockIndex), uint32_t(mIndex.Length()));
 
   if (aForStream && aForStreamBlock > 0 &&
       uint32_t(aForStreamBlock) <= aForStream->mBlocks.Length()) {
     int32_t prevCacheBlock = aForStream->mBlocks[aForStreamBlock - 1];
     if (prevCacheBlock >= 0) {
@@ -963,16 +967,18 @@ MediaCache::FindReusableBlock(TimeStamp 
   }
 
   return latestUseBlock;
 }
 
 MediaCache::BlockList*
 MediaCache::GetListForBlock(BlockOwner* aBlock)
 {
+  mReentrantMonitor.AssertCurrentThreadIn();
+
   switch (aBlock->mClass) {
   case METADATA_BLOCK:
     NS_ASSERTION(aBlock->mStream, "Metadata block has no stream?");
     return &aBlock->mStream->mMetadataBlocks;
   case PLAYED_BLOCK:
     NS_ASSERTION(aBlock->mStream, "Metadata block has no stream?");
     return &aBlock->mStream->mPlayedBlocks;
   case READAHEAD_BLOCK:
@@ -982,16 +988,18 @@ MediaCache::GetListForBlock(BlockOwner* 
     NS_ERROR("Invalid block class");
     return nullptr;
   }
 }
 
 MediaCache::BlockOwner*
 MediaCache::GetBlockOwner(int32_t aBlockIndex, MediaCacheStream* aStream)
 {
+  mReentrantMonitor.AssertCurrentThreadIn();
+
   Block* block = &mIndex[aBlockIndex];
   for (uint32_t i = 0; i < block->mOwners.Length(); ++i) {
     if (block->mOwners[i].mStream == aStream)
       return &block->mOwners[i];
   }
   return nullptr;
 }
 
@@ -1037,16 +1045,18 @@ MediaCache::SwapBlocks(int32_t aBlockInd
   }
 
   Verify();
 }
 
 void
 MediaCache::RemoveBlockOwner(int32_t aBlockIndex, MediaCacheStream* aStream)
 {
+  mReentrantMonitor.AssertCurrentThreadIn();
+
   Block* block = &mIndex[aBlockIndex];
   for (uint32_t i = 0; i < block->mOwners.Length(); ++i) {
     BlockOwner* bo = &block->mOwners[i];
     if (bo->mStream == aStream) {
       GetListForBlock(bo)->RemoveBlock(aBlockIndex);
       bo->mStream->mBlocks[bo->mStreamBlock] = -1;
       block->mOwners.RemoveElementAt(i);
       if (block->mOwners.IsEmpty()) {
@@ -1057,16 +1067,18 @@ MediaCache::RemoveBlockOwner(int32_t aBl
   }
 }
 
 void
 MediaCache::AddBlockOwnerAsReadahead(int32_t aBlockIndex,
                                        MediaCacheStream* aStream,
                                        int32_t aStreamBlockIndex)
 {
+  mReentrantMonitor.AssertCurrentThreadIn();
+
   Block* block = &mIndex[aBlockIndex];
   if (block->mOwners.IsEmpty()) {
     mFreeBlocks.RemoveBlock(aBlockIndex);
   }
   BlockOwner* bo = block->mOwners.AppendElement();
   mBlockOwnersWatermark =
     std::max(mBlockOwnersWatermark, uint32_t(block->mOwners.Length()));
   bo->mStream = aStream;
@@ -1097,16 +1109,17 @@ MediaCache::FreeBlock(int32_t aBlock)
   block->mOwners.Clear();
   mFreeBlocks.AddFirstBlock(aBlock);
   Verify();
 }
 
 TimeDuration
 MediaCache::PredictNextUse(TimeStamp aNow, int32_t aBlock)
 {
+  MOZ_ASSERT(sThread->IsOnCurrentThread());
   mReentrantMonitor.AssertCurrentThreadIn();
   NS_ASSERTION(!IsBlockFree(aBlock), "aBlock is free");
 
   Block* block = &mIndex[aBlock];
   // Blocks can be belong to multiple streams. The predicted next use
   // time is the earliest time predicted by any of the streams.
   TimeDuration result;
   for (uint32_t i = 0; i < block->mOwners.Length(); ++i) {
@@ -1152,16 +1165,17 @@ MediaCache::PredictNextUse(TimeStamp aNo
     }
   }
   return result;
 }
 
 TimeDuration
 MediaCache::PredictNextUseForIncomingData(MediaCacheStream* aStream)
 {
+  MOZ_ASSERT(sThread->IsOnCurrentThread());
   mReentrantMonitor.AssertCurrentThreadIn();
 
   int64_t bytesAhead = aStream->mChannelOffset - aStream->mStreamOffset;
   if (bytesAhead <= -BLOCK_SIZE) {
     // Hmm, no idea when data behind us will be used. Guess 24 hours.
     return TimeDuration::FromSeconds(24*60*60);
   }
   if (bytesAhead <= 0)
@@ -1622,18 +1636,17 @@ MediaCache::Verify()
       lastStreamBlock = nextStreamBlock;
       block = stream->mReadaheadBlocks.GetNextBlock(block);
     }
   }
 }
 #endif
 
 void
-MediaCache::InsertReadaheadBlock(BlockOwner* aBlockOwner,
-                                   int32_t aBlockIndex)
+MediaCache::InsertReadaheadBlock(BlockOwner* aBlockOwner, int32_t aBlockIndex)
 {
   mReentrantMonitor.AssertCurrentThreadIn();
 
   // Find the last block whose stream block is before aBlockIndex's
   // stream block, and insert after it
   MediaCacheStream* stream = aBlockOwner->mStream;
   int32_t readaheadIndex = stream->mReadaheadBlocks.GetLastBlock();
   while (readaheadIndex >= 0) {
@@ -1654,16 +1667,17 @@ MediaCache::InsertReadaheadBlock(BlockOw
 
 void
 MediaCache::AllocateAndWriteBlock(MediaCacheStream* aStream,
                                   int32_t aStreamBlockIndex,
                                   MediaCacheStream::ReadMode aMode,
                                   Span<const uint8_t> aData1,
                                   Span<const uint8_t> aData2)
 {
+  MOZ_ASSERT(sThread->IsOnCurrentThread());
   mReentrantMonitor.AssertCurrentThreadIn();
 
   // Remove all cached copies of this block
   ResourceStreamIterator iter(this, aStream->mResourceID);
   while (MediaCacheStream* stream = iter.Next()) {
     while (aStreamBlockIndex >= int32_t(stream->mBlocks.Length())) {
       stream->mBlocks.AppendElement(-1);
     }
@@ -2100,16 +2114,18 @@ MediaCacheStream::NotifyDataReceived(uin
   // avoid waking up reader threads unnecessarily
   mon.NotifyAll();
 }
 
 void
 MediaCacheStream::FlushPartialBlockInternal(bool aNotifyAll,
                                             ReentrantMonitorAutoEnter& aReentrantMonitor)
 {
+  MOZ_ASSERT(OwnerThread()->IsOnCurrentThread());
+
   int32_t blockIndex = OffsetToBlockIndexUnchecked(mChannelOffset);
   int32_t blockOffset = OffsetInBlock(mChannelOffset);
   if (blockOffset > 0) {
     LOG("Stream %p writing partial block: [%d] bytes; "
         "mStreamOffset [%" PRId64 "] mChannelOffset[%"
         PRId64 "] mStreamLength [%" PRId64 "] notifying: [%s]",
         this, blockOffset, mStreamOffset, mChannelOffset, mStreamLength,
         aNotifyAll ? "yes" : "no");
@@ -2133,16 +2149,17 @@ MediaCacheStream::FlushPartialBlockInter
   }
 }
 
 void
 MediaCacheStream::NotifyDataEndedInternal(uint32_t aLoadID,
                                           nsresult aStatus,
                                           bool aReopenOnError)
 {
+  MOZ_ASSERT(OwnerThread()->IsOnCurrentThread());
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
 
   if (mClosed || aLoadID != mLoadID) {
     // Nothing to do if the stream is closed or a new load has begun.
     return;
   }
 
   // Note that aStatus might have succeeded --- this might be a normal close
@@ -2268,17 +2285,19 @@ MediaCacheStream::~MediaCacheStream()
       lengthKb);
   Telemetry::Accumulate(Telemetry::HistogramID::MEDIACACHESTREAM_LENGTH_KB,
                         lengthKb);
 }
 
 bool
 MediaCacheStream::AreAllStreamsForResourceSuspended()
 {
+  MOZ_ASSERT(!NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
+
   MediaCache::ResourceStreamIterator iter(mMediaCache, mResourceID);
   // Look for a stream that's able to read the data we need
   int64_t dataOffset = -1;
   while (MediaCacheStream* stream = iter.Next()) {
     if (stream->mCacheSuspended || stream->mChannelEnded || stream->mClosed) {
       continue;
     }
     if (dataOffset < 0) {
@@ -2319,65 +2338,72 @@ MediaCacheStream::Close()
   // it from CloseInternal since that gets called by Update() itself
   // sometimes, and we try to not to queue updates from Update().
   mMediaCache->QueueUpdate();
 }
 
 void
 MediaCacheStream::Pin()
 {
+  // TODO: Assert non-main thread.
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   ++mPinCount;
   // Queue an Update since we may no longer want to read more into the
   // cache, if this stream's block have become non-evictable
   mMediaCache->QueueUpdate();
 }
 
 void
 MediaCacheStream::Unpin()
 {
+  // TODO: Assert non-main thread.
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   NS_ASSERTION(mPinCount > 0, "Unbalanced Unpin");
   --mPinCount;
   // Queue an Update since we may be able to read more into the
   // cache, if this stream's block have become evictable
   mMediaCache->QueueUpdate();
 }
 
 int64_t
 MediaCacheStream::GetLength()
 {
+  // TODO: Assert non-main thread.
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   return mStreamLength;
 }
 
 int64_t
 MediaCacheStream::GetOffset() const
 {
+  // TODO: Assert non-main thread.
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   return mChannelOffset;
 }
 
 int64_t
 MediaCacheStream::GetNextCachedData(int64_t aOffset)
 {
+  MOZ_ASSERT(!NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   return GetNextCachedDataInternal(aOffset);
 }
 
 int64_t
 MediaCacheStream::GetCachedDataEnd(int64_t aOffset)
 {
+  // TODO: Assert non-main thread.
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   return GetCachedDataEndInternal(aOffset);
 }
 
 bool
 MediaCacheStream::IsDataCachedToEndOfStream(int64_t aOffset)
 {
+  MOZ_ASSERT(!NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   if (mStreamLength < 0)
     return false;
   return GetCachedDataEndInternal(aOffset) >= mStreamLength;
 }
 
 int64_t
 MediaCacheStream::GetCachedDataEndInternal(int64_t aOffset)
@@ -2452,16 +2478,17 @@ MediaCacheStream::GetNextCachedDataInter
 
   NS_NOTREACHED("Should return in loop");
   return -1;
 }
 
 void
 MediaCacheStream::SetReadMode(ReadMode aMode)
 {
+  // TODO: Assert non-main thread.
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   if (aMode == mCurrentMode)
     return;
   mCurrentMode = aMode;
   mMediaCache->QueueUpdate();
 }
 
 void
@@ -2591,18 +2618,17 @@ MediaCacheStream::ReadBlockFromCache(int
   }
 
   return bytesRead;
 }
 
 nsresult
 MediaCacheStream::Read(char* aBuffer, uint32_t aCount, uint32_t* aBytes)
 {
-  NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
-
+  MOZ_ASSERT(!NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
 
   // Cache the offset in case it is changed again when we are waiting for the
   // monitor to be notified to avoid reading at the wrong position.
   auto streamOffset = mStreamOffset;
 
   // The buffer we are about to fill.
   auto buffer = MakeSpan<char>(aBuffer, aCount);
@@ -2689,27 +2715,27 @@ MediaCacheStream::Read(char* aBuffer, ui
   mStreamOffset = streamOffset;
   return NS_OK;
 }
 
 nsresult
 MediaCacheStream::ReadAt(int64_t aOffset, char* aBuffer,
                          uint32_t aCount, uint32_t* aBytes)
 {
-  NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
-
+  MOZ_ASSERT(!NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
   nsresult rv = Seek(aOffset);
   if (NS_FAILED(rv)) return rv;
   return Read(aBuffer, aCount, aBytes);
 }
 
 nsresult
 MediaCacheStream::ReadFromCache(char* aBuffer, int64_t aOffset, uint32_t aCount)
 {
+  MOZ_ASSERT(!NS_IsMainThread());
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
 
   // The buffer we are about to fill.
   auto buffer = MakeSpan<char>(aBuffer, aCount);
 
   // Read one block (or part of a block) at a time
   int64_t streamOffset = aOffset;
   while (!buffer.IsEmpty()) {
@@ -2837,16 +2863,17 @@ MediaCacheStream::InitAsClone(MediaCache
 nsIEventTarget*
 MediaCacheStream::OwnerThread() const
 {
   return mMediaCache->OwnerThread();
 }
 
 nsresult MediaCacheStream::GetCachedRanges(MediaByteRangeSet& aRanges)
 {
+  MOZ_ASSERT(!NS_IsMainThread());
   // Take the monitor, so that the cached data ranges can't grow while we're
   // trying to loop over them.
   ReentrantMonitorAutoEnter mon(mMediaCache->GetReentrantMonitor());
 
   // We must be pinned while running this, otherwise the cached data ranges may
   // shrink while we're trying to loop over them.
   NS_ASSERTION(mPinCount > 0, "Must be pinned");