Bug 1371882 - MediaCache::ResourceStreamIterator is given the MediaCache to work with - r=cpearce draft
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 08 Jun 2017 15:32:13 +1200
changeset 595146 d69d52c68512041dd61c5782e3406aa66a487a28
parent 595145 1570e30787ba486f9436b4b05aa3cfa0329d1ee7
child 595147 0b3e6fae71207076812b5cb9172d4497d3e68ea2
push id64265
push usergsquelart@mozilla.com
push dateFri, 16 Jun 2017 03:37:56 +0000
reviewerscpearce
bugs1371882
milestone56.0a1
Bug 1371882 - MediaCache::ResourceStreamIterator is given the MediaCache to work with - r=cpearce MozReview-Commit-ID: 3Xl4WNESdnY
dom/media/MediaCache.cpp
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -257,31 +257,37 @@ public:
 
   ReentrantMonitor& GetReentrantMonitor() { return mReentrantMonitor; }
 
   /**
    * An iterator that makes it easy to iterate through all streams that
    * have a given resource ID and are not closed.
    * Can be used on the main thread or while holding the media cache lock.
    */
-  class ResourceStreamIterator {
+  class ResourceStreamIterator
+  {
   public:
-    explicit ResourceStreamIterator(int64_t aResourceID) :
-      mResourceID(aResourceID), mNext(0) {}
+    ResourceStreamIterator(MediaCache* aMediaCache, int64_t aResourceID)
+      : mMediaCache(aMediaCache)
+      , mResourceID(aResourceID)
+      , mNext(0)
+    {
+    }
     MediaCacheStream* Next()
     {
-      while (mNext < gMediaCache->mStreams.Length()) {
-        MediaCacheStream* stream = gMediaCache->mStreams[mNext];
+      while (mNext < mMediaCache->mStreams.Length()) {
+        MediaCacheStream* stream = mMediaCache->mStreams[mNext];
         ++mNext;
         if (stream->GetResourceID() == mResourceID && !stream->IsClosed())
           return stream;
       }
       return nullptr;
     }
   private:
+    MediaCache* mMediaCache;
     int64_t  mResourceID;
     uint32_t mNext;
   };
 
 protected:
   // Find a free or reusable block and return its index. If there are no
   // free blocks and no reusable blocks, add a new block to the cache
   // and return it. Can return -1 on OOM.
@@ -1405,17 +1411,17 @@ MediaCache::Update()
       // Reads will also be woken up.
       ReentrantMonitorAutoEnter mon(mReentrantMonitor);
       stream->CloseInternal(mon);
     }
   }
 
   // Notify streams about the suspended status changes.
   for (uint32_t i = 0; i < mSuspendedStatusToNotify.Length(); ++i) {
-    MediaCache::ResourceStreamIterator iter(mSuspendedStatusToNotify[i]);
+    MediaCache::ResourceStreamIterator iter(this, mSuspendedStatusToNotify[i]);
     while (MediaCacheStream* stream = iter.Next()) {
       stream->mClient->CacheClientNotifySuspendedStatusChanged();
     }
   }
   mSuspendedStatusToNotify.Clear();
 }
 
 class UpdateEvent : public Runnable
@@ -1525,17 +1531,17 @@ MediaCache::AllocateAndWriteBlock(
   MediaCacheStream* aStream, MediaCacheStream::ReadMode aMode,
   Span<const uint8_t> aData1, Span<const uint8_t> aData2)
 {
   mReentrantMonitor.AssertCurrentThreadIn();
 
   int32_t streamBlockIndex = aStream->mChannelOffset/BLOCK_SIZE;
 
   // Remove all cached copies of this block
-  ResourceStreamIterator iter(aStream->mResourceID);
+  ResourceStreamIterator iter(this, aStream->mResourceID);
   while (MediaCacheStream* stream = iter.Next()) {
     while (streamBlockIndex >= int32_t(stream->mBlocks.Length())) {
       stream->mBlocks.AppendElement(-1);
     }
     if (stream->mBlocks[streamBlockIndex] >= 0) {
       // We no longer want to own this block
       int32_t globalBlockIndex = stream->mBlocks[streamBlockIndex];
       LOG("Released block %d from stream %p block %d(%" PRId64 ")",
@@ -1551,17 +1557,17 @@ MediaCache::AllocateAndWriteBlock(
   int32_t blockIndex = FindBlockForIncomingData(now, aStream);
   if (blockIndex >= 0) {
     FreeBlock(blockIndex);
 
     Block* block = &mIndex[blockIndex];
     LOG("Allocated block %d to stream %p block %d(%" PRId64 ")",
         blockIndex, aStream, streamBlockIndex, streamBlockIndex*BLOCK_SIZE);
 
-    ResourceStreamIterator iter(aStream->mResourceID);
+    ResourceStreamIterator iter(this, aStream->mResourceID);
     while (MediaCacheStream* stream = iter.Next()) {
       BlockOwner* bo = block->mOwners.AppendElement();
       if (!bo) {
         // Roll back mOwners if any allocation fails.
         block->mOwners.Clear();
         return;
       }
       mBlockOwnersWatermark =
@@ -1825,17 +1831,17 @@ MediaCacheStream::NotifyDataReceived(int
   }
 
   // Update principals before putting the data in the cache. This is important,
   // we want to make sure all principals are updated before any consumer
   // can see the new data.
   // We do this without holding the cache monitor, in case the client wants
   // to do something that takes a lock.
   {
-    MediaCache::ResourceStreamIterator iter(mResourceID);
+    MediaCache::ResourceStreamIterator iter(gMediaCache, mResourceID);
     while (MediaCacheStream* stream = iter.Next()) {
       if (stream->UpdatePrincipal(aPrincipal)) {
         stream->mClient->CacheClientNotifyPrincipalChanged();
       }
     }
   }
 
   ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
@@ -1871,17 +1877,17 @@ MediaCacheStream::NotifyDataReceived(int
       memcpy(mPartialBlockBuffer.get() + blockOffset, data, chunkSize);
     }
 
     mChannelOffset += chunkSize;
     size -= chunkSize;
     data += chunkSize;
   }
 
-  MediaCache::ResourceStreamIterator iter(mResourceID);
+  MediaCache::ResourceStreamIterator iter(gMediaCache, mResourceID);
   while (MediaCacheStream* stream = iter.Next()) {
     if (stream->mStreamLength >= 0) {
       // The stream is at least as long as what we've read
       stream->mStreamLength = std::max(stream->mStreamLength, mChannelOffset);
     }
     stream->mClient->CacheClientNotifyDataReceived();
   }
 
@@ -1952,17 +1958,17 @@ MediaCacheStream::NotifyDataEnded(nsresu
   }
 
   // It is prudent to update channel/cache status before calling
   // CacheClientNotifyDataEnded() which will read |mChannelEnded|.
   FlushPartialBlockInternal(true, mon);
   mChannelEnded = true;
   gMediaCache->QueueUpdate();
 
-  MediaCache::ResourceStreamIterator iter(mResourceID);
+  MediaCache::ResourceStreamIterator iter(gMediaCache, mResourceID);
   while (MediaCacheStream* stream = iter.Next()) {
     if (NS_SUCCEEDED(aStatus)) {
       // We read the whole stream, so remember the true length
       stream->mStreamLength = mChannelOffset;
     }
     if (!stream->mDidNotifyDataEnded) {
       stream->mDidNotifyDataEnded = true;
       stream->mNotifyDataEndedStatus = aStatus;
@@ -2019,17 +2025,17 @@ MediaCacheStream::IsTransportSeekable()
   ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
   return mIsTransportSeekable;
 }
 
 bool
 MediaCacheStream::AreAllStreamsForResourceSuspended()
 {
   ReentrantMonitorAutoEnter mon(gMediaCache->GetReentrantMonitor());
-  MediaCache::ResourceStreamIterator iter(mResourceID);
+  MediaCache::ResourceStreamIterator iter(gMediaCache, 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) {
       dataOffset = GetCachedDataEndInternal(mStreamOffset);
@@ -2327,17 +2333,17 @@ MediaCacheStream::Read(char* aBuffer, ui
         break;
       }
 
       // See if the data is available in the partial cache block of any
       // stream reading this resource. We need to do this in case there is
       // another stream with this resource that has all the data to the end of
       // the stream but the data doesn't end on a block boundary.
       MediaCacheStream* streamWithPartialBlock = nullptr;
-      MediaCache::ResourceStreamIterator iter(mResourceID);
+      MediaCache::ResourceStreamIterator iter(gMediaCache, mResourceID);
       while (MediaCacheStream* stream = iter.Next()) {
         if (uint32_t(stream->mChannelOffset/BLOCK_SIZE) == streamBlock &&
             streamOffset < stream->mChannelOffset) {
           streamWithPartialBlock = stream;
           break;
         }
       }
       if (streamWithPartialBlock) {