Bug 1371882 - Remove MediaBlockCacheBase::Close() - r?cpearce draft
authorGerald Squelart <gsquelart@mozilla.com>
Thu, 15 Jun 2017 14:10:05 +1200
changeset 595164 17aaf07adeb9a7468c6aeea101b1a53f1a43235e
parent 595163 eed65eafbabe59ca7c02f2c2c43ddd8ff349e99b
child 595165 507ffe036c060afb18bba30c3afa0884ee06a99e
push id64265
push usergsquelart@mozilla.com
push dateFri, 16 Jun 2017 03:37:56 +0000
reviewerscpearce
bugs1371882
milestone56.0a1
Bug 1371882 - Remove MediaBlockCacheBase::Close() - r?cpearce The only external use of Close was always followed by an implicit destruction (by resetting the RefPtr), so we don't need to expose it, and it can be done from the destructor. FileBlockCache keeps its Close() function for internal use. Also, FileBlockCache::mIsOpen is redundant, as it's true iff mThread is not null. MozReview-Commit-ID: LV7YVrwJvGG
dom/media/FileBlockCache.cpp
dom/media/FileBlockCache.h
dom/media/MediaBlockCacheBase.h
dom/media/MediaCache.cpp
dom/media/MemoryBlockCache.cpp
dom/media/MemoryBlockCache.h
--- a/dom/media/FileBlockCache.cpp
+++ b/dom/media/FileBlockCache.cpp
@@ -28,30 +28,30 @@ CloseFD(PRFileDesc* aFD)
   if (prrc != PR_SUCCESS) {
     NS_WARNING("PR_Close() failed.");
   }
 }
 
 void
 FileBlockCache::SetCacheFile(PRFileDesc* aFD)
 {
-  LOG("SetFD(aFD=%p) mIsOpen=%d", aFD, mIsOpen);
+  LOG("SetFD(aFD=%p) mThread=%p", aFD, mThread.get());
 
   if (!aFD) {
     // Failed to get a temporary file. Shutdown.
     Close();
     return;
   }
   {
     MutexAutoLock lock(mFileMutex);
     mFD = aFD;
   }
   {
     MutexAutoLock lock(mDataMutex);
-    if (mIsOpen) {
+    if (mThread) {
       // Still open, complete the initialization.
       mInitialized = true;
       if (mIsWriteScheduled) {
         // A write was scheduled while waiting for FD. We need to run/dispatch a
         // task to service the request.
         nsCOMPtr<nsIRunnable> event = mozilla::NewRunnableMethod(
           "FileBlockCache::SetCacheFile -> PerformBlockIOs",
           this,
@@ -78,17 +78,16 @@ FileBlockCache::Init()
   MutexAutoLock mon(mDataMutex);
   nsresult rv = NS_NewNamedThread("FileBlockCache",
                                   getter_AddRefs(mThread),
                                   nullptr,
                                   SharedThreadPool::kStackSize);
   if (NS_FAILED(rv)) {
     return rv;
   }
-  mIsOpen = true;
 
   if (XRE_IsParentProcess()) {
     RefPtr<FileBlockCache> self = this;
     rv = mThread->Dispatch(NS_NewRunnableFunction([self] {
       PRFileDesc* fd = nullptr;
       nsresult rv = NS_OpenAnonymousTemporaryFile(&fd);
       if (NS_SUCCEEDED(rv)) {
         self->SetCacheFile(fd);
@@ -106,42 +105,38 @@ FileBlockCache::Init()
   if (NS_FAILED(rv)) {
     Close();
   }
 
   return rv;
 }
 
 FileBlockCache::FileBlockCache()
-  : mFileMutex("MediaCache.Writer.IO.Mutex"),
-    mFD(nullptr),
-    mFDCurrentPos(0),
-    mDataMutex("MediaCache.Writer.Data.Mutex"),
-    mIsWriteScheduled(false),
-    mIsReading(false),
-    mIsOpen(false)
+  : mFileMutex("MediaCache.Writer.IO.Mutex")
+  , mFD(nullptr)
+  , mFDCurrentPos(0)
+  , mDataMutex("MediaCache.Writer.Data.Mutex")
+  , mIsWriteScheduled(false)
+  , mIsReading(false)
 {
 }
 
 FileBlockCache::~FileBlockCache()
 {
-  NS_ASSERTION(!mIsOpen, "Should Close() FileBlockCache before destroying");
+  Close();
 }
 
-void FileBlockCache::Close()
+void
+FileBlockCache::Close()
 {
   LOG("Close()");
 
   nsCOMPtr<nsIThread> thread;
   {
     MutexAutoLock mon(mDataMutex);
-    if (!mIsOpen) {
-      return;
-    }
-    mIsOpen = false;
     if (!mThread) {
       return;
     }
     thread.swap(mThread);
   }
 
   PRFileDesc* fd;
   {
@@ -178,18 +173,19 @@ ContainerContains(const Container& aCont
 }
 
 nsresult
 FileBlockCache::WriteBlock(uint32_t aBlockIndex,
   Span<const uint8_t> aData1, Span<const uint8_t> aData2)
 {
   MutexAutoLock mon(mDataMutex);
 
-  if (!mIsOpen)
+  if (!mThread) {
     return NS_ERROR_FAILURE;
+  }
 
   // Check if we've already got a pending write scheduled for this block.
   mBlockChanges.EnsureLengthAtLeast(aBlockIndex + 1);
   bool blockAlreadyHadPendingChange = mBlockChanges[aBlockIndex] != nullptr;
   mBlockChanges[aBlockIndex] = new BlockChange(aData1, aData2);
 
   if (!blockAlreadyHadPendingChange || !ContainerContains(mChangeIndexList, aBlockIndex)) {
     // We either didn't already have a pending change for this block, or we
@@ -205,17 +201,17 @@ FileBlockCache::WriteBlock(uint32_t aBlo
   EnsureWriteScheduled();
 
   return NS_OK;
 }
 
 void FileBlockCache::EnsureWriteScheduled()
 {
   mDataMutex.AssertCurrentThreadOwns();
-  MOZ_ASSERT(mIsOpen);
+  MOZ_ASSERT(mThread);
 
   if (mIsWriteScheduled || mIsReading) {
     return;
   }
   mIsWriteScheduled = true;
   if (!mInitialized) {
     // We're still waiting on a file descriptor. When it arrives,
     // the write will be scheduled.
@@ -306,20 +302,20 @@ nsresult FileBlockCache::MoveBlockInFile
 void
 FileBlockCache::PerformBlockIOs()
 {
   NS_ASSERTION(!NS_IsMainThread(), "Don't call on main thread");
   MutexAutoLock mon(mDataMutex);
   NS_ASSERTION(!mChangeIndexList.empty(), "Only dispatch when there's work to do");
   NS_ASSERTION(mIsWriteScheduled, "Should report write running or scheduled.");
 
-  LOG("Run() mFD=%p mIsOpen=%d", mFD, mIsOpen);
+  LOG("Run() mFD=%p mThread=%p", mFD, mThread.get());
 
   while (!mChangeIndexList.empty()) {
-    if (!mIsOpen) {
+    if (!mThread) {
       // We've been closed, abort, discarding unwritten changes.
       mIsWriteScheduled = false;
       return;
     }
 
     if (mIsReading) {
       // We're trying to read; postpone all writes. (Reader will resume writes.)
       mIsWriteScheduled = false;
@@ -370,18 +366,19 @@ FileBlockCache::PerformBlockIOs()
 
 nsresult FileBlockCache::Read(int64_t aOffset,
                               uint8_t* aData,
                               int32_t aLength,
                               int32_t* aBytes)
 {
   MutexAutoLock mon(mDataMutex);
 
-  if (!mIsOpen || (aOffset / BLOCK_SIZE) > INT32_MAX)
+  if (!mThread || (aOffset / BLOCK_SIZE) > INT32_MAX) {
     return NS_ERROR_FAILURE;
+  }
 
   mIsReading = true;
   auto exitRead = MakeScopeExit([&] {
     mIsReading = false;
     if (!mChangeIndexList.empty()) {
       // mReading has stopped or prevented pending writes, resume them.
       EnsureWriteScheduled();
     }
@@ -439,18 +436,19 @@ nsresult FileBlockCache::Read(int64_t aO
   *aBytes = aLength - bytesToRead;
   return NS_OK;
 }
 
 nsresult FileBlockCache::MoveBlock(int32_t aSourceBlockIndex, int32_t aDestBlockIndex)
 {
   MutexAutoLock mon(mDataMutex);
 
-  if (!mIsOpen)
+  if (!mThread) {
     return NS_ERROR_FAILURE;
+  }
 
   mBlockChanges.EnsureLengthAtLeast(std::max(aSourceBlockIndex, aDestBlockIndex) + 1);
 
   // The source block's contents may be the destination of another pending
   // move, which in turn can be the destination of another pending move,
   // etc. Resolve the final source block, so that if one of the blocks in
   // the chain of moves is overwritten, we don't lose the reference to the
   // contents of the destination block.
--- a/dom/media/FileBlockCache.h
+++ b/dom/media/FileBlockCache.h
@@ -58,19 +58,16 @@ public:
   FileBlockCache();
 
 protected:
   virtual ~FileBlockCache();
 
 public:
   nsresult Init() override;
 
-  // Closes writer, shuts down thread.
-  void Close() override;
-
   // Can be called on any thread. This defers to a non-main thread.
   nsresult WriteBlock(uint32_t aBlockIndex,
                       Span<const uint8_t> aData1,
                       Span<const uint8_t> aData2) override;
 
   // Synchronously reads data from file. May read from file or memory
   // depending on whether written blocks have been flushed to file yet.
   // Not recommended to be called from the main thread, as can cause jank.
@@ -134,16 +131,19 @@ public:
 
 private:
   int64_t BlockIndexToOffset(int32_t aBlockIndex) {
     return static_cast<int64_t>(aBlockIndex) * BLOCK_SIZE;
   }
 
   void SetCacheFile(PRFileDesc* aFD);
 
+  // Close file in thread and terminate thread.
+  void Close();
+
   // Performs block writes and block moves on its own thread.
   void PerformBlockIOs();
 
   // Mutex which controls access to mFD and mFDCurrentPos. Don't hold
   // mDataMutex while holding mFileMutex! mFileMutex must be owned
   // while accessing any of the following data fields or methods.
   Mutex mFileMutex;
   // Moves a block already committed to file.
@@ -186,18 +186,16 @@ private:
   // Queue of pending block indexes that need to be written or moved.
   std::deque<int32_t> mChangeIndexList;
   // True if we've dispatched an event to commit all pending block changes
   // to file on mThread.
   bool mIsWriteScheduled;
   // True when a read is happening. Pending writes may be postponed, to give
   // higher priority to reads (which may be blocking the caller).
   bool mIsReading;
-  // True if the writer is ready to enqueue writes.
-  bool mIsOpen;
   // True if we've got a temporary file descriptor. Note: we don't use mFD
   // directly as that's synchronized via mFileMutex and we need to make
   // decisions about whether we can write while holding mDataMutex.
   bool mInitialized = false;
 };
 
 } // End namespace mozilla.
 
--- a/dom/media/MediaBlockCacheBase.h
+++ b/dom/media/MediaBlockCacheBase.h
@@ -45,19 +45,16 @@ public:
   static const int32_t BLOCK_SIZE = MediaCacheStream::BLOCK_SIZE;
 
 protected:
   virtual ~MediaBlockCacheBase() {}
 
 public:
   virtual nsresult Init() = 0;
 
-  // Closes writer, shuts down thread.
-  virtual void Close() = 0;
-
   // Can be called on any thread. This defers to a non-main thread.
   virtual nsresult WriteBlock(uint32_t aBlockIndex,
                               Span<const uint8_t> aData1,
                               Span<const uint8_t> aData2) = 0;
 
   // Synchronously reads data from file. May read from file or memory
   // depending on whether written blocks have been flushed to file yet.
   // Not recommended to be called from the main thread, as can cause jank.
--- a/dom/media/MediaCache.cpp
+++ b/dom/media/MediaCache.cpp
@@ -274,20 +274,16 @@ protected:
   }
 
   ~MediaCache()
   {
     MediaCacheFlusher::UnregisterMediaCache(this);
     NS_ASSERTION(mStreams.IsEmpty(), "Stream(s) still open!");
     Truncate();
     NS_ASSERTION(mIndex.Length() == 0, "Blocks leaked?");
-    if (mBlockCache) {
-      mBlockCache->Close();
-      mBlockCache = nullptr;
-    }
     if (mContentLength <= 0) {
       // Only gather "MEDIACACHE" telemetry for the file-based cache.
       LOG("MediaCache::~MediaCache(this=%p) MEDIACACHE_WATERMARK_KB=%u",
           this,
           unsigned(mIndexWatermark * MediaCache::BLOCK_SIZE / 1024));
       Telemetry::Accumulate(
         Telemetry::HistogramID::MEDIACACHE_WATERMARK_KB,
         uint32_t(mIndexWatermark * MediaCache::BLOCK_SIZE / 1024));
@@ -703,20 +699,17 @@ MediaCache::Flush()
 
   for (uint32_t blockIndex = 0; blockIndex < mIndex.Length(); ++blockIndex) {
     FreeBlock(blockIndex);
   }
 
   // Truncate file, close it, and reopen
   Truncate();
   NS_ASSERTION(mIndex.Length() == 0, "Blocks leaked?");
-  if (mBlockCache) {
-    mBlockCache->Close();
-    mBlockCache = nullptr;
-  }
+  mBlockCache = nullptr;
   Init();
 }
 
 void
 MediaCache::CloseStreamsForPrivateBrowsing()
 {
   MOZ_ASSERT(NS_IsMainThread());
   for (MediaCacheStream* s : mStreams) {
--- a/dom/media/MemoryBlockCache.cpp
+++ b/dom/media/MemoryBlockCache.cpp
@@ -41,17 +41,16 @@ MemoryBlockCache::MemoryBlockCache(int64
         this);
     Telemetry::Accumulate(Telemetry::HistogramID::MEMORYBLOCKCACHE_ERRORS,
                           InitUnderuse);
   }
 }
 
 MemoryBlockCache::~MemoryBlockCache()
 {
-  MOZ_ASSERT(mBuffer.IsEmpty());
 }
 
 bool
 MemoryBlockCache::EnsureBufferCanContain(size_t aContentLength)
 {
   mMutex.AssertCurrentThreadOwns();
   if (aContentLength == 0) {
     return true;
@@ -81,24 +80,16 @@ MemoryBlockCache::Init()
                           InitAllocation);
     return NS_ERROR_FAILURE;
   }
   // Ignore initial growth.
   mHasGrown = false;
   return NS_OK;
 }
 
-void
-MemoryBlockCache::Close()
-{
-  LOG("@%p Close()", this);
-  MutexAutoLock lock(mMutex);
-  mBuffer.SetLength(0);
-}
-
 nsresult
 MemoryBlockCache::WriteBlock(uint32_t aBlockIndex,
                              Span<const uint8_t> aData1,
                              Span<const uint8_t> aData2)
 {
   MutexAutoLock lock(mMutex);
 
   size_t offset = BlockIndexToOffset(aBlockIndex);
--- a/dom/media/MemoryBlockCache.h
+++ b/dom/media/MemoryBlockCache.h
@@ -36,19 +36,16 @@ public:
 
 protected:
   virtual ~MemoryBlockCache();
 
 public:
   // Allocate initial buffer.
   virtual nsresult Init() override;
 
-  // Empty buffer.
-  virtual void Close() override;
-
   // Can be called on any thread.
   virtual nsresult WriteBlock(uint32_t aBlockIndex,
                               Span<const uint8_t> aData1,
                               Span<const uint8_t> aData2) override;
 
   // Synchronously reads data from buffer.
   virtual nsresult Read(int64_t aOffset,
                         uint8_t* aData,