Example #1
0
NS_IMETHODIMP
CacheFileInputStream::AsyncWait(nsIInputStreamCallback *aCallback,
                                uint32_t aFlags,
                                uint32_t aRequestedCount,
                                nsIEventTarget *aEventTarget)
{
  CacheFileAutoLock lock(mFile);
  MOZ_ASSERT(!mInReadSegments);

  LOG(("CacheFileInputStream::AsyncWait() [this=%p, callback=%p, flags=%d, "
       "requestedCount=%d, eventTarget=%p]", this, aCallback, aFlags,
       aRequestedCount, aEventTarget));

  mCallback = aCallback;
  mCallbackFlags = aFlags;

  if (!mCallback) {
    if (mWaitingForUpdate) {
      mChunk->CancelWait(this);
      mWaitingForUpdate = false;
    }
    return NS_OK;
  }

  if (mClosed) {
    NotifyListener();
    return NS_OK;
  }

  EnsureCorrectChunk(false);

  MaybeNotifyListener();

  return NS_OK;
}
Example #2
0
nsresult
CacheFileInputStream::OnChunkUpdated(CacheFileChunk *aChunk)
{
  CacheFileAutoLock lock(mFile);
  MOZ_ASSERT(!mInReadSegments);

  LOG(("CacheFileInputStream::OnChunkUpdated() [this=%p, idx=%d]",
       this, aChunk->Index()));

  if (!mWaitingForUpdate) {
    LOG(("CacheFileInputStream::OnChunkUpdated() - Ignoring notification since "
         "mWaitingforUpdate == false. [this=%p]", this));

    return NS_OK;
  }
  else {
    mWaitingForUpdate = false;
  }

  MOZ_ASSERT(mChunk == aChunk);

  MaybeNotifyListener();

  return NS_OK;
}
Example #3
0
// nsIAsyncInputStream
NS_IMETHODIMP
CacheFileInputStream::CloseWithStatus(nsresult aStatus)
{
  CacheFileAutoLock lock(mFile);
  MOZ_ASSERT(!mInReadSegments);

  LOG(("CacheFileInputStream::CloseWithStatus() [this=%p, aStatus=0x%08x]",
       this, aStatus));

  if (mClosed) {
    MOZ_ASSERT(!mCallback);
    return NS_OK;
  }

  mClosed = true;
  mStatus = NS_FAILED(aStatus) ? aStatus : NS_BASE_STREAM_CLOSED;

  if (mChunk)
    ReleaseChunk();

  // TODO propagate error from input stream to other streams ???

  MaybeNotifyListener();

  return NS_OK;
}
nsresult
CacheFileInputStream::CloseWithStatusLocked(nsresult aStatus)
{
  LOG(("CacheFileInputStream::CloseWithStatusLocked() [this=%p, "
       "aStatus=0x%08x]", this, aStatus));

  if (mClosed) {
    MOZ_ASSERT(!mCallback);
    return NS_OK;
  }

  mClosed = true;
  mStatus = NS_FAILED(aStatus) ? aStatus : NS_BASE_STREAM_CLOSED;

  if (mChunk) {
    ReleaseChunk();
  }

  // TODO propagate error from input stream to other streams ???

  MaybeNotifyListener();

  mFile->ReleaseOutsideLock(mCacheEntryHandle.forget());

  return NS_OK;
}
void
CacheFileInputStream::EnsureCorrectChunk(bool aReleaseOnly)
{
  mFile->AssertOwnsLock();

  LOG(("CacheFileInputStream::EnsureCorrectChunk() [this=%p, releaseOnly=%d]",
       this, aReleaseOnly));

  nsresult rv;

  uint32_t chunkIdx = mPos / kChunkSize;

  if (mChunk) {
    if (mChunk->Index() == chunkIdx) {
      // we have a correct chunk
      LOG(("CacheFileInputStream::EnsureCorrectChunk() - Have correct chunk "
           "[this=%p, idx=%d]", this, chunkIdx));

      return;
    }
    else {
      ReleaseChunk();
    }
  }

  MOZ_ASSERT(!mWaitingForUpdate);

  if (aReleaseOnly)
    return;

  if (mListeningForChunk == static_cast<int64_t>(chunkIdx)) {
    // We're already waiting for this chunk
    LOG(("CacheFileInputStream::EnsureCorrectChunk() - Already listening for "
         "chunk %lld [this=%p]", mListeningForChunk, this));

    return;
  }

  rv = mFile->GetChunkLocked(chunkIdx, CacheFile::READER, this,
                             getter_AddRefs(mChunk));
  if (NS_FAILED(rv)) {
    LOG(("CacheFileInputStream::EnsureCorrectChunk() - GetChunkLocked failed. "
         "[this=%p, idx=%d, rv=0x%08x]", this, chunkIdx, rv));
    if (rv != NS_ERROR_NOT_AVAILABLE) {
      // Close the stream with error. The consumer will receive this error later
      // in Read(), Available() etc. We need to handle NS_ERROR_NOT_AVAILABLE
      // differently since it is returned when the requested chunk is not
      // available and there is no writer that could create it, i.e. it means
      // that we've reached the end of the file.
      CloseWithStatusLocked(rv);

      return;
    }
  } else if (!mChunk) {
    mListeningForChunk = static_cast<int64_t>(chunkIdx);
  }

  MaybeNotifyListener();
}
Example #6
0
void
CacheFileInputStream::EnsureCorrectChunk(bool aReleaseOnly)
{
  mFile->AssertOwnsLock();

  LOG(("CacheFileInputStream::EnsureCorrectChunk() [this=%p, releaseOnly=%d]",
       this, aReleaseOnly));

  nsresult rv;

  uint32_t chunkIdx = mPos / kChunkSize;

  if (mChunk) {
    if (mChunk->Index() == chunkIdx) {
      // we have a correct chunk
      LOG(("CacheFileInputStream::EnsureCorrectChunk() - Have correct chunk "
           "[this=%p, idx=%d]", this, chunkIdx));

      return;
    }
    else {
      ReleaseChunk();
    }
  }

  MOZ_ASSERT(!mWaitingForUpdate);

  if (aReleaseOnly)
    return;

  if (mListeningForChunk == static_cast<int64_t>(chunkIdx)) {
    // We're already waiting for this chunk
    LOG(("CacheFileInputStream::EnsureCorrectChunk() - Already listening for "
         "chunk %lld [this=%p]", mListeningForChunk, this));

    return;
  }

  rv = mFile->GetChunkLocked(chunkIdx, false, this, getter_AddRefs(mChunk));
  if (NS_FAILED(rv)) {
    LOG(("CacheFileInputStream::EnsureCorrectChunk() - GetChunkLocked failed. "
         "[this=%p, idx=%d, rv=0x%08x]", this, chunkIdx, rv));

  }
  else if (!mChunk) {
    mListeningForChunk = static_cast<int64_t>(chunkIdx);
  }

  MaybeNotifyListener();
}
nsresult
CacheFileInputStream::OnChunkAvailable(nsresult aResult, uint32_t aChunkIdx,
                                       CacheFileChunk *aChunk)
{
  CacheFileAutoLock lock(mFile);

  LOG(("CacheFileInputStream::OnChunkAvailable() [this=%p, result=0x%08x, "
       "idx=%d, chunk=%p]", this, aResult, aChunkIdx, aChunk));

  MOZ_ASSERT(mListeningForChunk != -1);

  if (mListeningForChunk != static_cast<int64_t>(aChunkIdx)) {
    // This is not a chunk that we're waiting for
    LOG(("CacheFileInputStream::OnChunkAvailable() - Notification is for a "
         "different chunk. [this=%p, listeningForChunk=%lld]",
         this, mListeningForChunk));

    return NS_OK;
  }

  MOZ_ASSERT(!mChunk);
  MOZ_ASSERT(!mWaitingForUpdate);
  mListeningForChunk = -1;

  if (mClosed) {
    MOZ_ASSERT(!mCallback);

    LOG(("CacheFileInputStream::OnChunkAvailable() - Stream is closed, "
         "ignoring notification. [this=%p]", this));

    return NS_OK;
  }

  if (NS_SUCCEEDED(aResult)) {
    mChunk = aChunk;
  } else if (aResult != NS_ERROR_NOT_AVAILABLE) {
    // Close the stream with error. The consumer will receive this error later
    // in Read(), Available() etc. We need to handle NS_ERROR_NOT_AVAILABLE
    // differently since it is returned when the requested chunk is not
    // available and there is no writer that could create it, i.e. it means that
    // we've reached the end of the file.
    CloseWithStatusLocked(aResult);

    return NS_OK;
  }

  MaybeNotifyListener();

  return NS_OK;
}
Example #8
0
nsresult
CacheFileInputStream::OnChunkAvailable(nsresult aResult, uint32_t aChunkIdx,
                                       CacheFileChunk *aChunk)
{
  CacheFileAutoLock lock(mFile);
  MOZ_ASSERT(!mInReadSegments);

  LOG(("CacheFileInputStream::OnChunkAvailable() [this=%p, result=0x%08x, "
       "idx=%d, chunk=%p]", this, aResult, aChunkIdx, aChunk));

  MOZ_ASSERT(mListeningForChunk != -1);

  if (mListeningForChunk != static_cast<int64_t>(aChunkIdx)) {
    // This is not a chunk that we're waiting for
    LOG(("CacheFileInputStream::OnChunkAvailable() - Notification is for a "
         "different chunk. [this=%p, listeningForChunk=%lld]",
         this, mListeningForChunk));

    return NS_OK;
  }

  MOZ_ASSERT(!mChunk);
  MOZ_ASSERT(!mWaitingForUpdate);
  mListeningForChunk = -1;

  if (mClosed) {
    MOZ_ASSERT(!mCallback);

    LOG(("CacheFileInputStream::OnChunkAvailable() - Stream is closed, "
         "ignoring notification. [this=%p]", this));

    return NS_OK;
  }

  mChunk = aChunk;
  MaybeNotifyListener();

  return NS_OK;
}