예제 #1
0
NS_IMETHODIMP _OldCacheEntryWrapper::AsyncDoom(nsICacheEntryDoomCallback* listener)
{
  RefPtr<DoomCallbackWrapper> cb = listener
    ? new DoomCallbackWrapper(listener)
    : nullptr;
  return AsyncDoom(cb);
}
예제 #2
0
NS_IMETHODIMP CacheEntry::SetPredictedDataSize(int64_t aPredictedDataSize)
{
  mPredictedDataSize = aPredictedDataSize;

  if (CacheObserver::EntryIsTooBig(mPredictedDataSize, mUseDisk)) {
    LOG(("CacheEntry::SetPredictedDataSize [this=%p] too big, dooming", this));
    AsyncDoom(nullptr);

    return NS_ERROR_FILE_TOO_BIG;
  }

  return NS_OK;
}
예제 #3
0
already_AddRefed<CacheEntryHandle> CacheEntry::ReopenTruncated(bool aMemoryOnly,
                                                               nsICacheEntryOpenCallback* aCallback)
{
  LOG(("CacheEntry::ReopenTruncated [this=%p]", this));

  mLock.AssertCurrentThreadOwns();

  // Hold callbacks invocation, AddStorageEntry would invoke from doom prematurly
  mPreventCallbacks = true;

  nsRefPtr<CacheEntryHandle> handle;
  nsRefPtr<CacheEntry> newEntry;
  {
    mozilla::MutexAutoUnlock unlock(mLock);

    // The following call dooms this entry (calls DoomAlreadyRemoved on us)
    nsresult rv = CacheStorageService::Self()->AddStorageEntry(
      GetStorageID(), GetURI(), GetEnhanceID(),
      mUseDisk && !aMemoryOnly,
      true, // always create
      true, // truncate existing (this one)
      getter_AddRefs(handle));

    if (NS_SUCCEEDED(rv)) {
      newEntry = handle->Entry();
      LOG(("  exchanged entry %p by entry %p, rv=0x%08x", this, newEntry.get(), rv));
      newEntry->AsyncOpen(aCallback, nsICacheStorage::OPEN_TRUNCATE);
    } else {
      LOG(("  exchanged of entry %p failed, rv=0x%08x", this, rv));
      AsyncDoom(nullptr);
    }
  }

  mPreventCallbacks = false;

  if (!newEntry)
    return nullptr;

  newEntry->TransferCallbacks(*this);
  mCallbacks.Clear();

  // Must return a new write handle, since the consumer is expected to
  // write to this newly recreated entry.  The |handle| is only a common
  // reference counter and doesn't revert entry state back when write
  // fails and also doesn't update the entry frecency.  Not updating
  // frecency causes entries to not be purged from our memory pools.
  nsRefPtr<CacheEntryHandle> writeHandle =
    newEntry->NewWriteHandle();
  return writeHandle.forget();
}
예제 #4
0
already_AddRefed<CacheEntryHandle> CacheEntry::ReopenTruncated(bool aMemoryOnly,
                                                               nsICacheEntryOpenCallback* aCallback)
{
  LOG(("CacheEntry::ReopenTruncated [this=%p]", this));

  mLock.AssertCurrentThreadOwns();

  // Hold callbacks invocation, AddStorageEntry would invoke from doom prematurly
  mPreventCallbacks = true;

  nsRefPtr<CacheEntryHandle> handle;
  nsRefPtr<CacheEntry> newEntry;
  {
    mozilla::MutexAutoUnlock unlock(mLock);

    // The following call dooms this entry (calls DoomAlreadyRemoved on us)
    nsresult rv = CacheStorageService::Self()->AddStorageEntry(
      GetStorageID(), GetURI(), GetEnhanceID(),
      mUseDisk && !aMemoryOnly,
      true, // always create
      true, // truncate existing (this one)
      getter_AddRefs(handle));

    LOG(("  exchanged entry %p by entry %p, rv=0x%08x", this, newEntry.get(), rv));

    if (NS_SUCCEEDED(rv)) {
      newEntry = handle->Entry();
      newEntry->AsyncOpen(aCallback, nsICacheStorage::OPEN_TRUNCATE);
    }
    else {
      AsyncDoom(nullptr);
    }
  }

  mPreventCallbacks = false;

  if (!newEntry)
    return nullptr;

  newEntry->TransferCallbacks(*this);
  mCallbacks.Clear();

  return handle.forget();
}
예제 #5
0
bool CacheEntry::Load(bool aTruncate, bool aPriority)
{
  LOG(("CacheEntry::Load [this=%p, trunc=%d]", this, aTruncate));

  mLock.AssertCurrentThreadOwns();

  if (mState > LOADING) {
    LOG(("  already loaded"));
    return false;
  }

  if (mState == LOADING) {
    LOG(("  already loading"));
    return true;
  }

  mState = LOADING;

  MOZ_ASSERT(!mFile);

  nsresult rv;

  nsAutoCString fileKey;
  rv = HashingKeyWithStorage(fileKey);

  // Check the index under two conditions for two states and take appropriate action:
  // 1. When this is a disk entry and not told to truncate, check there is a disk file.
  //    If not, set the 'truncate' flag to true so that this entry will open instantly
  //    as a new one.
  // 2. When this is a memory-only entry, check there is a disk file.
  //    If there is or could be, doom that file.
  if ((!aTruncate || !mUseDisk) && NS_SUCCEEDED(rv)) {
    // Check the index right now to know we have or have not the entry
    // as soon as possible.
    CacheIndex::EntryStatus status;
    if (NS_SUCCEEDED(CacheIndex::HasEntry(fileKey, &status))) {
      switch (status) {
      case CacheIndex::DOES_NOT_EXIST:
        LOG(("  entry doesn't exist according information from the index, truncating"));
        aTruncate = true;
        break;
      case CacheIndex::EXISTS:
      case CacheIndex::DO_NOT_KNOW:
        if (!mUseDisk) {
          LOG(("  entry open as memory-only, but there is (status=%d) a file, dooming it", status));
          CacheFileIOManager::DoomFileByKey(fileKey, nullptr);
        }
        break;
      }
    }
  }

  mFile = new CacheFile();

  BackgroundOp(Ops::REGISTER);

  bool directLoad = aTruncate || !mUseDisk;
  if (directLoad) {
    // mLoadStart will be used to calculate telemetry of life-time of this entry.
    // Low resulution is then enough.
    mLoadStart = TimeStamp::NowLoRes();
  } else {
    mLoadStart = TimeStamp::Now();
  }

  {
    mozilla::MutexAutoUnlock unlock(mLock);

    LOG(("  performing load, file=%p", mFile.get()));
    if (NS_SUCCEEDED(rv)) {
      rv = mFile->Init(fileKey,
                       aTruncate,
                       !mUseDisk,
                       aPriority,
                       directLoad ? nullptr : this);
    }

    if (NS_FAILED(rv)) {
      mFileStatus = rv;
      AsyncDoom(nullptr);
      return false;
    }
  }

  if (directLoad) {
    // Just fake the load has already been done as "new".
    mFileStatus = NS_OK;
    mState = EMPTY;
  }

  return mState == LOADING;
}