Beispiel #1
0
void
IDBDatabase::CloseInternal()
{
  AssertIsOnOwningThread();

  if (!mClosed) {
    mClosed = true;

    ExpireFileActors(/* aExpireAll */ true);

    if (mObserver) {
      mObserver->Revoke();

      nsCOMPtr<nsIObserverService> obsSvc = GetObserverService();
      if (obsSvc) {
        // These might not have been registered.
        obsSvc->RemoveObserver(mObserver, kCycleCollectionObserverTopic);
        obsSvc->RemoveObserver(mObserver, kMemoryPressureObserverTopic);

        MOZ_ALWAYS_TRUE(NS_SUCCEEDED(
          obsSvc->RemoveObserver(mObserver, kWindowObserverTopic)));
      }

      mObserver = nullptr;
    }

    if (mBackgroundActor && !mInvalidated) {
      mBackgroundActor->SendClose();
    }
  }
}
Beispiel #2
0
nsresult
IDBDatabase::Transaction(JSContext* aCx,
                         const StringOrStringSequence& aStoreNames,
                         IDBTransactionMode aMode,
                         IDBTransaction** aTransaction)
{
  AssertIsOnOwningThread();

  if (NS_WARN_IF((aMode == IDBTransactionMode::Readwriteflush ||
                  aMode == IDBTransactionMode::Cleanup) &&
                 !IndexedDatabaseManager::ExperimentalFeaturesEnabled())) {
    IDB_REPORT_INTERNAL_ERR();
    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
  }

  if (QuotaManager::IsShuttingDown()) {
    IDB_REPORT_INTERNAL_ERR();
    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
  }

  if (mClosed || RunningVersionChangeTransaction()) {
    return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
  }

  AutoTArray<nsString, 1> stackSequence;

  if (aStoreNames.IsString()) {
    stackSequence.AppendElement(aStoreNames.GetAsString());
  } else {
    MOZ_ASSERT(aStoreNames.IsStringSequence());
    if (aStoreNames.GetAsStringSequence().IsEmpty()) {
      return NS_ERROR_DOM_INVALID_ACCESS_ERR;
    }
  }

  const nsTArray<nsString>& storeNames =
    aStoreNames.IsString() ?
    stackSequence :
    static_cast<const nsTArray<nsString>&>(aStoreNames.GetAsStringSequence());
  MOZ_ASSERT(!storeNames.IsEmpty());

  const nsTArray<ObjectStoreSpec>& objectStores = mSpec->objectStores();
  const uint32_t nameCount = storeNames.Length();

  nsTArray<nsString> sortedStoreNames;
  sortedStoreNames.SetCapacity(nameCount);

  // Check to make sure the object store names we collected actually exist.
  for (uint32_t nameIndex = 0; nameIndex < nameCount; nameIndex++) {
    const nsString& name = storeNames[nameIndex];

    bool found = false;

    for (uint32_t objCount = objectStores.Length(), objIndex = 0;
         objIndex < objCount;
         objIndex++) {
      if (objectStores[objIndex].metadata().name() == name) {
        found = true;
        break;
      }
    }

    if (!found) {
      return NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR;
    }

    sortedStoreNames.InsertElementSorted(name);
  }

  // Remove any duplicates.
  for (uint32_t nameIndex = nameCount - 1; nameIndex > 0; nameIndex--) {
    if (sortedStoreNames[nameIndex] == sortedStoreNames[nameIndex - 1]) {
      sortedStoreNames.RemoveElementAt(nameIndex);
    }
  }

  IDBTransaction::Mode mode;
  switch (aMode) {
    case IDBTransactionMode::Readonly:
      mode = IDBTransaction::READ_ONLY;
      break;
    case IDBTransactionMode::Readwrite:
      mode = IDBTransaction::READ_WRITE;
      break;
    case IDBTransactionMode::Readwriteflush:
      mode = IDBTransaction::READ_WRITE_FLUSH;
      break;
    case IDBTransactionMode::Cleanup:
      mode = IDBTransaction::CLEANUP;
      break;
    case IDBTransactionMode::Versionchange:
      return NS_ERROR_DOM_INVALID_ACCESS_ERR;

    default:
      MOZ_CRASH("Unknown mode!");
  }

  RefPtr<IDBTransaction> transaction =
    IDBTransaction::Create(aCx, this, sortedStoreNames, mode);
  if (NS_WARN_IF(!transaction)) {
    IDB_REPORT_INTERNAL_ERR();
    return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
  }

  BackgroundTransactionChild* actor =
    new BackgroundTransactionChild(transaction);

  IDB_LOG_MARK("IndexedDB %s: Child  Transaction[%lld]: "
                 "database(%s).transaction(%s)",
               "IndexedDB %s: C T[%lld]: IDBDatabase.transaction()",
               IDB_LOG_ID_STRING(),
               transaction->LoggingSerialNumber(),
               IDB_LOG_STRINGIFY(this),
               IDB_LOG_STRINGIFY(transaction));

  MOZ_ALWAYS_TRUE(
    mBackgroundActor->SendPBackgroundIDBTransactionConstructor(actor,
                                                               sortedStoreNames,
                                                               mode));

  transaction->SetBackgroundActor(actor);

  if (aMode == IDBTransactionMode::Cleanup) {
    ExpireFileActors(/* aExpireAll */ true);
  }

  transaction.forget(aTransaction);
  return NS_OK;
}