Esempio n. 1
0
nsresult
FileHandleBase::CreateParallelStream(nsISupports** aStream)
{
  MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");

  MutableFileBase* mutableFile = MutableFile();

  if (mutableFile->IsInvalid()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  nsCOMPtr<nsISupports> stream =
    mutableFile->CreateStream(mMode == FileMode::Readonly);
  NS_ENSURE_TRUE(stream, NS_ERROR_FAILURE);

  mParallelStreams.AppendElement(stream);

  stream.forget(aStream);
  return NS_OK;
}
Esempio n. 2
0
nsresult
FileService::Enqueue(FileHandleBase* aFileHandle, FileHelper* aFileHelper)
{
  MOZ_ASSERT(NS_IsMainThread(), "Wrong thread!");
  MOZ_ASSERT(aFileHandle, "Null pointer!");

  MutableFileBase* mutableFile = aFileHandle->MutableFile();

  if (mutableFile->IsInvalid()) {
    return NS_ERROR_NOT_AVAILABLE;
  }

  const nsACString& storageId = mutableFile->mStorageId;
  const nsAString& fileName = mutableFile->mFileName;
  bool modeIsWrite = aFileHandle->mMode == FileMode::Readwrite;

  StorageInfo* storageInfo;
  if (!mStorageInfos.Get(storageId, &storageInfo)) {
    nsAutoPtr<StorageInfo> newStorageInfo(new StorageInfo());

    mStorageInfos.Put(storageId, newStorageInfo);

    storageInfo = newStorageInfo.forget();
  }

  FileHandleQueue* existingFileHandleQueue =
    storageInfo->GetFileHandleQueue(aFileHandle);

  if (existingFileHandleQueue) {
    existingFileHandleQueue->Enqueue(aFileHelper);
    return NS_OK;
  }

  bool lockedForReading = storageInfo->IsFileLockedForReading(fileName);
  bool lockedForWriting = storageInfo->IsFileLockedForWriting(fileName);

  if (modeIsWrite) {
    if (!lockedForWriting) {
      storageInfo->LockFileForWriting(fileName);
    }
  }
  else {
    if (!lockedForReading) {
      storageInfo->LockFileForReading(fileName);
    }
  }

  if (lockedForWriting || (lockedForReading && modeIsWrite)) {
    storageInfo->CreateDelayedEnqueueInfo(aFileHandle, aFileHelper);
  }
  else {
    FileHandleQueue* fileHandleQueue =
      storageInfo->CreateFileHandleQueue(aFileHandle);

    if (aFileHelper) {
      // Enqueue() will queue the file helper if there's already something
      // running. That can't fail, so no need to eventually remove
      // storageInfo from the hash table.
      //
      // If the file helper is free to run then AsyncRun() is called on the
      // file helper. AsyncRun() is responsible for calling all necessary
      // callbacks when something fails. We're propagating the error here,
      // however there's no need to eventually remove storageInfo from
      // the hash table. Code behind AsyncRun() will take care of it. The last
      // item in the code path is NotifyFileHandleCompleted() which removes
      // storageInfo from the hash table if there are no file handles for
      // the file storage.
      nsresult rv = fileHandleQueue->Enqueue(aFileHelper);
      NS_ENSURE_SUCCESS(rv, rv);
    }
  }

  return NS_OK;
}