Commit 7d81a268 authored by Victor Costan's avatar Victor Costan Committed by Chromium LUCI CQ

IndexedDB: Tighten up IndexedDBBackingStore thread safety checks.

This CL updates IndexedDBBackingStore and its inner classes.

* Each class is documented as not thread-safe. The obsolete thread
  safety comment on IndexedDBBackingstore is removed.

* Each class' data members are either marked const or
  GUARDED_BY_CONTEXT with a SequenceChecker.

* DISALLOW_COPY_AND_ASSIGN is replaced with deleted copy constructor and
  assignment.

* An unused data member was removed.

* Data members initialized with constants in constructors are instead
  initialized when declared.

* Invariant-enforcing DCHECKs are consistently placed at the beginning
  of methods.

This CL introduces no functional changes.

Change-Id: I8a38d0f2225ff4b5334fd37891a8216b8bb72930
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2588292Reviewed-by: default avatarChris Mumford <cmumford@google.com>
Commit-Queue: Victor Costan <pwnall@chromium.org>
Cr-Commit-Position: refs/heads/master@{#836952}
parent bc35381b
......@@ -8,6 +8,7 @@
#include <utility>
#include "base/bind.h"
#include "base/dcheck_is_on.h"
#include "base/files/file_path.h"
#include "base/format_macros.h"
#include "base/json/json_reader.h"
......@@ -17,10 +18,12 @@
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/optional.h"
#include "base/sequence_checker.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/thread_annotations.h"
#include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
......@@ -62,13 +65,11 @@
#include "third_party/blink/public/mojom/blob/blob.mojom.h"
#include "third_party/leveldatabase/env_chromium.h"
using base::FilePath;
using base::StringPiece;
using blink::IndexedDBDatabaseMetadata;
using blink::IndexedDBKey;
using blink::IndexedDBKeyRange;
using leveldb::Status;
using url::Origin;
namespace content {
using indexed_db::CheckIndexAndMetaDataKey;
......@@ -95,40 +96,42 @@ class AutoDidCommitTransaction {
: backing_store_(backing_store) {
DCHECK(backing_store_);
}
~AutoDidCommitTransaction() { backing_store_->DidCommitTransaction(); }
AutoDidCommitTransaction(const AutoDidCommitTransaction&) = delete;
AutoDidCommitTransaction operator=(const AutoDidCommitTransaction&) = delete;
~AutoDidCommitTransaction() { backing_store_->DidCommitTransaction(); }
private:
IndexedDBBackingStore* backing_store_;
IndexedDBBackingStore* const backing_store_;
};
namespace {
FilePath GetBlobDirectoryName(const FilePath& path_base, int64_t database_id) {
base::FilePath GetBlobDirectoryName(const base::FilePath& path_base,
int64_t database_id) {
return path_base.AppendASCII(base::StringPrintf("%" PRIx64, database_id));
}
FilePath GetBlobDirectoryNameForKey(const FilePath& path_base,
base::FilePath GetBlobDirectoryNameForKey(const base::FilePath& path_base,
int64_t database_id,
int64_t blob_number) {
FilePath path = GetBlobDirectoryName(path_base, database_id);
base::FilePath path = GetBlobDirectoryName(path_base, database_id);
path = path.AppendASCII(base::StringPrintf(
"%02x", static_cast<int>(blob_number & 0x000000000000ff00) >> 8));
return path;
}
FilePath GetBlobFileNameForKey(const FilePath& path_base,
base::FilePath GetBlobFileNameForKey(const base::FilePath& path_base,
int64_t database_id,
int64_t blob_number) {
FilePath path =
base::FilePath path =
GetBlobDirectoryNameForKey(path_base, database_id, blob_number);
path = path.AppendASCII(base::StringPrintf("%" PRIx64, blob_number));
return path;
}
std::string ComputeOriginIdentifier(const Origin& origin) {
std::string ComputeOriginIdentifier(const url::Origin& origin) {
return storage::GetIdentifierFromOrigin(origin) + "@1";
}
......@@ -145,6 +148,7 @@ Status GetBlobJournal(const StringPiece& key,
TransactionType* transaction,
BlobJournalType* journal) {
IDB_TRACE("IndexedDBBackingStore::GetBlobJournal");
std::string data;
bool found = false;
Status s = transaction->Get(key, &data, &found);
......@@ -244,6 +248,7 @@ Status MergeDatabaseIntoBlobJournal(
const std::string& key,
int64_t database_id) {
IDB_TRACE("IndexedDBBackingStore::MergeDatabaseIntoBlobJournal");
BlobJournalType journal;
Status s = GetBlobJournal(key, transaction, &journal);
if (!s.ok())
......@@ -326,13 +331,12 @@ bool DecodeV3ExternalObjects(const base::StringPiece& data,
if (is_file) {
if (!DecodeStringWithLength(&slice, &file_name))
return false;
ret.push_back(
IndexedDBExternalObject(blob_number, type, file_name, base::Time(),
IndexedDBExternalObject::kUnknownSize));
ret.emplace_back(blob_number, type, file_name, base::Time(),
IndexedDBExternalObject::kUnknownSize);
} else {
if (!DecodeVarInt(&slice, &size) || size < 0)
return false;
ret.push_back(IndexedDBExternalObject(type, size, blob_number));
ret.emplace_back(type, size, blob_number);
}
}
output->swap(ret);
......@@ -371,7 +375,7 @@ bool DecodeExternalObjects(const std::string& data,
if (!DecodeVarInt(&slice, &size) || size < 0)
return false;
if (object_type != IndexedDBExternalObject::ObjectType::kFile) {
ret.push_back(IndexedDBExternalObject(type, size, blob_number));
ret.emplace_back(type, size, blob_number);
break;
}
if (!DecodeStringWithLength(&slice, &file_name))
......@@ -379,19 +383,17 @@ bool DecodeExternalObjects(const std::string& data,
int64_t last_modified;
if (!DecodeVarInt(&slice, &last_modified) || size < 0)
return false;
ret.push_back(IndexedDBExternalObject(
blob_number, type, file_name,
ret.emplace_back(blob_number, type, file_name,
base::Time::FromDeltaSinceWindowsEpoch(
base::TimeDelta::FromMicroseconds(last_modified)),
size));
size);
break;
}
case IndexedDBExternalObject::ObjectType::kNativeFileSystemHandle: {
base::span<const uint8_t> token;
if (!DecodeBinary(&slice, &token))
return false;
ret.push_back(IndexedDBExternalObject(
std::vector<uint8_t>(token.begin(), token.end())));
ret.emplace_back(std::vector<uint8_t>(token.begin(), token.end()));
break;
}
}
......@@ -548,8 +550,10 @@ bool IndexCursorOptions(
blink::mojom::IDBCursorDirection direction,
IndexedDBBackingStore::Cursor::CursorOptions* cursor_options,
Status* status) {
IDB_TRACE("IndexedDBBackingStore::IndexCursorOptions");
DCHECK(transaction);
DCHECK(cursor_options);
IDB_TRACE("IndexedDBBackingStore::IndexCursorOptions");
if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
return false;
......@@ -619,8 +623,8 @@ bool IndexCursorOptions(
IndexedDBBackingStore::IndexedDBBackingStore(
Mode backing_store_mode,
TransactionalLevelDBFactory* transactional_leveldb_factory,
const Origin& origin,
const FilePath& blob_path,
const url::Origin& origin,
const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db,
storage::mojom::BlobStorageContext* blob_storage_context,
storage::mojom::NativeFileSystemContext* native_file_system_context,
......@@ -631,20 +635,19 @@ IndexedDBBackingStore::IndexedDBBackingStore(
: backing_store_mode_(backing_store_mode),
transactional_leveldb_factory_(transactional_leveldb_factory),
origin_(origin),
blob_path_(blob_path),
blob_path_(backing_store_mode == Mode::kInMemory ? base::FilePath()
: blob_path),
blob_storage_context_(blob_storage_context),
native_file_system_context_(native_file_system_context),
filesystem_proxy_(std::move(filesystem_proxy)),
origin_identifier_(ComputeOriginIdentifier(origin)),
idb_task_runner_(idb_task_runner),
idb_task_runner_(std::move(idb_task_runner)),
db_(std::move(db)),
blob_files_cleaned_(std::move(blob_files_cleaned)) {
DCHECK(idb_task_runner_->RunsTasksInCurrentSequence());
if (backing_store_mode == Mode::kInMemory) {
blob_path_ = FilePath();
} else {
DCHECK(filesystem_proxy_) << "On disk database must have a filesystem";
}
if (backing_store_mode != Mode::kInMemory)
DCHECK(filesystem_proxy_) << "On disk databases must have a filesystem";
active_blob_registry_ = std::make_unique<IndexedDBActiveBlobRegistry>(
std::move(report_outstanding_blobs),
base::BindRepeating(&IndexedDBBackingStore::ReportBlobUnused,
......@@ -652,18 +655,28 @@ IndexedDBBackingStore::IndexedDBBackingStore(
}
IndexedDBBackingStore::~IndexedDBBackingStore() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
IndexedDBBackingStore::RecordIdentifier::RecordIdentifier(
const std::string& primary_key,
std::string primary_key,
int64_t version)
: primary_key_(primary_key), version_(version) {
: primary_key_(std::move(primary_key)), version_(version) {
DCHECK(!primary_key.empty());
}
IndexedDBBackingStore::RecordIdentifier::RecordIdentifier()
: primary_key_(), version_(-1) {}
IndexedDBBackingStore::RecordIdentifier::~RecordIdentifier() = default;
IndexedDBBackingStore::RecordIdentifier::RecordIdentifier() = default;
IndexedDBBackingStore::RecordIdentifier::~RecordIdentifier() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
void IndexedDBBackingStore::RecordIdentifier::Reset(std::string primary_key,
int64_t version) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
primary_key_ = std::move(primary_key);
version_ = version;
}
constexpr const int IndexedDBBackingStore::kMaxJournalCleanRequests;
constexpr const base::TimeDelta
......@@ -673,7 +686,7 @@ constexpr const base::TimeDelta
leveldb::Status IndexedDBBackingStore::Initialize(bool clean_active_journal) {
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!initialized_);
#endif
const IndexedDBDataFormatVersion latest_known_data_version =
......@@ -798,7 +811,7 @@ leveldb::Status IndexedDBBackingStore::Initialize(bool clean_active_journal) {
Status IndexedDBBackingStore::AnyDatabaseContainsBlobs(
TransactionalLevelDBDatabase* db,
bool* blobs_exist) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
Status status = leveldb::Status::OK();
std::vector<base::string16> names;
......@@ -853,6 +866,7 @@ Status IndexedDBBackingStore::UpgradeBlobEntriesToV4(
TransactionalLevelDBDatabase* db,
LevelDBWriteBatch* write_batch,
std::vector<base::FilePath>* empty_blobs_to_delete) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(filesystem_proxy_);
Status status = leveldb::Status::OK();
......@@ -939,6 +953,7 @@ Status IndexedDBBackingStore::UpgradeBlobEntriesToV4(
Status IndexedDBBackingStore::ValidateBlobFiles(
TransactionalLevelDBDatabase* db) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(filesystem_proxy_);
Status status = leveldb::Status::OK();
......@@ -1016,7 +1031,7 @@ Status IndexedDBBackingStore::ValidateBlobFiles(
Status IndexedDBBackingStore::RevertSchemaToV2() {
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(initialized_);
#endif
const std::string schema_version_key = SchemaVersionKey::Encode();
......@@ -1029,8 +1044,8 @@ Status IndexedDBBackingStore::RevertSchemaToV2() {
}
V2SchemaCorruptionStatus IndexedDBBackingStore::HasV2SchemaCorruption() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
const std::string schema_version_key = SchemaVersionKey::Encode();
......@@ -1056,7 +1071,7 @@ std::unique_ptr<IndexedDBBackingStore::Transaction>
IndexedDBBackingStore::CreateTransaction(
blink::mojom::IDBTransactionDurability durability,
blink::mojom::IDBTransactionMode mode) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return std::make_unique<IndexedDBBackingStore::Transaction>(
weak_factory_.GetWeakPtr(), durability, mode);
}
......@@ -1075,8 +1090,8 @@ bool IndexedDBBackingStore::ShouldSyncOnCommit(
leveldb::Status IndexedDBBackingStore::GetCompleteMetadata(
std::vector<IndexedDBDatabaseMetadata>* output) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
......@@ -1108,7 +1123,7 @@ leveldb::Status IndexedDBBackingStore::GetCompleteMetadata(
// static
bool IndexedDBBackingStore::RecordCorruptionInfo(
const base::FilePath& path_base,
const Origin& origin,
const url::Origin& origin,
const std::string& message) {
auto filesystem = storage::CreateFilesystemProxy();
const base::FilePath info_path =
......@@ -1127,8 +1142,8 @@ bool IndexedDBBackingStore::RecordCorruptionInfo(
Status IndexedDBBackingStore::DeleteDatabase(
const base::string16& name,
TransactionalLevelDBTransaction* transaction) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
IDB_TRACE("IndexedDBBackingStore::DeleteDatabase");
......@@ -1196,8 +1211,8 @@ Status IndexedDBBackingStore::DeleteDatabase(
}
void IndexedDBBackingStore::Compact() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
db_->CompactAll();
......@@ -1209,8 +1224,8 @@ Status IndexedDBBackingStore::GetRecord(
int64_t object_store_id,
const IndexedDBKey& key,
IndexedDBValue* record) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
......@@ -1252,7 +1267,7 @@ Status IndexedDBBackingStore::GetRecord(
}
int64_t IndexedDBBackingStore::GetInMemoryBlobSize() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
int64_t total_size = 0;
for (const auto& kvp : incognito_external_object_map_) {
......@@ -1273,8 +1288,8 @@ Status IndexedDBBackingStore::PutRecord(
const IndexedDBKey& key,
IndexedDBValue* value,
RecordIdentifier* record_identifier) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
......@@ -1324,7 +1339,7 @@ Status IndexedDBBackingStore::ClearObjectStore(
IndexedDBBackingStore::Transaction* transaction,
int64_t database_id,
int64_t object_store_id) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK(initialized_);
#endif
......@@ -1367,7 +1382,7 @@ Status IndexedDBBackingStore::DeleteRecord(
int64_t database_id,
int64_t object_store_id,
const RecordIdentifier& record_identifier) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::DeleteRecord");
if (!KeyPrefix::ValidIds(database_id, object_store_id))
......@@ -1395,8 +1410,8 @@ Status IndexedDBBackingStore::DeleteRange(
int64_t database_id,
int64_t object_store_id,
const IndexedDBKeyRange& key_range) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
......@@ -1459,8 +1474,8 @@ Status IndexedDBBackingStore::GetKeyGeneratorCurrentNumber(
int64_t database_id,
int64_t object_store_id,
int64_t* key_generator_current_number) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
if (!KeyPrefix::ValidIds(database_id, object_store_id))
......@@ -1541,8 +1556,8 @@ Status IndexedDBBackingStore::MaybeUpdateKeyGeneratorCurrentNumber(
int64_t object_store_id,
int64_t new_number,
bool check_current) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
if (!KeyPrefix::ValidIds(database_id, object_store_id))
......@@ -1573,8 +1588,8 @@ Status IndexedDBBackingStore::KeyExistsInObjectStore(
const IndexedDBKey& key,
RecordIdentifier* found_record_identifier,
bool* found) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
IDB_TRACE("IndexedDBBackingStore::KeyExistsInObjectStore");
......@@ -1611,8 +1626,8 @@ Status IndexedDBBackingStore::KeyExistsInObjectStore(
void IndexedDBBackingStore::ReportBlobUnused(int64_t database_id,
int64_t blob_number) {
DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
bool all_blobs = blob_number == DatabaseMetaDataKey::kAllBlobsNumber;
......@@ -1678,8 +1693,8 @@ void IndexedDBBackingStore::ReportBlobUnused(int64_t database_id,
// HasLastBackingStoreReference. It's safe because if the backing store is
// deleted, the timer will automatically be canceled on destruction.
void IndexedDBBackingStore::StartJournalCleaningTimer() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
++num_aggregated_journal_cleaning_requests_;
......@@ -1717,17 +1732,18 @@ void IndexedDBBackingStore::StartJournalCleaningTimer() {
}
// This assumes a file path of dbId/second-to-LSB-of-counter/counter.
FilePath IndexedDBBackingStore::GetBlobFileName(int64_t database_id,
base::FilePath IndexedDBBackingStore::GetBlobFileName(
int64_t database_id,
int64_t blob_number) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return GetBlobFileNameForKey(blob_path_, database_id, blob_number);
}
bool IndexedDBBackingStore::RemoveBlobFile(int64_t database_id,
int64_t blob_number) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(filesystem_proxy_) << "Only call this for on disk databases";
FilePath path = GetBlobFileName(database_id, blob_number);
base::FilePath path = GetBlobFileName(database_id, blob_number);
#if DCHECK_IS_ON()
++num_blob_files_deleted_;
DVLOG(1) << "Deleting blob " << blob_number << " from IndexedDB database "
......@@ -1737,16 +1753,16 @@ bool IndexedDBBackingStore::RemoveBlobFile(int64_t database_id,
}
bool IndexedDBBackingStore::RemoveBlobDirectory(int64_t database_id) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(filesystem_proxy_) << "Only call this for on disk databases";
FilePath path = GetBlobDirectoryName(blob_path_, database_id);
base::FilePath path = GetBlobDirectoryName(blob_path_, database_id);
return filesystem_proxy_->DeletePathRecursively(path);
}
Status IndexedDBBackingStore::CleanUpBlobJournal(
const std::string& level_db_key) const {
IDB_TRACE("IndexedDBBackingStore::CleanUpBlobJournal");
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!committing_transaction_count_);
std::unique_ptr<LevelDBDirectTransaction> journal_transaction =
transactional_leveldb_factory_->CreateLevelDBDirectTransaction(db_.get());
......@@ -1771,7 +1787,7 @@ Status IndexedDBBackingStore::CleanUpBlobJournal(
Status IndexedDBBackingStore::CleanUpBlobJournalEntries(
const BlobJournalType& journal) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::CleanUpBlobJournalEntries");
if (journal.empty())
return Status::OK();
......@@ -1794,12 +1810,12 @@ Status IndexedDBBackingStore::CleanUpBlobJournalEntries(
}
void IndexedDBBackingStore::WillCommitTransaction() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
++committing_transaction_count_;
}
void IndexedDBBackingStore::DidCommitTransaction() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_GT(committing_transaction_count_, 0UL);
--committing_transaction_count_;
if (committing_transaction_count_ == 0 &&
......@@ -1813,7 +1829,7 @@ Status IndexedDBBackingStore::Transaction::GetExternalObjectsForRecord(
int64_t database_id,
const std::string& object_store_data_key,
IndexedDBValue* value) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
IndexedDBExternalObjectChangeRecord* change_record = nullptr;
auto object_iter = external_object_change_map_.find(object_store_data_key);
if (object_iter != external_object_change_map_.end()) {
......@@ -1872,12 +1888,12 @@ Status IndexedDBBackingStore::Transaction::GetExternalObjectsForRecord(
base::WeakPtr<IndexedDBBackingStore::Transaction>
IndexedDBBackingStore::Transaction::AsWeakPtr() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
return ptr_factory_.GetWeakPtr();
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return weak_ptr_factory_.GetWeakPtr();
}
void IndexedDBBackingStore::CleanRecoveryJournalIgnoreReturn() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// While a transaction is busy it is not safe to clean the journal.
if (committing_transaction_count_ > 0) {
execute_journal_cleaning_on_no_txns_ = true;
......@@ -1893,8 +1909,8 @@ Status IndexedDBBackingStore::ClearIndex(
int64_t object_store_id,
int64_t index_id) {
IDB_TRACE("IndexedDBBackingStore::ClearIndex");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
......@@ -1924,8 +1940,8 @@ Status IndexedDBBackingStore::PutIndexDataForRecord(
const IndexedDBKey& key,
const RecordIdentifier& record_identifier) {
IDB_TRACE("IndexedDBBackingStore::PutIndexDataForRecord");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
DCHECK(key.IsValid());
......@@ -1955,8 +1971,8 @@ Status IndexedDBBackingStore::FindKeyInIndex(
std::string* found_encoded_primary_key,
bool* found) {
IDB_TRACE("IndexedDBBackingStore::FindKeyInIndex");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
DCHECK(KeyPrefix::ValidIds(database_id, object_store_id, index_id));
......@@ -2023,8 +2039,8 @@ Status IndexedDBBackingStore::GetPrimaryKeyViaIndex(
const IndexedDBKey& key,
std::unique_ptr<IndexedDBKey>* primary_key) {
IDB_TRACE("IndexedDBBackingStore::GetPrimaryKeyViaIndex");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK(initialized_);
#endif
if (!KeyPrefix::ValidIds(database_id, object_store_id, index_id))
......@@ -2060,8 +2076,8 @@ Status IndexedDBBackingStore::KeyExistsInIndex(
const IndexedDBKey& index_key,
std::unique_ptr<IndexedDBKey>* found_primary_key,
bool* exists) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::KeyExistsInIndex");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
#if DCHECK_IS_ON()
DCHECK(initialized_);
#endif
......@@ -2111,13 +2127,18 @@ IndexedDBBackingStore::Cursor::Cursor(base::WeakPtr<Transaction> transaction,
DCHECK(transaction_);
}
IndexedDBBackingStore::Cursor::~Cursor() = default;
IndexedDBBackingStore::Cursor::~Cursor() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
// static
std::unique_ptr<TransactionalLevelDBIterator>
IndexedDBBackingStore::Cursor::CloneIterator(
const IndexedDBBackingStore::Cursor* other) {
if (!other)
return nullptr;
DCHECK_CALLED_ON_VALID_SEQUENCE(other->sequence_checker_);
if (!other->iterator_)
return nullptr;
......@@ -2138,7 +2159,7 @@ IndexedDBBackingStore::Cursor::CloneIterator(
}
bool IndexedDBBackingStore::Cursor::FirstSeek(Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(transaction_);
DCHECK(s);
iterator_ = transaction_->transaction()->CreateIterator(*s);
......@@ -2160,7 +2181,7 @@ bool IndexedDBBackingStore::Cursor::FirstSeek(Status* s) {
}
bool IndexedDBBackingStore::Cursor::Advance(uint32_t count, Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
*s = Status::OK();
while (count--) {
if (!Continue(s))
......@@ -2173,7 +2194,7 @@ bool IndexedDBBackingStore::Cursor::Continue(const IndexedDBKey* key,
const IndexedDBKey* primary_key,
IteratorState next_state,
Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::Cursor::Continue");
DCHECK(!key || next_state == SEEK);
......@@ -2190,7 +2211,7 @@ IndexedDBBackingStore::Cursor::ContinueNext(const IndexedDBKey* key,
const IndexedDBKey* primary_key,
IteratorState next_state,
Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(cursor_options_.forward);
DCHECK(!key || key->IsValid());
DCHECK(!primary_key || primary_key->IsValid());
......@@ -2259,7 +2280,7 @@ IndexedDBBackingStore::Cursor::ContinuePrevious(const IndexedDBKey* key,
const IndexedDBKey* primary_key,
IteratorState next_state,
Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!cursor_options_.forward);
DCHECK(!key || key->IsValid());
DCHECK(!primary_key || primary_key->IsValid());
......@@ -2364,7 +2385,8 @@ IndexedDBBackingStore::Cursor::ContinuePrevious(const IndexedDBKey* key,
}
bool IndexedDBBackingStore::Cursor::HaveEnteredRange() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (cursor_options_.forward) {
int compare = CompareIndexKeys(iterator_->Key(), cursor_options_.low_key);
if (cursor_options_.low_open) {
......@@ -2380,7 +2402,8 @@ bool IndexedDBBackingStore::Cursor::HaveEnteredRange() const {
}
bool IndexedDBBackingStore::Cursor::IsPastBounds() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (cursor_options_.forward) {
int compare = CompareIndexKeys(iterator_->Key(), cursor_options_.high_key);
if (cursor_options_.high_open) {
......@@ -2396,7 +2419,7 @@ bool IndexedDBBackingStore::Cursor::IsPastBounds() const {
}
const IndexedDBKey& IndexedDBBackingStore::Cursor::primary_key() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return *current_key_;
}
......@@ -2410,8 +2433,12 @@ class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
database_id,
cursor_options) {}
ObjectStoreKeyCursorImpl(const ObjectStoreKeyCursorImpl&) = delete;
ObjectStoreKeyCursorImpl& operator=(const ObjectStoreKeyCursorImpl&) = delete;
std::unique_ptr<Cursor> Clone() const override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto iter = CloneIterator(this);
if (!iter)
return nullptr;
......@@ -2428,7 +2455,7 @@ class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
protected:
std::string EncodeKey(const IndexedDBKey& key) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return ObjectStoreDataKey::Encode(cursor_options_.database_id,
cursor_options_.object_store_id, key);
}
......@@ -2443,22 +2470,24 @@ class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
const ObjectStoreKeyCursorImpl* other,
std::unique_ptr<TransactionalLevelDBIterator> iterator)
: IndexedDBBackingStore::Cursor(other, std::move(iterator)) {}
DISALLOW_COPY_AND_ASSIGN(ObjectStoreKeyCursorImpl);
};
IndexedDBBackingStore::Cursor::CursorOptions::CursorOptions() = default;
IndexedDBBackingStore::Cursor::CursorOptions::CursorOptions(
const CursorOptions& other) = default;
IndexedDBBackingStore::Cursor::CursorOptions::~CursorOptions() = default;
const IndexedDBBackingStore::RecordIdentifier&
IndexedDBBackingStore::Cursor::record_identifier() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return record_identifier_;
}
bool ObjectStoreKeyCursorImpl::LoadCurrentRow(Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
StringPiece slice(iterator_->Key());
ObjectStoreDataKey object_store_data_key;
if (!ObjectStoreDataKey::Decode(&slice, &object_store_data_key)) {
......@@ -2495,24 +2524,33 @@ class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
database_id,
cursor_options) {}
ObjectStoreCursorImpl(const ObjectStoreCursorImpl&) = delete;
ObjectStoreCursorImpl& operator=(const ObjectStoreCursorImpl&) = delete;
~ObjectStoreCursorImpl() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
// IndexedDBBackingStore::Cursor:
std::unique_ptr<Cursor> Clone() const override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto iter = CloneIterator(this);
if (!iter)
return nullptr;
return base::WrapUnique(new ObjectStoreCursorImpl(this, std::move(iter)));
}
// IndexedDBBackingStore::Cursor
IndexedDBValue* value() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return &current_value_;
}
bool LoadCurrentRow(Status* s) override;
protected:
std::string EncodeKey(const IndexedDBKey& key) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return ObjectStoreDataKey::Encode(cursor_options_.database_id,
cursor_options_.object_store_id, key);
}
......@@ -2528,14 +2566,13 @@ class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
std::unique_ptr<TransactionalLevelDBIterator> iterator)
: IndexedDBBackingStore::Cursor(other, std::move(iterator)) {}
IndexedDBValue current_value_;
DISALLOW_COPY_AND_ASSIGN(ObjectStoreCursorImpl);
IndexedDBValue current_value_ GUARDED_BY_CONTEXT(sequence_checker_);
};
bool ObjectStoreCursorImpl::LoadCurrentRow(Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(transaction_);
StringPiece key_slice(iterator_->Key());
ObjectStoreDataKey object_store_data_key;
if (!ObjectStoreDataKey::Decode(&key_slice, &object_store_data_key)) {
......@@ -2578,8 +2615,16 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
database_id,
cursor_options) {}
IndexKeyCursorImpl(const IndexKeyCursorImpl&) = delete;
IndexKeyCursorImpl& operator=(const IndexKeyCursorImpl&) = delete;
~IndexKeyCursorImpl() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
std::unique_ptr<Cursor> Clone() const override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto iter = CloneIterator(this);
if (!iter)
return nullptr;
......@@ -2592,7 +2637,7 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
return nullptr;
}
const IndexedDBKey& primary_key() const override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return *primary_key_;
}
const IndexedDBBackingStore::RecordIdentifier& record_identifier()
......@@ -2604,14 +2649,14 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
protected:
std::string EncodeKey(const IndexedDBKey& key) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return IndexDataKey::Encode(cursor_options_.database_id,
cursor_options_.object_store_id,
cursor_options_.index_id, key);
}
std::string EncodeKey(const IndexedDBKey& key,
const IndexedDBKey& primary_key) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return IndexDataKey::Encode(cursor_options_.database_id,
cursor_options_.object_store_id,
cursor_options_.index_id, key, primary_key);
......@@ -2624,14 +2669,14 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
: IndexedDBBackingStore::Cursor(other, std::move(iterator)),
primary_key_(std::make_unique<IndexedDBKey>(*other->primary_key_)) {}
std::unique_ptr<IndexedDBKey> primary_key_;
DISALLOW_COPY_AND_ASSIGN(IndexKeyCursorImpl);
std::unique_ptr<IndexedDBKey> primary_key_
GUARDED_BY_CONTEXT(sequence_checker_);
};
bool IndexKeyCursorImpl::LoadCurrentRow(Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(transaction_);
StringPiece slice(iterator_->Key());
IndexDataKey index_data_key;
if (!IndexDataKey::Decode(&slice, &index_data_key)) {
......@@ -2707,8 +2752,15 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
database_id,
cursor_options) {}
IndexCursorImpl(const IndexCursorImpl&) = delete;
IndexCursorImpl& operator=(const IndexCursorImpl&) = delete;
~IndexCursorImpl() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
}
std::unique_ptr<Cursor> Clone() const override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
auto iter = CloneIterator(this);
if (!iter)
return nullptr;
......@@ -2717,11 +2769,11 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
// IndexedDBBackingStore::Cursor
IndexedDBValue* value() override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return &current_value_;
}
const IndexedDBKey& primary_key() const override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return *primary_key_;
}
const IndexedDBBackingStore::RecordIdentifier& record_identifier()
......@@ -2733,14 +2785,14 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
protected:
std::string EncodeKey(const IndexedDBKey& key) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return IndexDataKey::Encode(cursor_options_.database_id,
cursor_options_.object_store_id,
cursor_options_.index_id, key);
}
std::string EncodeKey(const IndexedDBKey& key,
const IndexedDBKey& primary_key) override {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return IndexDataKey::Encode(cursor_options_.database_id,
cursor_options_.object_store_id,
cursor_options_.index_id, key, primary_key);
......@@ -2755,16 +2807,16 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
current_value_(other->current_value_),
primary_leveldb_key_(other->primary_leveldb_key_) {}
std::unique_ptr<IndexedDBKey> primary_key_;
IndexedDBValue current_value_;
std::string primary_leveldb_key_;
DISALLOW_COPY_AND_ASSIGN(IndexCursorImpl);
std::unique_ptr<IndexedDBKey> primary_key_
GUARDED_BY_CONTEXT(sequence_checker_);
IndexedDBValue current_value_ GUARDED_BY_CONTEXT(sequence_checker_);
std::string primary_leveldb_key_ GUARDED_BY_CONTEXT(sequence_checker_);
};
bool IndexCursorImpl::LoadCurrentRow(Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(transaction_);
StringPiece slice(iterator_->Key());
IndexDataKey index_data_key;
if (!IndexDataKey::Decode(&slice, &index_data_key)) {
......@@ -2845,8 +2897,9 @@ IndexedDBBackingStore::OpenObjectStoreCursor(
const IndexedDBKeyRange& range,
blink::mojom::IDBCursorDirection direction,
Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreCursor");
TransactionalLevelDBTransaction* leveldb_transaction =
transaction->transaction();
IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
......@@ -2874,8 +2927,9 @@ IndexedDBBackingStore::OpenObjectStoreKeyCursor(
const IndexedDBKeyRange& range,
blink::mojom::IDBCursorDirection direction,
Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::OpenObjectStoreKeyCursor");
TransactionalLevelDBTransaction* leveldb_transaction =
transaction->transaction();
IndexedDBBackingStore::Cursor::CursorOptions cursor_options;
......@@ -2904,7 +2958,7 @@ IndexedDBBackingStore::OpenIndexKeyCursor(
const IndexedDBKeyRange& range,
blink::mojom::IDBCursorDirection direction,
Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::OpenIndexKeyCursor");
*s = Status::OK();
TransactionalLevelDBTransaction* leveldb_transaction =
......@@ -2932,7 +2986,7 @@ IndexedDBBackingStore::OpenIndexCursor(
const IndexedDBKeyRange& range,
blink::mojom::IDBCursorDirection direction,
Status* s) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::OpenIndexCursor");
TransactionalLevelDBTransaction* leveldb_transaction =
transaction->transaction();
......@@ -2950,12 +3004,12 @@ IndexedDBBackingStore::OpenIndexCursor(
}
bool IndexedDBBackingStore::IsBlobCleanupPending() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return journal_cleaning_timer_.IsRunning();
}
void IndexedDBBackingStore::ForceRunBlobCleanup() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
journal_cleaning_timer_.FireNow();
}
......@@ -2977,8 +3031,6 @@ IndexedDBBackingStore::Transaction::Transaction(
transactional_leveldb_factory_(
backing_store_ ? backing_store_->transactional_leveldb_factory_
: nullptr),
database_id_(-1),
committing_(false),
durability_(durability),
mode_(mode) {
DCHECK(!backing_store_ ||
......@@ -2986,15 +3038,17 @@ IndexedDBBackingStore::Transaction::Transaction(
}
IndexedDBBackingStore::Transaction::~Transaction() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!committing_);
}
void IndexedDBBackingStore::Transaction::Begin(std::vector<ScopeLock> locks) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
IDB_TRACE("IndexedDBBackingStore::Transaction::Begin");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(backing_store_->sequence_checker_);
DCHECK(backing_store_);
DCHECK(!transaction_.get());
IDB_TRACE("IndexedDBBackingStore::Transaction::Begin");
transaction_ = transactional_leveldb_factory_->CreateLevelDBTransaction(
backing_store_->db_.get(),
backing_store_->db_->scopes()->CreateScope(
......@@ -3007,6 +3061,8 @@ void IndexedDBBackingStore::Transaction::Begin(std::vector<ScopeLock> locks) {
}
Status IndexedDBBackingStore::MigrateToV1(LevelDBWriteBatch* write_batch) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const int64_t db_schema_version = 1;
const std::string schema_version_key = SchemaVersionKey::Encode();
const std::string data_version_key = DataVersionKey::Encode();
......@@ -3043,6 +3099,8 @@ Status IndexedDBBackingStore::MigrateToV1(LevelDBWriteBatch* write_batch) {
}
Status IndexedDBBackingStore::MigrateToV2(LevelDBWriteBatch* write_batch) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const int64_t db_schema_version = 2;
const std::string schema_version_key = SchemaVersionKey::Encode();
const std::string data_version_key = DataVersionKey::Encode();
......@@ -3055,6 +3113,8 @@ Status IndexedDBBackingStore::MigrateToV2(LevelDBWriteBatch* write_batch) {
}
Status IndexedDBBackingStore::MigrateToV3(LevelDBWriteBatch* write_batch) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const int64_t db_schema_version = 3;
const std::string schema_version_key = SchemaVersionKey::Encode();
const std::string data_version_key = DataVersionKey::Encode();
......@@ -3090,6 +3150,8 @@ Status IndexedDBBackingStore::MigrateToV3(LevelDBWriteBatch* write_batch) {
}
Status IndexedDBBackingStore::MigrateToV4(LevelDBWriteBatch* write_batch) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
const int64_t db_schema_version = 4;
const std::string schema_version_key = SchemaVersionKey::Encode();
Status s;
......@@ -3114,6 +3176,8 @@ Status IndexedDBBackingStore::MigrateToV4(LevelDBWriteBatch* write_batch) {
}
Status IndexedDBBackingStore::MigrateToV5(LevelDBWriteBatch* write_batch) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// Some blob files were not written to disk due to a bug.
// Validate that all blob files in the db exist on disk,
// and return InternalInconsistencyStatus if any do not.
......@@ -3135,13 +3199,13 @@ Status IndexedDBBackingStore::MigrateToV5(LevelDBWriteBatch* write_batch) {
}
Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(backing_store_);
DCHECK(blobs_to_write_.empty());
if (backing_store_->is_incognito())
return Status::OK();
DCHECK(blobs_to_write_.empty());
if (external_object_change_map_.empty())
return Status::OK();
......@@ -3190,8 +3254,9 @@ Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction() {
}
bool IndexedDBBackingStore::Transaction::CollectBlobFilesToRemove() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(backing_store_);
if (backing_store_->is_incognito())
return true;
......@@ -3242,8 +3307,9 @@ bool IndexedDBBackingStore::Transaction::CollectBlobFilesToRemove() {
void IndexedDBBackingStore::Transaction::PartitionBlobsToRemove(
BlobJournalType* inactive_blobs,
BlobJournalType* active_blobs) const {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(backing_store_);
IndexedDBActiveBlobRegistry* registry =
backing_store_->active_blob_registry();
for (const auto& iter : blobs_to_remove_) {
......@@ -3258,10 +3324,11 @@ void IndexedDBBackingStore::Transaction::PartitionBlobsToRemove(
Status IndexedDBBackingStore::Transaction::CommitPhaseOne(
BlobWriteCallback callback) {
IDB_TRACE("IndexedDBBackingStore::Transaction::CommitPhaseOne");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(transaction_.get());
DCHECK(backing_store_);
DCHECK(backing_store_->idb_task_runner()->RunsTasksInCurrentSequence());
IDB_TRACE("IndexedDBBackingStore::Transaction::CommitPhaseOne");
Status s;
......@@ -3294,14 +3361,16 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseOne(
}
Status IndexedDBBackingStore::Transaction::CommitPhaseTwo() {
IDB_TRACE("IndexedDBBackingStore::Transaction::CommitPhaseTwo");
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(backing_store_->sequence_checker_);
DCHECK(backing_store_);
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
Status s;
IDB_TRACE("IndexedDBBackingStore::Transaction::CommitPhaseTwo");
DCHECK(committing_);
committing_ = false;
Status s;
// DidCommitTransaction must be called during CommitPhaseTwo,
// as it decrements the number of active transactions that were
// incremented from CommitPhaseOne. However, it also potentially cleans up
......@@ -3427,14 +3496,15 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseTwo() {
leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs(
BlobWriteCallback callback) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
IDB_ASYNC_TRACE_BEGIN("IndexedDBBackingStore::Transaction::WriteNewBlobs",
this);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(backing_store_);
DCHECK(!backing_store_->is_incognito());
DCHECK(!external_object_change_map_.empty());
DCHECK_GT(database_id_, 0);
IDB_ASYNC_TRACE_BEGIN("IndexedDBBackingStore::Transaction::WriteNewBlobs",
this);
// Count how many objects we need to write by excluding all empty files and
// blobs.
int num_objects_to_write = 0;
......@@ -3469,6 +3539,8 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs(
auto write_result_callback = base::BindRepeating(
[](base::WeakPtr<Transaction> transaction,
storage::mojom::WriteBlobToFileResult result) {
DCHECK_CALLED_ON_VALID_SEQUENCE(transaction->sequence_checker_);
if (!transaction)
return;
// This can be null if Rollback() is called.
......@@ -3496,7 +3568,7 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs(
.Run(BlobWriteResult::kRunPhaseTwoAsync, result);
}
},
ptr_factory_.GetWeakPtr());
weak_ptr_factory_.GetWeakPtr());
for (auto& iter : external_object_change_map_) {
for (auto& entry : iter.second->mutable_external_objects()) {
......@@ -3507,7 +3579,7 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs(
continue;
// If this directory creation fails then the WriteBlobToFile call
// will fail. So there is no need to special-case handle it here.
FilePath path = GetBlobDirectoryNameForKey(
base::FilePath path = GetBlobDirectoryNameForKey(
backing_store_->blob_path_, database_id_, entry.blob_number());
backing_store_->filesystem_proxy_->CreateDirectory(path);
// TODO(dmurph): Refactor IndexedDBExternalObject to not use a
......@@ -3565,7 +3637,8 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs(
std::move(callback).Run(
storage::mojom::WriteBlobToFileResult::kSuccess);
},
ptr_factory_.GetWeakPtr(), &entry, write_result_callback));
weak_ptr_factory_.GetWeakPtr(), &entry,
write_result_callback));
break;
}
}
......@@ -3575,15 +3648,16 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs(
}
void IndexedDBBackingStore::Transaction::Reset() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
backing_store_.reset();
transaction_ = nullptr;
}
leveldb::Status IndexedDBBackingStore::Transaction::Rollback() {
IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(backing_store_);
IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
if (committing_) {
committing_ = false;
......@@ -3602,7 +3676,7 @@ leveldb::Status IndexedDBBackingStore::Transaction::Rollback() {
}
uint64_t IndexedDBBackingStore::Transaction::GetTransactionSize() {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(transaction_);
return transaction_->GetTransactionSize();
}
......@@ -3611,7 +3685,8 @@ Status IndexedDBBackingStore::Transaction::PutExternalObjectsIfNeeded(
int64_t database_id,
const std::string& object_store_data_key,
std::vector<IndexedDBExternalObject>* external_objects) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
if (!external_objects || external_objects->empty()) {
external_object_change_map_.erase(object_store_data_key);
incognito_external_object_map_.erase(object_store_data_key);
......@@ -3643,7 +3718,7 @@ void IndexedDBBackingStore::Transaction::PutExternalObjects(
int64_t database_id,
const std::string& object_store_data_key,
std::vector<IndexedDBExternalObject>* external_objects) {
DCHECK_CALLED_ON_VALID_SEQUENCE(idb_sequence_checker_);
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(!object_store_data_key.empty());
if (database_id_ < 0)
database_id_ = database_id;
......
......@@ -15,12 +15,14 @@
#include <utility>
#include <vector>
#include "base/dcheck_is_on.h"
#include "base/files/file_path.h"
#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "base/strings/string_piece.h"
#include "base/thread_annotations.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
#include "components/services/storage/indexed_db/scopes/scope_lock.h"
......@@ -70,31 +72,46 @@ enum class V2SchemaCorruptionStatus {
kYes = 2,
};
// All interaction with this class should be done on the task runner given to
// Open.
// This class is not thread-safe.
// All accessses to one instance must occur on the same sequence. Currently,
// this must be the IndexedDB task runner's sequence.
class CONTENT_EXPORT IndexedDBBackingStore {
public:
// This class is not thread-safe.
// All accessses to one instance must occur on the same sequence.
class CONTENT_EXPORT RecordIdentifier {
public:
RecordIdentifier(const std::string& primary_key, int64_t version);
RecordIdentifier();
RecordIdentifier(std::string primary_key, int64_t version);
RecordIdentifier(const RecordIdentifier&) = delete;
RecordIdentifier& operator=(const RecordIdentifier&) = delete;
~RecordIdentifier();
const std::string& primary_key() const { return primary_key_; }
int64_t version() const { return version_; }
void Reset(const std::string& primary_key, int64_t version) {
primary_key_ = primary_key;
version_ = version;
const std::string& primary_key() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return primary_key_;
}
int64_t version() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return version_;
}
void Reset(std::string primary_key, int64_t version);
private:
// TODO(jsbell): Make it more clear that this is the *encoded* version of
// the key.
std::string primary_key_;
int64_t version_;
DISALLOW_COPY_AND_ASSIGN(RecordIdentifier);
std::string primary_key_ GUARDED_BY_CONTEXT(sequence_checker_);
int64_t version_ GUARDED_BY_CONTEXT(sequence_checker_) = -1;
// Data members must be immutable or GUARDED_BY_CONTEXT(sequence_checker_).
SEQUENCE_CHECKER(sequence_checker_);
};
// This class is not thread-safe.
// All accessses to one instance must occur on the same sequence.
class CONTENT_EXPORT Transaction {
public:
struct BlobWriteState {
......@@ -108,6 +125,10 @@ class CONTENT_EXPORT IndexedDBBackingStore {
Transaction(base::WeakPtr<IndexedDBBackingStore> backing_store,
blink::mojom::IDBTransactionDurability durability,
blink::mojom::IDBTransactionMode mode);
Transaction(const Transaction&) = delete;
Transaction& operator=(const Transaction&) = delete;
virtual ~Transaction();
virtual void Begin(std::vector<ScopeLock> locks);
......@@ -140,6 +161,7 @@ class CONTENT_EXPORT IndexedDBBackingStore {
std::vector<IndexedDBExternalObject>*);
TransactionalLevelDBTransaction* transaction() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return transaction_.get();
}
......@@ -154,7 +176,10 @@ class CONTENT_EXPORT IndexedDBBackingStore {
blink::mojom::IDBTransactionMode mode() const { return mode_; }
IndexedDBBackingStore* backing_store() { return backing_store_.get(); }
IndexedDBBackingStore* backing_store() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return backing_store_.get();
}
private:
// Called by CommitPhaseOne: Identifies the blob entries to write and adds
......@@ -178,62 +203,69 @@ class CONTENT_EXPORT IndexedDBBackingStore {
void PartitionBlobsToRemove(BlobJournalType* dead_blobs,
BlobJournalType* live_blobs) const;
SEQUENCE_CHECKER(idb_sequence_checker_);
// This does NOT mean that this class can outlive the IndexedDBBackingStore.
// This is only to protect against security issues before this class is
// refactored away and this isn't necessary.
// https://crbug.com/1012918
base::WeakPtr<IndexedDBBackingStore> backing_store_;
base::WeakPtr<IndexedDBBackingStore> backing_store_
GUARDED_BY_CONTEXT(sequence_checker_);
TransactionalLevelDBFactory* const transactional_leveldb_factory_;
scoped_refptr<TransactionalLevelDBTransaction> transaction_;
scoped_refptr<TransactionalLevelDBTransaction> transaction_
GUARDED_BY_CONTEXT(sequence_checker_);
std::map<std::string, std::unique_ptr<IndexedDBExternalObjectChangeRecord>>
external_object_change_map_;
external_object_change_map_ GUARDED_BY_CONTEXT(sequence_checker_);
std::map<std::string, std::unique_ptr<IndexedDBExternalObjectChangeRecord>>
incognito_external_object_map_;
int64_t database_id_;
incognito_external_object_map_ GUARDED_BY_CONTEXT(sequence_checker_);
int64_t database_id_ GUARDED_BY_CONTEXT(sequence_checker_) = -1;
// List of blob files being newly written as part of this transaction.
// These will be added to the recovery blob journal prior to commit, then
// removed after a successful commit.
BlobJournalType blobs_to_write_;
BlobJournalType blobs_to_write_ GUARDED_BY_CONTEXT(sequence_checker_);
// List of blob files being deleted as part of this transaction. These will
// be added to either the recovery or live blob journal as appropriate
// following a successful commit.
BlobJournalType blobs_to_remove_;
BlobJournalType blobs_to_remove_ GUARDED_BY_CONTEXT(sequence_checker_);
// Populated when blobs are being written to disk. This is saved here (as
// opposed to being ephemeral and owned by the WriteBlobToFile callbacks)
// because the transaction needs to be able to cancel this operation in
// Rollback().
base::Optional<BlobWriteState> write_state_;
base::Optional<BlobWriteState> write_state_
GUARDED_BY_CONTEXT(sequence_checker_);
// Set to true between CommitPhaseOne and CommitPhaseTwo/Rollback, to
// indicate that the committing_transaction_count_ on the backing store
// has been bumped, and journal cleaning should be deferred.
bool committing_;
bool committing_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
// This flag is passed to LevelDBScopes as |sync_on_commit|, converted
// via ShouldSyncOnCommit.
blink::mojom::IDBTransactionDurability durability_;
const blink::mojom::IDBTransactionDurability durability_;
const blink::mojom::IDBTransactionMode mode_;
base::WeakPtrFactory<Transaction> ptr_factory_{this};
// Data members must be immutable or GUARDED_BY_CONTEXT(sequence_checker_).
SEQUENCE_CHECKER(sequence_checker_);
DISALLOW_COPY_AND_ASSIGN(Transaction);
base::WeakPtrFactory<Transaction> weak_ptr_factory_
GUARDED_BY_CONTEXT(sequence_checker_){this};
};
// This class is not thread-safe.
// All accessses to one instance must occur on the same sequence.
class Cursor {
public:
enum IteratorState { READY = 0, SEEK };
virtual ~Cursor();
struct CursorOptions {
CursorOptions();
CursorOptions(const CursorOptions& other);
~CursorOptions();
int64_t database_id;
int64_t object_store_id;
int64_t index_id;
......@@ -247,7 +279,16 @@ class CONTENT_EXPORT IndexedDBBackingStore {
blink::mojom::IDBTransactionMode::ReadWrite;
};
const blink::IndexedDBKey& key() const { return *current_key_; }
Cursor(const Cursor&) = delete;
Cursor& operator=(const Cursor&) = delete;
virtual ~Cursor();
const blink::IndexedDBKey& key() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return *current_key_;
}
bool Continue(leveldb::Status* s) {
return Continue(nullptr, nullptr, SEEK, s);
}
......@@ -288,18 +329,22 @@ class CONTENT_EXPORT IndexedDBBackingStore {
bool IsPastBounds() const;
bool HaveEnteredRange() const;
SEQUENCE_CHECKER(idb_sequence_checker_);
// This does NOT mean that this class can outlive the Transaction.
// This is only to protect against security issues before this class is
// refactored away and this isn't necessary.
// https://crbug.com/1012918
base::WeakPtr<Transaction> transaction_;
int64_t database_id_;
const base::WeakPtr<Transaction> transaction_;
const int64_t database_id_;
const CursorOptions cursor_options_;
std::unique_ptr<TransactionalLevelDBIterator> iterator_;
std::unique_ptr<blink::IndexedDBKey> current_key_;
IndexedDBBackingStore::RecordIdentifier record_identifier_;
std::unique_ptr<TransactionalLevelDBIterator> iterator_
GUARDED_BY_CONTEXT(sequence_checker_);
std::unique_ptr<blink::IndexedDBKey> current_key_
GUARDED_BY_CONTEXT(sequence_checker_);
IndexedDBBackingStore::RecordIdentifier record_identifier_
GUARDED_BY_CONTEXT(sequence_checker_);
// Data members must be immutable or GUARDED_BY_CONTEXT(sequence_checker_).
SEQUENCE_CHECKER(sequence_checker_);
private:
enum class ContinueResult { LEVELDB_ERROR, DONE, OUT_OF_BOUNDS };
......@@ -317,9 +362,8 @@ class CONTENT_EXPORT IndexedDBBackingStore {
IteratorState state,
leveldb::Status*);
base::WeakPtrFactory<Cursor> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(Cursor);
base::WeakPtrFactory<Cursor> weak_factory_
GUARDED_BY_CONTEXT(sequence_checker_){this};
};
using BlobFilesCleanedCallback = base::RepeatingClosure;
......@@ -366,6 +410,7 @@ class CONTENT_EXPORT IndexedDBBackingStore {
return idb_task_runner_.get();
}
IndexedDBActiveBlobRegistry* active_blob_registry() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return active_blob_registry_.get();
}
......@@ -499,12 +544,17 @@ class CONTENT_EXPORT IndexedDBBackingStore {
int64_t GetInMemoryBlobSize() const;
#if DCHECK_IS_ON()
int NumBlobFilesDeletedForTesting() { return num_blob_files_deleted_; }
int NumBlobFilesDeletedForTesting() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return num_blob_files_deleted_;
}
int NumAggregatedJournalCleaningRequestsForTesting() const {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return num_aggregated_journal_cleaning_requests_;
}
#endif
void SetExecuteJournalCleaningOnNoTransactionsForTesting() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
execute_journal_cleaning_on_no_txns_ = true;
}
......@@ -527,6 +577,7 @@ class CONTENT_EXPORT IndexedDBBackingStore {
blink::mojom::IDBTransactionMode mode);
base::WeakPtr<IndexedDBBackingStore> AsWeakPtr() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return weak_factory_.GetWeakPtr();
}
......@@ -608,23 +659,21 @@ class CONTENT_EXPORT IndexedDBBackingStore {
// Can run a journal cleaning job if one is pending.
void DidCommitTransaction();
SEQUENCE_CHECKER(idb_sequence_checker_);
Mode backing_store_mode_;
const Mode backing_store_mode_;
TransactionalLevelDBFactory* const transactional_leveldb_factory_;
const url::Origin origin_;
base::FilePath blob_path_;
const base::FilePath blob_path_;
// IndexedDB can store blobs and native file system handles. These mojo
// interfaces are used to make this possible by communicating with the
// relevant subsystems.
// Raw pointers are safe because the bindings are owned by
// IndexedDBContextImpl.
storage::mojom::BlobStorageContext* blob_storage_context_;
storage::mojom::NativeFileSystemContext* native_file_system_context_;
storage::mojom::BlobStorageContext* const blob_storage_context_;
storage::mojom::NativeFileSystemContext* const native_file_system_context_;
// Filesystem proxy to use for file operations. nullptr if in memory.
std::unique_ptr<storage::FilesystemProxy> filesystem_proxy_;
const std::unique_ptr<storage::FilesystemProxy> filesystem_proxy_;
// The origin identifier is a key prefix unique to the origin used in the
// leveldb backing store to partition data by origin. It is a normalized
......@@ -634,37 +683,47 @@ class CONTENT_EXPORT IndexedDBBackingStore {
// provides for future flexibility.
const std::string origin_identifier_;
scoped_refptr<base::SequencedTaskRunner> idb_task_runner_;
std::set<int> child_process_ids_granted_;
const scoped_refptr<base::SequencedTaskRunner> idb_task_runner_;
std::map<std::string, std::unique_ptr<IndexedDBExternalObjectChangeRecord>>
incognito_external_object_map_;
incognito_external_object_map_ GUARDED_BY_CONTEXT(sequence_checker_);
bool execute_journal_cleaning_on_no_txns_ = false;
int num_aggregated_journal_cleaning_requests_ = 0;
base::OneShotTimer journal_cleaning_timer_;
base::TimeTicks journal_cleaning_timer_window_start_;
bool execute_journal_cleaning_on_no_txns_
GUARDED_BY_CONTEXT(sequence_checker_) = false;
int num_aggregated_journal_cleaning_requests_
GUARDED_BY_CONTEXT(sequence_checker_) = 0;
base::OneShotTimer journal_cleaning_timer_
GUARDED_BY_CONTEXT(sequence_checker_);
base::TimeTicks journal_cleaning_timer_window_start_
GUARDED_BY_CONTEXT(sequence_checker_);
#if DCHECK_IS_ON()
mutable int num_blob_files_deleted_ = 0;
mutable int num_blob_files_deleted_ GUARDED_BY_CONTEXT(sequence_checker_) = 0;
#endif
std::unique_ptr<TransactionalLevelDBDatabase> db_;
const std::unique_ptr<TransactionalLevelDBDatabase> db_;
BlobFilesCleanedCallback blob_files_cleaned_;
const BlobFilesCleanedCallback blob_files_cleaned_;
// Whenever blobs are registered in active_blob_registry_,
// indexed_db_factory_ will hold a reference to this backing store.
std::unique_ptr<IndexedDBActiveBlobRegistry> active_blob_registry_;
std::unique_ptr<IndexedDBActiveBlobRegistry> active_blob_registry_
GUARDED_BY_CONTEXT(sequence_checker_);
// Incremented whenever a transaction starts committing, decremented when
// complete. While > 0, temporary journal entries may exist so out-of-band
// journal cleaning must be deferred.
size_t committing_transaction_count_ = 0;
size_t committing_transaction_count_ GUARDED_BY_CONTEXT(sequence_checker_) =
0;
#if DCHECK_IS_ON()
bool initialized_ = false;
bool initialized_ GUARDED_BY_CONTEXT(sequence_checker_) = false;
#endif
base::WeakPtrFactory<IndexedDBBackingStore> weak_factory_{this};
// Data members must be immutable or GUARDED_BY_CONTEXT(sequence_checker_).
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<IndexedDBBackingStore> weak_factory_
GUARDED_BY_CONTEXT(sequence_checker_){this};
};
} // namespace content
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment