Bug 1042192 - Use Cache2 I/O thread for callbacks from CacheFileIOManager. r=sworkman, a=sledru
authorMichal Novotny <michal.novotny@gmail.com>
Mon, 18 Aug 2014 15:36:27 +0200
changeset 217731 b529a7e31a988a8ab53665c51e95efe9c4ffcf84
parent 217730 c3f6bcaf840534d7bfbfad63cd1668fedb4370fb
child 217732 104c671afe110c6c4200b4fc7cba0c8d63824b13
push id515
push userraliiev@mozilla.com
push dateMon, 06 Oct 2014 12:51:51 +0000
treeherdermozilla-release@267c7a481bef [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssworkman, sledru
bugs1042192
milestone33.0a2
Bug 1042192 - Use Cache2 I/O thread for callbacks from CacheFileIOManager. r=sworkman, a=sledru
netwerk/cache2/CacheFile.cpp
netwerk/cache2/CacheFileChunk.cpp
netwerk/cache2/CacheFileIOManager.cpp
netwerk/cache2/CacheFileIOManager.h
netwerk/cache2/CacheFileInputStream.cpp
netwerk/cache2/CacheFileMetadata.cpp
netwerk/cache2/CacheFileOutputStream.cpp
netwerk/cache2/CacheIndex.cpp
netwerk/cache2/CacheStorageService.cpp
netwerk/test/unit/test_cache2-05-visit.js
netwerk/test/unit/test_cache2-23-read-over-chunk.js
--- a/netwerk/cache2/CacheFile.cpp
+++ b/netwerk/cache2/CacheFile.cpp
@@ -260,17 +260,17 @@ CacheFile::Init(const nsACString &aKey,
     }
 
     if (mPriority) {
       flags |= CacheFileIOManager::PRIORITY;
     }
 
     mOpeningFile = true;
     mListener = aCallback;
-    rv = CacheFileIOManager::OpenFile(mKey, flags, true, this);
+    rv = CacheFileIOManager::OpenFile(mKey, flags, this);
     if (NS_FAILED(rv)) {
       mListener = nullptr;
       mOpeningFile = false;
 
       if (aCreateNew) {
         NS_WARNING("Forcing memory-only entry since OpenFile failed");
         LOG(("CacheFile::Init() - CacheFileIOManager::OpenFile() failed "
              "synchronously. We can continue in memory-only mode since "
@@ -325,16 +325,23 @@ CacheFile::OnChunkRead(nsresult aResult,
   }
 
   return NS_OK;
 }
 
 nsresult
 CacheFile::OnChunkWritten(nsresult aResult, CacheFileChunk *aChunk)
 {
+  // In case the chunk was reused, made dirty and released between calls to
+  // CacheFileChunk::Write() and CacheFile::OnChunkWritten(), we must write
+  // the chunk to the disk again. When the chunk is unused and is dirty simply
+  // addref and release (outside the lock) the chunk which ensures that
+  // CacheFile::DeactivateChunk() will be called again.
+  nsRefPtr<CacheFileChunk> deactivateChunkAgain;
+
   CacheFileAutoLock lock(this);
 
   nsresult rv;
 
   LOG(("CacheFile::OnChunkWritten() [this=%p, rv=0x%08x, chunk=%p, idx=%u]",
        this, aResult, aChunk, aChunk->Index()));
 
   MOZ_ASSERT(!mMemoryOnly);
@@ -362,16 +369,24 @@ CacheFile::OnChunkWritten(nsresult aResu
 
   if (aChunk->mRefCnt != 2) {
     LOG(("CacheFile::OnChunkWritten() - Chunk is still used [this=%p, chunk=%p,"
          " refcnt=%d]", this, aChunk, aChunk->mRefCnt.get()));
 
     return NS_OK;
   }
 
+  if (aChunk->IsDirty()) {
+    LOG(("CacheFile::OnChunkWritten() - Unused chunk is dirty. We must go "
+         "through deactivation again. [this=%p, chunk=%p]", this, aChunk));
+
+    deactivateChunkAgain = aChunk;
+    return NS_OK;
+  }
+
   bool keepChunk = false;
   if (NS_SUCCEEDED(aResult)) {
     keepChunk = ShouldCacheChunk(aChunk->Index());
     LOG(("CacheFile::OnChunkWritten() - %s unused chunk [this=%p, chunk=%p]",
          keepChunk ? "Caching" : "Releasing", this, aChunk));
   } else {
     LOG(("CacheFile::OnChunkWritten() - Releasing failed chunk [this=%p, "
          "chunk=%p]", this, aChunk));
@@ -1589,17 +1604,22 @@ CacheFile::QueueChunkListener(uint32_t a
   LOG(("CacheFile::QueueChunkListener() [this=%p, idx=%u, listener=%p]",
        this, aIndex, aCallback));
 
   AssertOwnsLock();
 
   MOZ_ASSERT(aCallback);
 
   ChunkListenerItem *item = new ChunkListenerItem();
-  item->mTarget = NS_GetCurrentThread();
+  item->mTarget = CacheFileIOManager::IOTarget();
+  if (!item->mTarget) {
+    LOG(("CacheFile::QueueChunkListener() - Cannot get Cache I/O thread! Using "
+         "main thread for callback."));
+    item->mTarget = do_GetMainThread();
+  }
   item->mCallback = aCallback;
 
   ChunkListeners *listeners;
   if (!mChunkListeners.Get(aIndex, &listeners)) {
     listeners = new ChunkListeners();
     mChunkListeners.Put(aIndex, listeners);
   }
 
--- a/netwerk/cache2/CacheFileChunk.cpp
+++ b/netwerk/cache2/CacheFileChunk.cpp
@@ -196,17 +196,17 @@ CacheFileChunk::Read(CacheFileHandle *aH
     // Allocation was denied or failed
     SetError(NS_ERROR_OUT_OF_MEMORY);
     return mStatus;
   }
 
   DoMemoryReport(MemorySize());
 
   rv = CacheFileIOManager::Read(aHandle, mIndex * kChunkSize, mRWBuf, aLen,
-                                true, this);
+                                this);
   if (NS_WARN_IF(NS_FAILED(rv))) {
     rv = mIndex ? NS_ERROR_FILE_CORRUPTED : NS_ERROR_FILE_NOT_FOUND;
     SetError(rv);
   } else {
     mListener = aCallback;
     mDataSize = aLen;
     mReadHash = aHash;
   }
@@ -262,17 +262,24 @@ CacheFileChunk::WaitForUpdate(CacheFileC
 
 #ifdef DEBUG
   for (uint32_t i = 0 ; i < mUpdateListeners.Length() ; i++) {
     MOZ_ASSERT(mUpdateListeners[i]->mCallback != aCallback);
   }
 #endif
 
   ChunkListenerItem *item = new ChunkListenerItem();
-  item->mTarget = NS_GetCurrentThread();
+  item->mTarget = CacheFileIOManager::IOTarget();
+  if (!item->mTarget) {
+    LOG(("CacheFileChunk::WaitForUpdate() - Cannot get Cache I/O thread! Using "
+         "main thread for callback."));
+    item->mTarget = do_GetMainThread();
+  }
+  item->mCallback = aCallback;
+  MOZ_ASSERT(item->mTarget);
   item->mCallback = aCallback;
 
   mUpdateListeners.AppendElement(item);
 }
 
 nsresult
 CacheFileChunk::CancelWait(CacheFileChunkListener *aCallback)
 {
--- a/netwerk/cache2/CacheFileIOManager.cpp
+++ b/netwerk/cache2/CacheFileIOManager.cpp
@@ -557,194 +557,146 @@ public:
 
 protected:
   mozilla::Mutex   *mLock;
   mozilla::CondVar *mCondVar;
 };
 
 class OpenFileEvent : public nsRunnable {
 public:
-  OpenFileEvent(const nsACString &aKey,
-                uint32_t aFlags, bool aResultOnAnyThread,
+  OpenFileEvent(const nsACString &aKey, uint32_t aFlags,
                 CacheFileIOListener *aCallback)
     : mFlags(aFlags)
-    , mResultOnAnyThread(aResultOnAnyThread)
     , mCallback(aCallback)
-    , mRV(NS_ERROR_FAILURE)
     , mKey(aKey)
   {
     MOZ_COUNT_CTOR(OpenFileEvent);
-
-    if (!aResultOnAnyThread) {
-      mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
-      MOZ_ASSERT(mTarget);
-    }
-
     mIOMan = CacheFileIOManager::gInstance;
 
     MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aKey.BeginReading());
     MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::open-background");
   }
 
 protected:
   ~OpenFileEvent()
   {
     MOZ_COUNT_DTOR(OpenFileEvent);
   }
 
 public:
   NS_IMETHOD Run()
   {
-    if (mResultOnAnyThread || mTarget) {
-      mRV = NS_OK;
-
-      if (!(mFlags & CacheFileIOManager::SPECIAL_FILE)) {
-        SHA1Sum sum;
-        sum.update(mKey.BeginReading(), mKey.Length());
-        sum.finish(mHash);
+    nsresult rv = NS_OK;
+
+    if (!(mFlags & CacheFileIOManager::SPECIAL_FILE)) {
+      SHA1Sum sum;
+      sum.update(mKey.BeginReading(), mKey.Length());
+      sum.finish(mHash);
+    }
+
+    MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-background");
+    if (!mIOMan) {
+      rv = NS_ERROR_NOT_INITIALIZED;
+    } else {
+      if (mFlags & CacheFileIOManager::SPECIAL_FILE) {
+        rv = mIOMan->OpenSpecialFileInternal(mKey, mFlags,
+                                             getter_AddRefs(mHandle));
+      } else {
+        rv = mIOMan->OpenFileInternal(&mHash, mKey, mFlags,
+                                      getter_AddRefs(mHandle));
       }
-
-      MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this),
-                            "net::cache::open-background");
-      if (NS_SUCCEEDED(mRV)) {
-        if (!mIOMan) {
-          mRV = NS_ERROR_NOT_INITIALIZED;
-        } else {
-          if (mFlags & CacheFileIOManager::SPECIAL_FILE) {
-            mRV = mIOMan->OpenSpecialFileInternal(mKey, mFlags,
-                                                  getter_AddRefs(mHandle));
-          } else {
-            mRV = mIOMan->OpenFileInternal(&mHash, mKey, mFlags,
-                                           getter_AddRefs(mHandle));
-          }
-          mIOMan = nullptr;
-          if (mHandle) {
-            MOZ_EVENT_TRACER_NAME_OBJECT(mHandle.get(), mKey.get());
-            if (mHandle->Key().IsEmpty()) {
-              mHandle->Key() = mKey;
-            }
-          }
+      mIOMan = nullptr;
+      if (mHandle) {
+        MOZ_EVENT_TRACER_NAME_OBJECT(mHandle.get(), mKey.get());
+        if (mHandle->Key().IsEmpty()) {
+          mHandle->Key() = mKey;
         }
       }
-      MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-background");
-
-      MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::open-result");
-
-      if (mTarget) {
-        nsCOMPtr<nsIEventTarget> target;
-        mTarget.swap(target);
-        return target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
-      }
     }
-
-    if (!mTarget) {
-      MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-result");
-      mCallback->OnFileOpened(mHandle, mRV);
-      MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-result");
-    }
+    MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-background");
+
+    MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::open-result");
+    mCallback->OnFileOpened(mHandle, rv);
+    MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::open-result");
 
     return NS_OK;
   }
 
 protected:
   SHA1Sum::Hash                 mHash;
   uint32_t                      mFlags;
-  bool                          mResultOnAnyThread;
   nsCOMPtr<CacheFileIOListener> mCallback;
-  nsCOMPtr<nsIEventTarget>      mTarget;
   nsRefPtr<CacheFileIOManager>  mIOMan;
   nsRefPtr<CacheFileHandle>     mHandle;
-  nsresult                      mRV;
   nsCString                     mKey;
 };
 
 class ReadEvent : public nsRunnable {
 public:
   ReadEvent(CacheFileHandle *aHandle, int64_t aOffset, char *aBuf,
-            int32_t aCount, bool aResultOnAnyThread, CacheFileIOListener *aCallback)
+            int32_t aCount, CacheFileIOListener *aCallback)
     : mHandle(aHandle)
     , mOffset(aOffset)
     , mBuf(aBuf)
     , mCount(aCount)
-    , mResultOnAnyThread(aResultOnAnyThread)
     , mCallback(aCallback)
-    , mRV(NS_ERROR_FAILURE)
   {
     MOZ_COUNT_CTOR(ReadEvent);
 
-    if (!aResultOnAnyThread) {
-      mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
-    }
-
     MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
     MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::read-background");
   }
 
 protected:
   ~ReadEvent()
   {
     MOZ_COUNT_DTOR(ReadEvent);
   }
 
 public:
   NS_IMETHOD Run()
   {
-    if (mResultOnAnyThread || mTarget) {
-      MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-background");
-      if (mHandle->IsClosed()) {
-        mRV = NS_ERROR_NOT_INITIALIZED;
-      } else {
-        mRV = CacheFileIOManager::gInstance->ReadInternal(
-          mHandle, mOffset, mBuf, mCount);
-      }
-      MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-background");
-
-      MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::read-result");
-
-      if (mTarget) {
-        nsCOMPtr<nsIEventTarget> target;
-        mTarget.swap(target);
-        return target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
-      }
+    nsresult rv;
+
+    MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-background");
+    if (mHandle->IsClosed()) {
+      rv = NS_ERROR_NOT_INITIALIZED;
+    } else {
+      rv = CacheFileIOManager::gInstance->ReadInternal(
+        mHandle, mOffset, mBuf, mCount);
     }
-
-    if (!mTarget && mCallback) {
-      MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-result");
-      mCallback->OnDataRead(mHandle, mBuf, mRV);
-      MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-result");
-    }
+    MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-background");
+
+    MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::read-result");
+    mCallback->OnDataRead(mHandle, mBuf, rv);
+    MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::read-result");
 
     return NS_OK;
   }
 
 protected:
   nsRefPtr<CacheFileHandle>     mHandle;
   int64_t                       mOffset;
   char                         *mBuf;
   int32_t                       mCount;
-  bool                          mResultOnAnyThread;
   nsCOMPtr<CacheFileIOListener> mCallback;
-  nsCOMPtr<nsIEventTarget>      mTarget;
-  nsresult                      mRV;
 };
 
 class WriteEvent : public nsRunnable {
 public:
   WriteEvent(CacheFileHandle *aHandle, int64_t aOffset, const char *aBuf,
              int32_t aCount, bool aValidate, CacheFileIOListener *aCallback)
     : mHandle(aHandle)
     , mOffset(aOffset)
     , mBuf(aBuf)
     , mCount(aCount)
     , mValidate(aValidate)
     , mCallback(aCallback)
-    , mRV(NS_ERROR_FAILURE)
   {
     MOZ_COUNT_CTOR(WriteEvent);
-    mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
 
     MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
     MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::write-background");
   }
 
 protected:
   ~WriteEvent()
   {
@@ -753,160 +705,139 @@ protected:
     if (!mCallback && mBuf) {
       free(const_cast<char *>(mBuf));
     }
   }
 
 public:
   NS_IMETHOD Run()
   {
-    if (mTarget) {
-      MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-background");
-      if (mHandle->IsClosed()) {
-        mRV = NS_ERROR_NOT_INITIALIZED;
-      } else {
-        mRV = CacheFileIOManager::gInstance->WriteInternal(
+    nsresult rv;
+
+    MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-background");
+    if (mHandle->IsClosed()) {
+      rv = NS_ERROR_NOT_INITIALIZED;
+    } else {
+      rv = CacheFileIOManager::gInstance->WriteInternal(
           mHandle, mOffset, mBuf, mCount, mValidate);
-      }
-      MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-background");
-
-      MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::write-result");
-      nsCOMPtr<nsIEventTarget> target;
-      mTarget.swap(target);
-      target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
+    }
+    MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-background");
+
+    MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-result");
+    if (mCallback) {
+      mCallback->OnDataWritten(mHandle, mBuf, rv);
     } else {
-      MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::write-result");
-      if (mCallback) {
-        mCallback->OnDataWritten(mHandle, mBuf, mRV);
-      } else {
-        free(const_cast<char *>(mBuf));
-        mBuf = nullptr;
-      }
-      MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-result");
+      free(const_cast<char *>(mBuf));
+      mBuf = nullptr;
     }
+    MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::write-result");
+
     return NS_OK;
   }
 
 protected:
   nsRefPtr<CacheFileHandle>     mHandle;
   int64_t                       mOffset;
   const char                   *mBuf;
   int32_t                       mCount;
   bool                          mValidate;
   nsCOMPtr<CacheFileIOListener> mCallback;
-  nsCOMPtr<nsIEventTarget>      mTarget;
-  nsresult                      mRV;
 };
 
 class DoomFileEvent : public nsRunnable {
 public:
   DoomFileEvent(CacheFileHandle *aHandle,
                 CacheFileIOListener *aCallback)
     : mCallback(aCallback)
     , mHandle(aHandle)
-    , mRV(NS_ERROR_FAILURE)
   {
     MOZ_COUNT_CTOR(DoomFileEvent);
-    mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
 
     MOZ_EVENT_TRACER_NAME_OBJECT(static_cast<nsIRunnable*>(this), aHandle->Key().get());
     MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
   }
 
 protected:
   ~DoomFileEvent()
   {
     MOZ_COUNT_DTOR(DoomFileEvent);
   }
 
 public:
   NS_IMETHOD Run()
   {
-    if (mTarget) {
-      MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
-      if (mHandle->IsClosed()) {
-        mRV = NS_ERROR_NOT_INITIALIZED;
-      } else {
-        mRV = CacheFileIOManager::gInstance->DoomFileInternal(mHandle);
-      }
-      MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
-
-      MOZ_EVENT_TRACER_WAIT(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
-      nsCOMPtr<nsIEventTarget> target;
-      mTarget.swap(target);
-      target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
+    nsresult rv;
+
+    MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
+    if (mHandle->IsClosed()) {
+      rv = NS_ERROR_NOT_INITIALIZED;
     } else {
-      MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
-      if (mCallback) {
-        mCallback->OnFileDoomed(mHandle, mRV);
-      }
-      MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
+      rv = CacheFileIOManager::gInstance->DoomFileInternal(mHandle);
     }
+    MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-background");
+
+    MOZ_EVENT_TRACER_EXEC(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
+    if (mCallback) {
+      mCallback->OnFileDoomed(mHandle, rv);
+    }
+    MOZ_EVENT_TRACER_DONE(static_cast<nsIRunnable*>(this), "net::cache::doom-result");
+
     return NS_OK;
   }
 
 protected:
   nsCOMPtr<CacheFileIOListener> mCallback;
   nsCOMPtr<nsIEventTarget>      mTarget;
   nsRefPtr<CacheFileHandle>     mHandle;
-  nsresult                      mRV;
 };
 
 class DoomFileByKeyEvent : public nsRunnable {
 public:
   DoomFileByKeyEvent(const nsACString &aKey,
                      CacheFileIOListener *aCallback)
     : mCallback(aCallback)
-    , mRV(NS_ERROR_FAILURE)
   {
     MOZ_COUNT_CTOR(DoomFileByKeyEvent);
 
     SHA1Sum sum;
     sum.update(aKey.BeginReading(), aKey.Length());
     sum.finish(mHash);
 
-    mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
     mIOMan = CacheFileIOManager::gInstance;
-    MOZ_ASSERT(mTarget);
   }
 
 protected:
   ~DoomFileByKeyEvent()
   {
     MOZ_COUNT_DTOR(DoomFileByKeyEvent);
   }
 
 public:
   NS_IMETHOD Run()
   {
-    if (mTarget) {
-      if (!mIOMan) {
-        mRV = NS_ERROR_NOT_INITIALIZED;
-      } else {
-        mRV = mIOMan->DoomFileByKeyInternal(&mHash, false);
-        mIOMan = nullptr;
-      }
-
-      nsCOMPtr<nsIEventTarget> target;
-      mTarget.swap(target);
-      target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
+    nsresult rv;
+
+    if (!mIOMan) {
+      rv = NS_ERROR_NOT_INITIALIZED;
     } else {
-      if (mCallback) {
-        mCallback->OnFileDoomed(nullptr, mRV);
-      }
+      rv = mIOMan->DoomFileByKeyInternal(&mHash, false);
+      mIOMan = nullptr;
     }
+
+    if (mCallback) {
+      mCallback->OnFileDoomed(nullptr, rv);
+    }
+
     return NS_OK;
   }
 
 protected:
   SHA1Sum::Hash                 mHash;
   nsCOMPtr<CacheFileIOListener> mCallback;
-  nsCOMPtr<nsIEventTarget>      mTarget;
   nsRefPtr<CacheFileIOManager>  mIOMan;
-  nsresult                      mRV;
 };
 
 class ReleaseNSPRHandleEvent : public nsRunnable {
 public:
   ReleaseNSPRHandleEvent(CacheFileHandle *aHandle)
     : mHandle(aHandle)
   {
     MOZ_COUNT_CTOR(ReleaseNSPRHandleEvent);
@@ -935,106 +866,92 @@ protected:
 class TruncateSeekSetEOFEvent : public nsRunnable {
 public:
   TruncateSeekSetEOFEvent(CacheFileHandle *aHandle, int64_t aTruncatePos,
                           int64_t aEOFPos, CacheFileIOListener *aCallback)
     : mHandle(aHandle)
     , mTruncatePos(aTruncatePos)
     , mEOFPos(aEOFPos)
     , mCallback(aCallback)
-    , mRV(NS_ERROR_FAILURE)
   {
     MOZ_COUNT_CTOR(TruncateSeekSetEOFEvent);
-    mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
   }
 
 protected:
   ~TruncateSeekSetEOFEvent()
   {
     MOZ_COUNT_DTOR(TruncateSeekSetEOFEvent);
   }
 
 public:
   NS_IMETHOD Run()
   {
-    if (mTarget) {
-      if (mHandle->IsClosed()) {
-        mRV = NS_ERROR_NOT_INITIALIZED;
-      } else {
-        mRV = CacheFileIOManager::gInstance->TruncateSeekSetEOFInternal(
-          mHandle, mTruncatePos, mEOFPos);
-      }
-
-      nsCOMPtr<nsIEventTarget> target;
-      mTarget.swap(target);
-      target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
+    nsresult rv;
+
+    if (mHandle->IsClosed()) {
+      rv = NS_ERROR_NOT_INITIALIZED;
     } else {
-      if (mCallback) {
-        mCallback->OnEOFSet(mHandle, mRV);
-      }
+      rv = CacheFileIOManager::gInstance->TruncateSeekSetEOFInternal(
+        mHandle, mTruncatePos, mEOFPos);
     }
+
+    if (mCallback) {
+      mCallback->OnEOFSet(mHandle, rv);
+    }
+
     return NS_OK;
   }
 
 protected:
   nsRefPtr<CacheFileHandle>     mHandle;
   int64_t                       mTruncatePos;
   int64_t                       mEOFPos;
   nsCOMPtr<CacheFileIOListener> mCallback;
-  nsCOMPtr<nsIEventTarget>      mTarget;
-  nsresult                      mRV;
 };
 
 class RenameFileEvent : public nsRunnable {
 public:
   RenameFileEvent(CacheFileHandle *aHandle, const nsACString &aNewName,
                   CacheFileIOListener *aCallback)
     : mHandle(aHandle)
     , mNewName(aNewName)
     , mCallback(aCallback)
-    , mRV(NS_ERROR_FAILURE)
   {
     MOZ_COUNT_CTOR(RenameFileEvent);
-    mTarget = static_cast<nsIEventTarget*>(NS_GetCurrentThread());
   }
 
 protected:
   ~RenameFileEvent()
   {
     MOZ_COUNT_DTOR(RenameFileEvent);
   }
 
 public:
   NS_IMETHOD Run()
   {
-    if (mTarget) {
-      if (mHandle->IsClosed()) {
-        mRV = NS_ERROR_NOT_INITIALIZED;
-      } else {
-        mRV = CacheFileIOManager::gInstance->RenameFileInternal(mHandle,
-                                                                mNewName);
-      }
-
-      nsCOMPtr<nsIEventTarget> target;
-      mTarget.swap(target);
-      target->Dispatch(this, nsIEventTarget::DISPATCH_NORMAL);
+    nsresult rv;
+
+    if (mHandle->IsClosed()) {
+      rv = NS_ERROR_NOT_INITIALIZED;
     } else {
-      if (mCallback) {
-        mCallback->OnFileRenamed(mHandle, mRV);
-      }
+      rv = CacheFileIOManager::gInstance->RenameFileInternal(mHandle,
+                                                             mNewName);
     }
+
+    if (mCallback) {
+      mCallback->OnFileRenamed(mHandle, rv);
+    }
+
     return NS_OK;
   }
 
 protected:
   nsRefPtr<CacheFileHandle>     mHandle;
   nsCString                     mNewName;
   nsCOMPtr<CacheFileIOListener> mCallback;
-  nsCOMPtr<nsIEventTarget>      mTarget;
-  nsresult                      mRV;
 };
 
 class InitIndexEntryEvent : public nsRunnable {
 public:
   InitIndexEntryEvent(CacheFileHandle *aHandle, uint32_t aAppId,
                       bool aAnonymous, bool aInBrowser)
     : mHandle(aHandle)
     , mAppId(aAppId)
@@ -1611,31 +1528,30 @@ CacheFileIOManager::Notify(nsITimer * aT
   }
 
   return NS_OK;
 }
 
 // static
 nsresult
 CacheFileIOManager::OpenFile(const nsACString &aKey,
-                             uint32_t aFlags, bool aResultOnAnyThread,
-                             CacheFileIOListener *aCallback)
+                             uint32_t aFlags, CacheFileIOListener *aCallback)
 {
   LOG(("CacheFileIOManager::OpenFile() [key=%s, flags=%d, listener=%p]",
        PromiseFlatCString(aKey).get(), aFlags, aCallback));
 
   nsresult rv;
   nsRefPtr<CacheFileIOManager> ioMan = gInstance;
 
   if (!ioMan) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   bool priority = aFlags & CacheFileIOManager::PRIORITY;
-  nsRefPtr<OpenFileEvent> ev = new OpenFileEvent(aKey, aFlags, aResultOnAnyThread, aCallback);
+  nsRefPtr<OpenFileEvent> ev = new OpenFileEvent(aKey, aFlags, aCallback);
   rv = ioMan->mIOThread->Dispatch(ev, priority
     ? CacheIOThread::OPEN_PRIORITY
     : CacheIOThread::OPEN);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
@@ -1881,31 +1797,31 @@ CacheFileIOManager::CloseHandleInternal(
   }
 
   return NS_OK;
 }
 
 // static
 nsresult
 CacheFileIOManager::Read(CacheFileHandle *aHandle, int64_t aOffset,
-                         char *aBuf, int32_t aCount, bool aResultOnAnyThread,
+                         char *aBuf, int32_t aCount,
                          CacheFileIOListener *aCallback)
 {
   LOG(("CacheFileIOManager::Read() [handle=%p, offset=%lld, count=%d, "
        "listener=%p]", aHandle, aOffset, aCount, aCallback));
 
   nsresult rv;
   nsRefPtr<CacheFileIOManager> ioMan = gInstance;
 
   if (aHandle->IsClosed() || !ioMan) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   nsRefPtr<ReadEvent> ev = new ReadEvent(aHandle, aOffset, aBuf, aCount,
-                                         aResultOnAnyThread, aCallback);
+                                         aCallback);
   rv = ioMan->mIOThread->Dispatch(ev, aHandle->IsPriority()
     ? CacheIOThread::READ_PRIORITY
     : CacheIOThread::READ);
   NS_ENSURE_SUCCESS(rv, rv);
 
   return NS_OK;
 }
 
--- a/netwerk/cache2/CacheFileIOManager.h
+++ b/netwerk/cache2/CacheFileIOManager.h
@@ -236,20 +236,19 @@ public:
   static nsresult ScheduleMetadataWrite(CacheFile * aFile);
   // Remove aFile from the scheduling registry array.
   // WriteMetadataIfNeeded will not be automatically called.
   static nsresult UnscheduleMetadataWrite(CacheFile * aFile);
   // Shuts the scheduling off and flushes all pending metadata writes.
   static nsresult ShutdownMetadataWriteScheduling();
 
   static nsresult OpenFile(const nsACString &aKey,
-                           uint32_t aFlags, bool aResultOnAnyThread,
-                           CacheFileIOListener *aCallback);
+                           uint32_t aFlags, CacheFileIOListener *aCallback);
   static nsresult Read(CacheFileHandle *aHandle, int64_t aOffset,
-                       char *aBuf, int32_t aCount, bool aResultOnAnyThread,
+                       char *aBuf, int32_t aCount,
                        CacheFileIOListener *aCallback);
   static nsresult Write(CacheFileHandle *aHandle, int64_t aOffset,
                         const char *aBuf, int32_t aCount, bool aValidate,
                         CacheFileIOListener *aCallback);
   static nsresult DoomFile(CacheFileHandle *aHandle,
                            CacheFileIOListener *aCallback);
   static nsresult DoomFileByKey(const nsACString &aKey,
                                 CacheFileIOListener *aCallback);
--- a/netwerk/cache2/CacheFileInputStream.cpp
+++ b/netwerk/cache2/CacheFileInputStream.cpp
@@ -534,18 +534,24 @@ void
 CacheFileInputStream::NotifyListener()
 {
   mFile->AssertOwnsLock();
 
   LOG(("CacheFileInputStream::NotifyListener() [this=%p]", this));
 
   MOZ_ASSERT(mCallback);
 
-  if (!mCallbackTarget)
-    mCallbackTarget = NS_GetCurrentThread();
+  if (!mCallbackTarget) {
+    mCallbackTarget = CacheFileIOManager::IOTarget();
+    if (!mCallbackTarget) {
+      LOG(("CacheFileInputStream::NotifyListener() - Cannot get Cache I/O "
+           "thread! Using main thread for callback."));
+      mCallbackTarget = do_GetMainThread();
+    }
+  }
 
   nsCOMPtr<nsIInputStreamCallback> asyncCallback =
     NS_NewInputStreamReadyEvent(mCallback, mCallbackTarget);
 
   mCallback = nullptr;
   mCallbackTarget = nullptr;
 
   asyncCallback->OnInputStreamReady(this);
--- a/netwerk/cache2/CacheFileMetadata.cpp
+++ b/netwerk/cache2/CacheFileMetadata.cpp
@@ -201,17 +201,17 @@ CacheFileMetadata::ReadMetadata(CacheFil
   mBuf = static_cast<char *>(moz_xmalloc(mBufSize));
 
   DoMemoryReport(MemoryUsage());
 
   LOG(("CacheFileMetadata::ReadMetadata() - Reading metadata from disk, trying "
        "offset=%lld, filesize=%lld [this=%p]", offset, size, this));
 
   mListener = aListener;
-  rv = CacheFileIOManager::Read(mHandle, offset, mBuf, mBufSize, true, this);
+  rv = CacheFileIOManager::Read(mHandle, offset, mBuf, mBufSize, this);
   if (NS_FAILED(rv)) {
     LOG(("CacheFileMetadata::ReadMetadata() - CacheFileIOManager::Read() failed"
          " synchronously, creating empty metadata. [this=%p, rv=0x%08x]",
          this, rv));
 
     mListener = nullptr;
     InitEmptyMetadata();
     aListener->OnMetadataRead(NS_OK);
@@ -649,17 +649,17 @@ CacheFileMetadata::OnDataRead(CacheFileH
     memmove(mBuf + missing, mBuf, mBufSize);
     mBufSize += missing;
 
     DoMemoryReport(MemoryUsage());
 
     LOG(("CacheFileMetadata::OnDataRead() - We need to read %d more bytes to "
          "have full metadata. [this=%p]", missing, this));
 
-    rv = CacheFileIOManager::Read(mHandle, realOffset, mBuf, missing, true, this);
+    rv = CacheFileIOManager::Read(mHandle, realOffset, mBuf, missing, this);
     if (NS_FAILED(rv)) {
       LOG(("CacheFileMetadata::OnDataRead() - CacheFileIOManager::Read() "
            "failed synchronously, creating empty metadata. [this=%p, "
            "rv=0x%08x]", this, rv));
 
       InitEmptyMetadata();
       retval = NS_OK;
 
--- a/netwerk/cache2/CacheFileOutputStream.cpp
+++ b/netwerk/cache2/CacheFileOutputStream.cpp
@@ -414,18 +414,24 @@ void
 CacheFileOutputStream::NotifyListener()
 {
   mFile->AssertOwnsLock();
 
   LOG(("CacheFileOutputStream::NotifyListener() [this=%p]", this));
 
   MOZ_ASSERT(mCallback);
 
-  if (!mCallbackTarget)
-    mCallbackTarget = NS_GetCurrentThread();
+  if (!mCallbackTarget) {
+    mCallbackTarget = CacheFileIOManager::IOTarget();
+    if (!mCallbackTarget) {
+      LOG(("CacheFileOutputStream::NotifyListener() - Cannot get Cache I/O "
+           "thread! Using main thread for callback."));
+      mCallbackTarget = do_GetMainThread();
+    }
+  }
 
   nsCOMPtr<nsIOutputStreamCallback> asyncCallback =
     NS_NewOutputStreamReadyEvent(mCallback, mCallbackTarget);
 
   mCallback = nullptr;
   mCallbackTarget = nullptr;
 
   asyncCallback->OnOutputStreamReady(this);
--- a/netwerk/cache2/CacheIndex.cpp
+++ b/netwerk/cache2/CacheIndex.cpp
@@ -1501,17 +1501,16 @@ CacheIndex::WriteIndexToDisk()
   ChangeState(WRITING);
 
   mProcessEntries = mIndexStats.ActiveEntriesCount();
 
   mIndexFileOpener = new FileOpenHelper(this);
   rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kTempIndexName),
                                     CacheFileIOManager::SPECIAL_FILE |
                                     CacheFileIOManager::CREATE,
-                                    true,
                                     mIndexFileOpener);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::WriteIndexToDisk() - Can't open file [rv=0x%08x]", rv));
     FinishWrite(false);
     return;
   }
 
   // Write index header to a buffer, it will be written to disk together with
@@ -1947,42 +1946,39 @@ CacheIndex::ReadIndexFromDisk()
   MOZ_ASSERT(mState == INITIAL);
 
   ChangeState(READING);
 
   mIndexFileOpener = new FileOpenHelper(this);
   rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kIndexName),
                                     CacheFileIOManager::SPECIAL_FILE |
                                     CacheFileIOManager::OPEN,
-                                    true,
                                     mIndexFileOpener);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
          "failed [rv=0x%08x, file=%s]", rv, kIndexName));
     FinishRead(false);
     return;
   }
 
   mJournalFileOpener = new FileOpenHelper(this);
   rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kJournalName),
                                     CacheFileIOManager::SPECIAL_FILE |
                                     CacheFileIOManager::OPEN,
-                                    true,
                                     mJournalFileOpener);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
          "failed [rv=0x%08x, file=%s]", rv, kJournalName));
     FinishRead(false);
   }
 
   mTmpFileOpener = new FileOpenHelper(this);
   rv = CacheFileIOManager::OpenFile(NS_LITERAL_CSTRING(kTempIndexName),
                                     CacheFileIOManager::SPECIAL_FILE |
                                     CacheFileIOManager::OPEN,
-                                    true,
                                     mTmpFileOpener);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::ReadIndexFromDisk() - CacheFileIOManager::OpenFile() "
          "failed [rv=0x%08x, file=%s]", rv, kTempIndexName));
     FinishRead(false);
   }
 }
 
@@ -2013,17 +2009,17 @@ CacheIndex::StartReadingIndex()
 
   AllocBuffer();
   mSkipEntries = 0;
   mRWHash = new CacheHash();
 
   mRWBufPos = std::min(mRWBufSize,
                        static_cast<uint32_t>(mIndexHandle->FileSize()));
 
-  rv = CacheFileIOManager::Read(mIndexHandle, 0, mRWBuf, mRWBufPos, true, this);
+  rv = CacheFileIOManager::Read(mIndexHandle, 0, mRWBuf, mRWBufPos, this);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::StartReadingIndex() - CacheFileIOManager::Read() failed "
          "synchronously [rv=0x%08x]", rv));
     FinishRead(false);
   }
 }
 
 void
@@ -2138,17 +2134,17 @@ CacheIndex::ParseRecords()
 
   pos = mRWBufPos;
   uint32_t toRead = std::min(mRWBufSize - pos,
                              static_cast<uint32_t>(mIndexHandle->FileSize() -
                                                    fileOffset));
   mRWBufPos = pos + toRead;
 
   rv = CacheFileIOManager::Read(mIndexHandle, fileOffset, mRWBuf + pos, toRead,
-                                true, this);
+                                this);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::ParseRecords() - CacheFileIOManager::Read() failed "
          "synchronously [rv=0x%08x]", rv));
     FinishRead(false);
     return;
   }
 }
 
@@ -2176,17 +2172,17 @@ CacheIndex::StartReadingJournal()
   }
 
   mSkipEntries = 0;
   mRWHash = new CacheHash();
 
   mRWBufPos = std::min(mRWBufSize,
                        static_cast<uint32_t>(mJournalHandle->FileSize()));
 
-  rv = CacheFileIOManager::Read(mJournalHandle, 0, mRWBuf, mRWBufPos, true, this);
+  rv = CacheFileIOManager::Read(mJournalHandle, 0, mRWBuf, mRWBufPos, this);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::StartReadingJournal() - CacheFileIOManager::Read() failed"
          " synchronously [rv=0x%08x]", rv));
     FinishRead(false);
   }
 }
 
 void
@@ -2251,17 +2247,17 @@ CacheIndex::ParseJournal()
 
   pos = mRWBufPos;
   uint32_t toRead = std::min(mRWBufSize - pos,
                              static_cast<uint32_t>(mJournalHandle->FileSize() -
                                                    fileOffset));
   mRWBufPos = pos + toRead;
 
   rv = CacheFileIOManager::Read(mJournalHandle, fileOffset, mRWBuf + pos,
-                                toRead, true, this);
+                                toRead, this);
   if (NS_FAILED(rv)) {
     LOG(("CacheIndex::ParseJournal() - CacheFileIOManager::Read() failed "
          "synchronously [rv=0x%08x]", rv));
     FinishRead(false);
     return;
   }
 }
 
--- a/netwerk/cache2/CacheStorageService.cpp
+++ b/netwerk/cache2/CacheStorageService.cpp
@@ -1407,53 +1407,68 @@ CacheStorageService::CheckStorageEntry(C
   *aResult = status == CacheIndex::EXISTS;
   LOG(("  %sfound in index", *aResult ? "" : "not "));
   return NS_OK;
 }
 
 namespace { // anon
 
 class CacheEntryDoomByKeyCallback : public CacheFileIOListener
+                                  , public nsIRunnable
 {
 public:
   NS_DECL_THREADSAFE_ISUPPORTS
+  NS_DECL_NSIRUNNABLE
 
   CacheEntryDoomByKeyCallback(nsICacheEntryDoomCallback* aCallback)
     : mCallback(aCallback) { }
 
 private:
   virtual ~CacheEntryDoomByKeyCallback();
 
   NS_IMETHOD OnFileOpened(CacheFileHandle *aHandle, nsresult aResult) { return NS_OK; }
   NS_IMETHOD OnDataWritten(CacheFileHandle *aHandle, const char *aBuf, nsresult aResult) { return NS_OK; }
   NS_IMETHOD OnDataRead(CacheFileHandle *aHandle, char *aBuf, nsresult aResult) { return NS_OK; }
   NS_IMETHOD OnFileDoomed(CacheFileHandle *aHandle, nsresult aResult);
   NS_IMETHOD OnEOFSet(CacheFileHandle *aHandle, nsresult aResult) { return NS_OK; }
   NS_IMETHOD OnFileRenamed(CacheFileHandle *aHandle, nsresult aResult) { return NS_OK; }
 
   nsCOMPtr<nsICacheEntryDoomCallback> mCallback;
+  nsresult mResult;
 };
 
 CacheEntryDoomByKeyCallback::~CacheEntryDoomByKeyCallback()
 {
   if (mCallback)
     ProxyReleaseMainThread(mCallback);
 }
 
 NS_IMETHODIMP CacheEntryDoomByKeyCallback::OnFileDoomed(CacheFileHandle *aHandle,
                                                         nsresult aResult)
 {
   if (!mCallback)
     return NS_OK;
 
-  mCallback->OnCacheEntryDoomed(aResult);
+  mResult = aResult;
+  if (NS_IsMainThread()) {
+    Run();
+  } else {
+    NS_DispatchToMainThread(this);
+  }
+
   return NS_OK;
 }
 
-NS_IMPL_ISUPPORTS(CacheEntryDoomByKeyCallback, CacheFileIOListener);
+NS_IMETHODIMP CacheEntryDoomByKeyCallback::Run()
+{
+  mCallback->OnCacheEntryDoomed(mResult);
+  return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS(CacheEntryDoomByKeyCallback, CacheFileIOListener, nsIRunnable);
 
 } // anon
 
 nsresult
 CacheStorageService::DoomStorageEntry(CacheStorage const* aStorage,
                                       nsIURI *aURI,
                                       const nsACString & aIdExtension,
                                       nsICacheEntryDoomCallback* aCallback)
@@ -1515,18 +1530,32 @@ CacheStorageService::DoomStorageEntry(Ca
     nsRefPtr<CacheEntryDoomByKeyCallback> callback(
       new CacheEntryDoomByKeyCallback(aCallback));
     rv = CacheFileIOManager::DoomFileByKey(entryKey, callback);
     NS_ENSURE_SUCCESS(rv, rv);
 
     return NS_OK;
   }
 
-  if (aCallback)
-    aCallback->OnCacheEntryDoomed(NS_ERROR_NOT_AVAILABLE);
+  class Callback : public nsRunnable
+  {
+  public:
+    Callback(nsICacheEntryDoomCallback* aCallback) : mCallback(aCallback) { }
+    NS_IMETHODIMP Run()
+    {
+      mCallback->OnCacheEntryDoomed(NS_ERROR_NOT_AVAILABLE);
+      return NS_OK;
+    }
+    nsCOMPtr<nsICacheEntryDoomCallback> mCallback;
+  };
+
+  if (aCallback) {
+    nsRefPtr<nsRunnable> callback = new Callback(aCallback);
+    return NS_DispatchToMainThread(callback);
+  }
 
   return NS_OK;
 }
 
 nsresult
 CacheStorageService::DoomStorageEntries(CacheStorage const* aStorage,
                                         nsICacheEntryDoomCallback* aCallback)
 {
@@ -1612,17 +1641,17 @@ CacheStorageService::DoomStorageEntries(
       mCallback->OnCacheEntryDoomed(NS_OK);
       return NS_OK;
     }
     nsCOMPtr<nsICacheEntryDoomCallback> mCallback;
   };
 
   if (aCallback) {
     nsRefPtr<nsRunnable> callback = new Callback(aCallback);
-    return NS_DispatchToCurrentThread(callback);
+    return NS_DispatchToMainThread(callback);
   }
 
   return NS_OK;
 }
 
 nsresult
 CacheStorageService::WalkStorageEntries(CacheStorage const* aStorage,
                                         bool aVisitEntries,
--- a/netwerk/test/unit/test_cache2-05-visit.js
+++ b/netwerk/test/unit/test_cache2-05-visit.js
@@ -1,33 +1,41 @@
 function run_test()
 {
   do_get_profile();
 
   var storage = getCacheStorage("disk");
   var mc = new MultipleCallbacks(4, function() {
-    syncWithCacheIOThread(function() {
+    // Method asyncVisitStorage() gets the data from index on Cache I/O thread
+    // with INDEX priority, so it is ensured that index contains information
+    // about all pending writes. However, OpenCallback emulates network latency
+    // by postponing the writes using do_execute_soon. We must do the same here
+    // to make sure that all writes are posted to Cache I/O thread before we
+    // visit the storage.
+    do_execute_soon(function() {
+      syncWithCacheIOThread(function() {
 
-      var expectedConsumption = newCacheBackEndUsed()
-        ? 4096
-        : 48;
+        var expectedConsumption = newCacheBackEndUsed()
+          ? 4096
+          : 48;
 
-      storage.asyncVisitStorage(
-        // Test should store 4 entries
-        new VisitCallback(4, expectedConsumption, ["http://a/", "http://b/", "http://c/", "http://d/"], function() {
-          storage.asyncVisitStorage(
-            // Still 4 entries expected, now don't walk them
-            new VisitCallback(4, expectedConsumption, null, function() {
-              finish_cache2_test();
-            }),
-            false
-          );
-        }),
-        true
-      );
+        storage.asyncVisitStorage(
+          // Test should store 4 entries
+          new VisitCallback(4, expectedConsumption, ["http://a/", "http://b/", "http://c/", "http://d/"], function() {
+            storage.asyncVisitStorage(
+              // Still 4 entries expected, now don't walk them
+              new VisitCallback(4, expectedConsumption, null, function() {
+                finish_cache2_test();
+              }),
+              false
+            );
+          }),
+          true
+        );
+      });
     });
   }, !newCacheBackEndUsed());
 
   asyncOpenCacheEntry("http://a/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
     new OpenCallback(NEW, "a1m", "a1d", function(entry) {
       asyncOpenCacheEntry("http://a/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, null,
         new OpenCallback(NORMAL, "a1m", "a1d", function(entry) {
           mc.fired();
--- a/netwerk/test/unit/test_cache2-23-read-over-chunk.js
+++ b/netwerk/test/unit/test_cache2-23-read-over-chunk.js
@@ -17,17 +17,19 @@ function run_test()
       payload += "0";
     else
       payload += String.fromCharCode(i + 65);
   }
 
   asyncOpenCacheEntry("http://read/", "disk", Ci.nsICacheStorage.OPEN_NORMALLY, LoadContextInfo.default,
     new OpenCallback(NEW|WAITFORWRITE, "", payload, function(entry) {
       var is = entry.openInputStream(0);
-      do_check_eq(is.available(), kChunkSize + 10);
-      var payloadCheck = read_stream(is, kChunkSize + 10);
-      do_check_true(payloadCheck == payload); // not using do_check_eq since logger will fail for the 1/4MB string
-      finish_cache2_test();
+      pumpReadStream(is, function(read) {
+        do_check_eq(read.length, kChunkSize + 10);
+        is.close();
+        do_check_true(read == payload); // not using do_check_eq since logger will fail for the 1/4MB string
+        finish_cache2_test();
+      });
     })
   );
 
   do_test_pending();
 }