Bug 1371882 - Remove FileBlockCache's dependency on Runnable - r=cpearce draft
authorGerald Squelart <gsquelart@mozilla.com>
Fri, 09 Jun 2017 14:51:17 +1200
changeset 595157 da8d1ce70dea0e49c9f145fdb5134814194887a1
parent 595156 6b975af79ceafe876e3ea780a6d3a1ce7d319281
child 595158 87b067ce2b9793f896880da4cfaf8624214ddd92
push id64265
push usergsquelart@mozilla.com
push dateFri, 16 Jun 2017 03:37:56 +0000
reviewerscpearce
bugs1371882
milestone56.0a1
Bug 1371882 - Remove FileBlockCache's dependency on Runnable - r=cpearce This is necessary before we can make FileBlockCache depend on another ref-counted base in the following patch. MozReview-Commit-ID: 8bfNwQhY8k0
dom/media/FileBlockCache.cpp
dom/media/FileBlockCache.h
--- a/dom/media/FileBlockCache.cpp
+++ b/dom/media/FileBlockCache.cpp
@@ -47,17 +47,21 @@ FileBlockCache::SetCacheFile(PRFileDesc*
   {
     MutexAutoLock lock(mDataMutex);
     if (mIsOpen) {
       // 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.
-        mThread->Dispatch(this, NS_DISPATCH_NORMAL);
+        nsCOMPtr<nsIRunnable> event = mozilla::NewRunnableMethod(
+          "FileBlockCache::SetCacheFile -> PerformBlockIOs",
+          this,
+          &FileBlockCache::PerformBlockIOs);
+        mThread->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
       }
       return;
     }
   }
   // We've been closed while waiting for the file descriptor.
   // Close the file descriptor we've just received, if still there.
   MutexAutoLock lock(mFileMutex);
   if (mFD) {
@@ -212,17 +216,21 @@ void FileBlockCache::EnsureWriteSchedule
     return;
   }
   mIsWriteScheduled = true;
   if (!mInitialized) {
     // We're still waiting on a file descriptor. When it arrives,
     // the write will be scheduled.
     return;
   }
-  mThread->Dispatch(this, NS_DISPATCH_NORMAL);
+  nsCOMPtr<nsIRunnable> event = mozilla::NewRunnableMethod(
+    "FileBlockCache::EnsureWriteScheduled -> PerformBlockIOs",
+    this,
+    &FileBlockCache::PerformBlockIOs);
+  mThread->Dispatch(event.forget(), NS_DISPATCH_NORMAL);
 }
 
 nsresult FileBlockCache::Seek(int64_t aOffset)
 {
   mFileMutex.AssertCurrentThreadOwns();
 
   if (mFDCurrentPos != aOffset) {
     MOZ_ASSERT(mFD);
@@ -290,36 +298,37 @@ nsresult FileBlockCache::MoveBlockInFile
                              buf,
                              BLOCK_SIZE,
                              bytesRead))) {
     return NS_ERROR_FAILURE;
   }
   return WriteBlockToFile(aDestBlockIndex, buf);
 }
 
-nsresult FileBlockCache::Run()
+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);
 
   while (!mChangeIndexList.empty()) {
     if (!mIsOpen) {
       // We've been closed, abort, discarding unwritten changes.
       mIsWriteScheduled = false;
-      return NS_ERROR_FAILURE;
+      return;
     }
 
     if (mIsReading) {
       // We're trying to read; postpone all writes. (Reader will resume writes.)
       mIsWriteScheduled = false;
-      return NS_OK;
+      return;
     }
 
     // Process each pending change. We pop the index out of the change
     // list, but leave the BlockChange in mBlockChanges until the change
     // is written to file. This is so that any read which happens while
     // we drop mDataMutex to write will refer to the data's source in
     // memory, rather than the not-yet up to date data written to file.
     // This also ensures we will insert a new index into mChangeIndexList
@@ -334,17 +343,17 @@ nsresult FileBlockCache::Run()
                "Change index list should only contain entries for blocks "
                "with changes");
     {
       MutexAutoUnlock unlock(mDataMutex);
       MutexAutoLock lock(mFileMutex);
       if (!mFD) {
         // We may be here if mFD has been reset because we're closing, so we
         // don't care anymore about writes.
-        return NS_OK;
+        return;
       }
       if (change->IsWrite()) {
         WriteBlockToFile(blockIndex, change->mData.get());
       } else if (change->IsMove()) {
         MoveBlockInFile(change->mSourceBlockIndex, blockIndex);
       }
     }
     mChangeIndexList.pop_front();
@@ -352,18 +361,16 @@ nsresult FileBlockCache::Run()
     // mDataMutex, clear reference to the old change. Otherwise, the old
     // reference has been cleared already.
     if (mBlockChanges[blockIndex] == change) {
       mBlockChanges[blockIndex] = nullptr;
     }
   }
 
   mIsWriteScheduled = false;
-
-  return NS_OK;
 }
 
 nsresult FileBlockCache::Read(int64_t aOffset,
                               uint8_t* aData,
                               int32_t aLength,
                               int32_t* aBytes)
 {
   MutexAutoLock mon(mDataMutex);
--- a/dom/media/FileBlockCache.h
+++ b/dom/media/FileBlockCache.h
@@ -47,18 +47,21 @@ namespace mozilla {
 // When WriteBlock() or MoveBlock() are called, data about how to complete
 // the block change is added to mBlockChanges, indexed by block index, and
 // the block index is appended to the mChangeIndexList. This enables
 // us to quickly tell if a block has been changed, and ensures we can perform
 // the changes in the correct order. An event is dispatched to perform the
 // changes listed in mBlockChanges to file. Read() checks mBlockChanges and
 // determines the current data to return, reading from file or from
 // mBlockChanges as necessary.
-class FileBlockCache : public Runnable {
+class FileBlockCache
+{
 public:
+  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FileBlockCache)
+
   enum {
     BLOCK_SIZE = MediaCacheStream::BLOCK_SIZE
   };
 
   FileBlockCache();
 
 protected:
   ~FileBlockCache();
@@ -68,19 +71,16 @@ public:
 
   // Closes writer, shuts down thread.
   void Close();
 
   // 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);
 
-  // Performs block writes and block moves on its own thread.
-  NS_IMETHOD Run() 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.
   nsresult Read(int64_t aOffset,
                 uint8_t* aData,
                 int32_t aLength,
                 int32_t* aBytes);
 
@@ -138,16 +138,19 @@ public:
 
 private:
   int64_t BlockIndexToOffset(int32_t aBlockIndex) {
     return static_cast<int64_t>(aBlockIndex) * BLOCK_SIZE;
   }
 
   void SetCacheFile(PRFileDesc* aFD);
 
+  // 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.
   nsresult MoveBlockInFile(int32_t aSourceBlockIndex,
                            int32_t aDestBlockIndex);
   // Seeks file pointer.