Commit a7dfd014 authored by Daniel Murphy's avatar Daniel Murphy Committed by Commit Bot

[IndexedDB] Removing all raw pointers and IndexedDBFactory dependencies

This patch:
* Changes most raw pointers to base::WeakPtr
* Removes the IndexedDBFactory raw pointer in IndexedDBDatabase and
  instead uses callbacks to report:
  1. If blobs are in use for a given origin, and
  2. If the blob journal has been cleaned.
* Changes the IndexedDBActiveBlobRegistry to use callbacks instead of
  the IndexedDBFactory as well, and also use callbacks for calling
  ReportUnusedBlob in IndexedDBOriginFactory. This simplifies the
  testing of that class.

There are no functional changes in this patch, and while all of those
raw pointers should be safe based on the architecture of the code, it
is much safer to store them appropriately now that we have our fancy
new pointer types.

Finally, this patch also does some naming changing in
IndexedDBActiveBlobRegistry to make that class easier to understand.

Bug: 1018741,960992
Change-Id: I6fd402c68d13870f347fe934b85e6281c396901d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1885094
Commit-Queue: Daniel Murphy <dmurph@chromium.org>
Reviewed-by: default avatarKen Rockot <rockot@google.com>
Cr-Commit-Position: refs/heads/master@{#711452}
parent c6c4ec37
...@@ -120,7 +120,7 @@ void DatabaseImpl::CreateTransaction( ...@@ -120,7 +120,7 @@ void DatabaseImpl::CreateTransaction(
transaction_id, transaction_id,
std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode, std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode,
new IndexedDBBackingStore::Transaction( new IndexedDBBackingStore::Transaction(
connection_->database()->backing_store(), durability)); connection_->database()->backing_store()->AsWeakPtr(), durability));
connection_->database()->RegisterAndScheduleTransaction(transaction); connection_->database()->RegisterAndScheduleTransaction(transaction);
dispatcher_host_->CreateAndBindTransactionImpl( dispatcher_host_->CreateAndBindTransactionImpl(
......
...@@ -2,11 +2,13 @@ ...@@ -2,11 +2,13 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/location.h" #include "base/location.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "base/task_runner.h" #include "base/task_runner.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h" #include "base/threading/sequenced_task_runner_handle.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_factory.h" #include "content/browser/indexed_db/indexed_db_factory.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h" #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
...@@ -14,38 +16,42 @@ ...@@ -14,38 +16,42 @@
namespace content { namespace content {
IndexedDBActiveBlobRegistry::IndexedDBActiveBlobRegistry( IndexedDBActiveBlobRegistry::IndexedDBActiveBlobRegistry(
IndexedDBBackingStore* backing_store) ReportOutstandingBlobsCallback report_outstanding_blobs,
: backing_store_(backing_store) {} ReportUnusedBlobCallback report_unused_blob)
: report_outstanding_blobs_(std::move(report_outstanding_blobs)),
report_unused_blob_(std::move(report_unused_blob)) {}
IndexedDBActiveBlobRegistry::~IndexedDBActiveBlobRegistry() { IndexedDBActiveBlobRegistry::~IndexedDBActiveBlobRegistry() {}
}
void IndexedDBActiveBlobRegistry::AddBlobRef(int64_t database_id, void IndexedDBActiveBlobRegistry::AddBlobRef(int64_t database_id,
int64_t blob_key) { int64_t blob_key) {
DCHECK(backing_store_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(backing_store_->task_runner()->RunsTasksInCurrentSequence()); DCHECK(report_outstanding_blobs_);
DCHECK(report_unused_blob_);
DCHECK(KeyPrefix::IsValidDatabaseId(database_id)); DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key)); DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
DCHECK(!base::Contains(deleted_dbs_, database_id)); DCHECK(!base::Contains(deleted_dbs_, database_id));
bool need_ref = use_tracker_.empty(); bool outstanding_blobs_in_backing_store = !use_tracker_.empty();
SingleDBMap& single_db_map = use_tracker_[database_id]; SingleDBMap& blobs_in_db = use_tracker_[database_id];
auto iter = single_db_map.find(blob_key); auto iter = blobs_in_db.find(blob_key);
if (iter == single_db_map.end()) { if (iter == blobs_in_db.end()) {
single_db_map[blob_key] = false; blobs_in_db[blob_key] = BlobState::kAlive;
if (need_ref) { if (!outstanding_blobs_in_backing_store)
backing_store_->factory()->ReportOutstandingBlobs( report_outstanding_blobs_.Run(true);
backing_store_->origin(), true);
}
} else { } else {
DCHECK(!need_ref); DCHECK(outstanding_blobs_in_backing_store);
DCHECK(!iter->second); // You can't add a reference once it's been deleted. // You can't add a reference once it's been deleted.
DCHECK(iter->second == BlobState::kAlive);
} }
} }
void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64_t database_id, void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64_t database_id,
int64_t blob_key) { int64_t blob_key) {
DCHECK(backing_store_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(backing_store_->task_runner()->RunsTasksInCurrentSequence()); DCHECK(report_outstanding_blobs_);
DCHECK(report_unused_blob_);
DCHECK(KeyPrefix::IsValidDatabaseId(database_id)); DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key)); DCHECK(DatabaseMetaDataKey::IsValidBlobKey(blob_key));
const auto& db_pair = use_tracker_.find(database_id); const auto& db_pair = use_tracker_.find(database_id);
...@@ -53,39 +59,37 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64_t database_id, ...@@ -53,39 +59,37 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRef(int64_t database_id,
NOTREACHED(); NOTREACHED();
return; return;
} }
SingleDBMap& single_db = db_pair->second; SingleDBMap& blobs_in_db = db_pair->second;
auto blob_pair = single_db.find(blob_key); auto blob_in_db_it = blobs_in_db.find(blob_key);
if (blob_pair == single_db.end()) { if (blob_in_db_it == blobs_in_db.end()) {
NOTREACHED(); NOTREACHED();
return; return;
} }
bool delete_in_backend = false; bool delete_blob_in_backend = false;
const auto& db_to_delete = deleted_dbs_.find(database_id); const auto& deleted_database_it = deleted_dbs_.find(database_id);
bool db_marked_for_deletion = db_to_delete != deleted_dbs_.end(); bool db_marked_for_deletion = deleted_database_it != deleted_dbs_.end();
// Don't bother deleting the file if we're going to delete its whole // Don't bother deleting the file if we're going to delete its whole
// database directory soon. // database directory soon.
delete_in_backend = blob_pair->second && !db_marked_for_deletion; delete_blob_in_backend =
single_db.erase(blob_pair); blob_in_db_it->second == BlobState::kDeleted && !db_marked_for_deletion;
if (single_db.empty()) { blobs_in_db.erase(blob_in_db_it);
if (blobs_in_db.empty()) {
use_tracker_.erase(db_pair); use_tracker_.erase(db_pair);
if (db_marked_for_deletion) { if (db_marked_for_deletion) {
delete_in_backend = true; delete_blob_in_backend = true;
blob_key = DatabaseMetaDataKey::kAllBlobsKey; blob_key = DatabaseMetaDataKey::kAllBlobsKey;
deleted_dbs_.erase(db_to_delete); deleted_dbs_.erase(deleted_database_it);
} }
} }
if (delete_in_backend) if (delete_blob_in_backend)
backing_store_->ReportBlobUnused(database_id, blob_key); report_unused_blob_.Run(database_id, blob_key);
if (use_tracker_.empty()) { if (use_tracker_.empty())
backing_store_->factory()->ReportOutstandingBlobs(backing_store_->origin(), report_outstanding_blobs_.Run(false);
false);
}
} }
bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64_t database_id, bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64_t database_id,
int64_t blob_key) { int64_t blob_key) {
DCHECK(backing_store_); DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
DCHECK(backing_store_->task_runner()->RunsTasksInCurrentSequence());
DCHECK(KeyPrefix::IsValidDatabaseId(database_id)); DCHECK(KeyPrefix::IsValidDatabaseId(database_id));
const auto& db_pair = use_tracker_.find(database_id); const auto& db_pair = use_tracker_.find(database_id);
if (db_pair == use_tracker_.end()) if (db_pair == use_tracker_.end())
...@@ -101,7 +105,7 @@ bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64_t database_id, ...@@ -101,7 +105,7 @@ bool IndexedDBActiveBlobRegistry::MarkDeletedCheckIfUsed(int64_t database_id,
if (iter == single_db.end()) if (iter == single_db.end())
return false; return false;
iter->second = true; iter->second = BlobState::kDeleted;
return true; return true;
} }
...@@ -113,29 +117,33 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe( ...@@ -113,29 +117,33 @@ void IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe(
const base::FilePath& unused) { const base::FilePath& unused) {
task_runner->PostTask( task_runner->PostTask(
FROM_HERE, base::BindOnce(&IndexedDBActiveBlobRegistry::ReleaseBlobRef, FROM_HERE, base::BindOnce(&IndexedDBActiveBlobRegistry::ReleaseBlobRef,
weak_ptr, database_id, blob_key)); std::move(weak_ptr), database_id, blob_key));
} }
IndexedDBBlobInfo::ReleaseCallback IndexedDBBlobInfo::ReleaseCallback
IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(int64_t database_id, IndexedDBActiveBlobRegistry::GetFinalReleaseCallback(int64_t database_id,
int64_t blob_key) { int64_t blob_key) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return base::BindRepeating( return base::BindRepeating(
&IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe, &IndexedDBActiveBlobRegistry::ReleaseBlobRefThreadSafe,
scoped_refptr<base::TaskRunner>(backing_store_->task_runner()), base::SequencedTaskRunnerHandle::Get(), weak_factory_.GetWeakPtr(),
weak_factory_.GetWeakPtr(), database_id, blob_key); database_id, blob_key);
} }
base::RepeatingClosure IndexedDBActiveBlobRegistry::GetAddBlobRefCallback( base::RepeatingClosure IndexedDBActiveBlobRegistry::GetAddBlobRefCallback(
int64_t database_id, int64_t database_id,
int64_t blob_key) { int64_t blob_key) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
return base::BindRepeating(&IndexedDBActiveBlobRegistry::AddBlobRef, return base::BindRepeating(&IndexedDBActiveBlobRegistry::AddBlobRef,
weak_factory_.GetWeakPtr(), database_id, blob_key); weak_factory_.GetWeakPtr(), database_id, blob_key);
} }
void IndexedDBActiveBlobRegistry::ForceShutdown() { void IndexedDBActiveBlobRegistry::ForceShutdown() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
weak_factory_.InvalidateWeakPtrs(); weak_factory_.InvalidateWeakPtrs();
use_tracker_.clear(); use_tracker_.clear();
backing_store_ = nullptr; report_outstanding_blobs_.Reset();
report_unused_blob_.Reset();
} }
} // namespace content } // namespace content
...@@ -11,19 +11,32 @@ ...@@ -11,19 +11,32 @@
#include <set> #include <set>
#include <utility> #include <utility>
#include "base/callback.h"
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/sequence_checker.h"
#include "content/browser/indexed_db/indexed_db_blob_info.h" #include "content/browser/indexed_db/indexed_db_blob_info.h"
#include "content/common/content_export.h" #include "content/common/content_export.h"
namespace content { namespace content {
class IndexedDBBackingStore; // Keeps track of blobs that have been sent to the renderer as database
// responses, and determines when the file should be deleted. The database entry
// that the blob files live in could be deleted in the database, but the file
// would need to stay alive while it is still used in the renderer.
// This class must be used on a single sequence, and will call the given
// callbacks back on the same sequence it is constructed on.
class CONTENT_EXPORT IndexedDBActiveBlobRegistry { class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
public: public:
explicit IndexedDBActiveBlobRegistry(IndexedDBBackingStore* backing_store); using ReportOutstandingBlobsCallback = base::RepeatingCallback<void(bool)>;
using ReportUnusedBlobCallback =
base::RepeatingCallback<void(int64_t /*database_id*/,
int64_t /*blob_key*/)>;
explicit IndexedDBActiveBlobRegistry(
ReportOutstandingBlobsCallback report_outstanding_blobs,
ReportUnusedBlobCallback report_unused_blob);
~IndexedDBActiveBlobRegistry(); ~IndexedDBActiveBlobRegistry();
// Most methods of this class, and the closure returned by // Most methods of this class, and the closure returned by
...@@ -31,6 +44,8 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry { ...@@ -31,6 +44,8 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
// runner. The exception is the closure returned by GetFinalReleaseCallback, // runner. The exception is the closure returned by GetFinalReleaseCallback,
// which just calls ReleaseBlobRefThreadSafe. // which just calls ReleaseBlobRefThreadSafe.
// Marks a given blob or a while database as deleted by a transaction, and
// returns if the given blob key (or database) was previously used.
// Use DatabaseMetaDataKey::AllBlobsKey for "the whole database". // Use DatabaseMetaDataKey::AllBlobsKey for "the whole database".
bool MarkDeletedCheckIfUsed(int64_t database_id, int64_t blob_key); bool MarkDeletedCheckIfUsed(int64_t database_id, int64_t blob_key);
...@@ -47,11 +62,14 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry { ...@@ -47,11 +62,14 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
void ForceShutdown(); void ForceShutdown();
private: private:
// Maps blob_key -> IsDeleted; if the record's absent, it's not in active use enum class BlobState { kAlive, kDeleted };
// Maps blob_key -> BlobState; if the record's absent, it's not in active use
// and we don't care if it's deleted. // and we don't care if it's deleted.
typedef std::map<int64_t, bool> SingleDBMap; typedef std::map<int64_t, BlobState> SingleDBMap;
void AddBlobRef(int64_t database_id, int64_t blob_key); void AddBlobRef(int64_t database_id, int64_t blob_key);
// Removes a reference to the given blob.
void ReleaseBlobRef(int64_t database_id, int64_t blob_key); void ReleaseBlobRef(int64_t database_id, int64_t blob_key);
static void ReleaseBlobRefThreadSafe( static void ReleaseBlobRefThreadSafe(
scoped_refptr<base::TaskRunner> task_runner, scoped_refptr<base::TaskRunner> task_runner,
...@@ -60,12 +78,13 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry { ...@@ -60,12 +78,13 @@ class CONTENT_EXPORT IndexedDBActiveBlobRegistry {
int64_t blob_key, int64_t blob_key,
const base::FilePath& unused); const base::FilePath& unused);
SEQUENCE_CHECKER(sequence_checker_);
std::map<int64_t, SingleDBMap> use_tracker_; std::map<int64_t, SingleDBMap> use_tracker_;
// Databases that have been marked as deleted by MarkDeletedCheckIfUsed.
std::set<int64_t> deleted_dbs_; std::set<int64_t> deleted_dbs_;
// As long as we've got blobs registered in use_tracker_, ReportOutstandingBlobsCallback report_outstanding_blobs_;
// backing_store_->factory() will keep backing_store_ alive for us. And ReportUnusedBlobCallback report_unused_blob_;
// backing_store_ owns us, so we'll stay alive as long as we're needed.
IndexedDBBackingStore* backing_store_;
base::WeakPtrFactory<IndexedDBActiveBlobRegistry> weak_factory_{this}; base::WeakPtrFactory<IndexedDBActiveBlobRegistry> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(IndexedDBActiveBlobRegistry); DISALLOW_COPY_AND_ASSIGN(IndexedDBActiveBlobRegistry);
......
...@@ -7,13 +7,11 @@ ...@@ -7,13 +7,11 @@
#include <memory> #include <memory>
#include <set> #include <set>
#include "base/bind.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/stl_util.h"
#include "base/test/task_environment.h" #include "base/test/task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h" #include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_fake_backing_store.h"
#include "content/browser/indexed_db/mock_indexed_db_factory.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
#include "url/origin.h" #include "url/origin.h"
...@@ -21,74 +19,38 @@ namespace content { ...@@ -21,74 +19,38 @@ namespace content {
namespace { namespace {
class RegistryTestMockFactory : public MockIndexedDBFactory { struct ReportOutstandingState {
public: int true_calls = 0;
RegistryTestMockFactory() : duplicate_calls_(false) {} int false_calls = 0;
~RegistryTestMockFactory() override = default;
bool no_calls() { return true_calls == 0 && false_calls == 0; }
};
void ReportOutstandingBlobs(const url::Origin& origin, void ReportOutstandingBlobs(ReportOutstandingState* state,
bool blobs_outstanding) override { bool blobs_outstanding) {
if (blobs_outstanding) { if (blobs_outstanding) {
if (origins_.count(origin)) { ++state->true_calls;
duplicate_calls_ = true;
} else {
origins_.insert(origin);
}
} else {
if (!origins_.count(origin)) {
duplicate_calls_ = true;
} else { } else {
origins_.erase(origin); ++state->false_calls;
}
}
} }
}
bool CheckNoOriginsInUse() const { struct UnusedBlob {
return !duplicate_calls_ && origins_.empty(); int64_t database_id;
} int64_t blob_key;
bool CheckSingleOriginInUse(const url::Origin& origin) const { bool operator<(const UnusedBlob& other) const {
return !duplicate_calls_ && origins_.size() == 1 && origins_.count(origin); if (database_id == other.database_id)
return blob_key < other.blob_key;
return database_id < other.database_id;
} }
private:
std::set<url::Origin> origins_;
bool duplicate_calls_;
DISALLOW_COPY_AND_ASSIGN(RegistryTestMockFactory);
}; };
class MockIDBBackingStore : public IndexedDBFakeBackingStore { void ReportUnusedBlob(std::set<UnusedBlob>* unused_blob_records,
public: int64_t database_id,
typedef std::pair<int64_t, int64_t> KeyPair; int64_t blob_key) {
typedef std::set<KeyPair> KeyPairSet; unused_blob_records->insert({database_id, blob_key});
}
MockIDBBackingStore(IndexedDBFactory* factory,
base::SequencedTaskRunner* task_runner)
: IndexedDBFakeBackingStore(factory, task_runner),
duplicate_calls_(false) {}
~MockIDBBackingStore() override = default;
void ReportBlobUnused(int64_t database_id, int64_t blob_key) override {
unused_blobs_.insert({database_id, blob_key});
}
bool CheckUnusedBlobsEmpty() const {
return !duplicate_calls_ && !unused_blobs_.size();
}
bool CheckSingleUnusedBlob(int64_t database_id, int64_t blob_key) const {
return !duplicate_calls_ && unused_blobs_.size() == 1 &&
unused_blobs_.count({database_id, blob_key});
}
const KeyPairSet& unused_blobs() const { return unused_blobs_; }
private:
KeyPairSet unused_blobs_;
bool duplicate_calls_;
DISALLOW_COPY_AND_ASSIGN(MockIDBBackingStore);
};
// Base class for our test fixtures. // Base class for our test fixtures.
class IndexedDBActiveBlobRegistryTest : public testing::Test { class IndexedDBActiveBlobRegistryTest : public testing::Test {
...@@ -101,42 +63,40 @@ class IndexedDBActiveBlobRegistryTest : public testing::Test { ...@@ -101,42 +63,40 @@ class IndexedDBActiveBlobRegistryTest : public testing::Test {
static const int64_t kBlobKey1 = 14; static const int64_t kBlobKey1 = 14;
IndexedDBActiveBlobRegistryTest() IndexedDBActiveBlobRegistryTest()
: task_runner_(new base::TestSimpleTaskRunner), : registry_(std::make_unique<IndexedDBActiveBlobRegistry>(
factory_(new RegistryTestMockFactory), base::BindRepeating(ReportOutstandingBlobs,
backing_store_( &report_outstanding_state_),
new MockIDBBackingStore(factory_.get(), task_runner_.get())), base::BindRepeating(&ReportUnusedBlob, &unused_blobs_))) {}
registry_(std::make_unique<IndexedDBActiveBlobRegistry>(
backing_store_.get())) {} void RunUntilIdle() { task_environment_.RunUntilIdle(); }
void RunUntilIdle() { task_runner_->RunUntilIdle(); }
RegistryTestMockFactory* factory() const { return factory_.get(); }
MockIDBBackingStore* backing_store() const { return backing_store_.get(); }
IndexedDBActiveBlobRegistry* registry() const { return registry_.get(); } IndexedDBActiveBlobRegistry* registry() const { return registry_.get(); }
protected:
ReportOutstandingState report_outstanding_state_;
std::set<UnusedBlob> unused_blobs_;
private: private:
base::test::TaskEnvironment task_environment_; base::test::TaskEnvironment task_environment_;
scoped_refptr<base::TestSimpleTaskRunner> task_runner_;
std::unique_ptr<RegistryTestMockFactory> factory_;
std::unique_ptr<MockIDBBackingStore> backing_store_;
std::unique_ptr<IndexedDBActiveBlobRegistry> registry_; std::unique_ptr<IndexedDBActiveBlobRegistry> registry_;
DISALLOW_COPY_AND_ASSIGN(IndexedDBActiveBlobRegistryTest); DISALLOW_COPY_AND_ASSIGN(IndexedDBActiveBlobRegistryTest);
}; };
TEST_F(IndexedDBActiveBlobRegistryTest, DeleteUnused) { TEST_F(IndexedDBActiveBlobRegistryTest, DeleteUnused) {
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_TRUE(report_outstanding_state_.no_calls());
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_TRUE(unused_blobs_.empty());
EXPECT_FALSE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey0)); EXPECT_FALSE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey0));
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_TRUE(report_outstanding_state_.no_calls());
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_TRUE(unused_blobs_.empty());
} }
TEST_F(IndexedDBActiveBlobRegistryTest, SimpleUse) { TEST_F(IndexedDBActiveBlobRegistryTest, SimpleUse) {
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_TRUE(report_outstanding_state_.no_calls());
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_TRUE(unused_blobs_.empty());
base::Closure add_ref = base::Closure add_ref =
registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0); registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0);
...@@ -145,19 +105,21 @@ TEST_F(IndexedDBActiveBlobRegistryTest, SimpleUse) { ...@@ -145,19 +105,21 @@ TEST_F(IndexedDBActiveBlobRegistryTest, SimpleUse) {
std::move(add_ref).Run(); std::move(add_ref).Run();
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
std::move(release).Run(base::FilePath()); std::move(release).Run(base::FilePath());
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(1, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
} }
TEST_F(IndexedDBActiveBlobRegistryTest, DeleteWhileInUse) { TEST_F(IndexedDBActiveBlobRegistryTest, DeleteWhileInUse) {
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_TRUE(report_outstanding_state_.no_calls());
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_TRUE(unused_blobs_.empty());
base::Closure add_ref = base::Closure add_ref =
registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0); registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0);
...@@ -167,25 +129,30 @@ TEST_F(IndexedDBActiveBlobRegistryTest, DeleteWhileInUse) { ...@@ -167,25 +129,30 @@ TEST_F(IndexedDBActiveBlobRegistryTest, DeleteWhileInUse) {
std::move(add_ref).Run(); std::move(add_ref).Run();
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
EXPECT_TRUE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey0)); EXPECT_TRUE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey0));
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
std::move(release).Run(base::FilePath()); std::move(release).Run(base::FilePath());
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0, kBlobKey0)); EXPECT_EQ(1, report_outstanding_state_.false_calls);
UnusedBlob unused_blob = {kDatabaseId0, kBlobKey0};
EXPECT_EQ(1u, unused_blobs_.size());
EXPECT_TRUE(base::Contains(unused_blobs_, unused_blob));
} }
TEST_F(IndexedDBActiveBlobRegistryTest, MultipleBlobs) { TEST_F(IndexedDBActiveBlobRegistryTest, MultipleBlobs) {
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_TRUE(report_outstanding_state_.no_calls());
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_TRUE(unused_blobs_.empty());
base::Closure add_ref_00 = base::Closure add_ref_00 =
registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0); registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0);
...@@ -208,40 +175,49 @@ TEST_F(IndexedDBActiveBlobRegistryTest, MultipleBlobs) { ...@@ -208,40 +175,49 @@ TEST_F(IndexedDBActiveBlobRegistryTest, MultipleBlobs) {
std::move(add_ref_01).Run(); std::move(add_ref_01).Run();
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
std::move(release_00).Run(base::FilePath()); std::move(release_00).Run(base::FilePath());
std::move(add_ref_10).Run(); std::move(add_ref_10).Run();
std::move(add_ref_11).Run(); std::move(add_ref_11).Run();
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
EXPECT_TRUE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey1)); EXPECT_TRUE(registry()->MarkDeletedCheckIfUsed(kDatabaseId0, kBlobKey1));
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
std::move(release_01).Run(base::FilePath()); std::move(release_01).Run(base::FilePath());
std::move(release_11).Run(base::FilePath()); std::move(release_11).Run(base::FilePath());
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0, kBlobKey1)); EXPECT_EQ(0, report_outstanding_state_.false_calls);
UnusedBlob unused_blob = {kDatabaseId0, kBlobKey1};
EXPECT_TRUE(base::Contains(unused_blobs_, unused_blob));
EXPECT_EQ(1u, unused_blobs_.size());
std::move(release_10).Run(base::FilePath()); std::move(release_10).Run(base::FilePath());
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckSingleUnusedBlob(kDatabaseId0, kBlobKey1)); EXPECT_EQ(1, report_outstanding_state_.false_calls);
unused_blob = {kDatabaseId0, kBlobKey1};
EXPECT_TRUE(base::Contains(unused_blobs_, unused_blob));
EXPECT_EQ(1u, unused_blobs_.size());
} }
TEST_F(IndexedDBActiveBlobRegistryTest, ForceShutdown) { TEST_F(IndexedDBActiveBlobRegistryTest, ForceShutdown) {
EXPECT_TRUE(factory()->CheckNoOriginsInUse()); EXPECT_TRUE(report_outstanding_state_.no_calls());
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_TRUE(unused_blobs_.empty());
base::Closure add_ref_0 = base::Closure add_ref_0 =
registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0); registry()->GetAddBlobRefCallback(kDatabaseId0, kBlobKey0);
...@@ -255,8 +231,9 @@ TEST_F(IndexedDBActiveBlobRegistryTest, ForceShutdown) { ...@@ -255,8 +231,9 @@ TEST_F(IndexedDBActiveBlobRegistryTest, ForceShutdown) {
std::move(add_ref_0).Run(); std::move(add_ref_0).Run();
RunUntilIdle(); RunUntilIdle();
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
registry()->ForceShutdown(); registry()->ForceShutdown();
...@@ -264,16 +241,18 @@ TEST_F(IndexedDBActiveBlobRegistryTest, ForceShutdown) { ...@@ -264,16 +241,18 @@ TEST_F(IndexedDBActiveBlobRegistryTest, ForceShutdown) {
RunUntilIdle(); RunUntilIdle();
// Nothing changes. // Nothing changes.
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
std::move(release_0).Run(base::FilePath()); std::move(release_0).Run(base::FilePath());
std::move(release_1).Run(base::FilePath()); std::move(release_1).Run(base::FilePath());
RunUntilIdle(); RunUntilIdle();
// Nothing changes. // Nothing changes.
EXPECT_TRUE(factory()->CheckSingleOriginInUse(backing_store()->origin())); EXPECT_EQ(1, report_outstanding_state_.true_calls);
EXPECT_TRUE(backing_store()->CheckUnusedBlobsEmpty()); EXPECT_EQ(0, report_outstanding_state_.false_calls);
EXPECT_TRUE(unused_blobs_.empty());
} }
} // namespace } // namespace
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/memory_dump_manager.h"
#include "build/build_config.h" #include "build/build_config.h"
#include "content/browser/child_process_security_policy_impl.h" #include "content/browser/child_process_security_policy_impl.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "content/browser/indexed_db/indexed_db_blob_info.h" #include "content/browser/indexed_db/indexed_db_blob_info.h"
#include "content/browser/indexed_db/indexed_db_context_impl.h" #include "content/browser/indexed_db/indexed_db_context_impl.h"
#include "content/browser/indexed_db/indexed_db_data_format_version.h" #include "content/browser/indexed_db/indexed_db_data_format_version.h"
...@@ -517,26 +518,28 @@ bool IndexCursorOptions( ...@@ -517,26 +518,28 @@ bool IndexCursorOptions(
IndexedDBBackingStore::IndexedDBBackingStore( IndexedDBBackingStore::IndexedDBBackingStore(
Mode backing_store_mode, Mode backing_store_mode,
IndexedDBFactory* indexed_db_factory,
TransactionalLevelDBFactory* transactional_leveldb_factory, TransactionalLevelDBFactory* transactional_leveldb_factory,
const Origin& origin, const Origin& origin,
const FilePath& blob_path, const FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db, std::unique_ptr<TransactionalLevelDBDatabase> db,
BlobFilesCleanedCallback blob_files_cleaned,
ReportOutstandingBlobsCallback report_outstanding_blobs,
base::SequencedTaskRunner* task_runner) base::SequencedTaskRunner* task_runner)
: backing_store_mode_(backing_store_mode), : backing_store_mode_(backing_store_mode),
indexed_db_factory_(indexed_db_factory),
transactional_leveldb_factory_(transactional_leveldb_factory), transactional_leveldb_factory_(transactional_leveldb_factory),
origin_(origin), origin_(origin),
blob_path_(blob_path), blob_path_(blob_path),
origin_identifier_(ComputeOriginIdentifier(origin)), origin_identifier_(ComputeOriginIdentifier(origin)),
task_runner_(task_runner), task_runner_(task_runner),
db_(std::move(db)), db_(std::move(db)),
active_blob_registry_(this) { blob_files_cleaned_(std::move(blob_files_cleaned)) {
if (backing_store_mode == Mode::kInMemory) {
indexed_db_factory_ = nullptr;
blob_path_ = FilePath();
}
DCHECK(task_runner_->RunsTasksInCurrentSequence()); DCHECK(task_runner_->RunsTasksInCurrentSequence());
if (backing_store_mode == Mode::kInMemory)
blob_path_ = FilePath();
active_blob_registry_ = std::make_unique<IndexedDBActiveBlobRegistry>(
std::move(report_outstanding_blobs),
base::BindRepeating(&IndexedDBBackingStore::ReportBlobUnused,
weak_factory_.GetWeakPtr()));
} }
IndexedDBBackingStore::~IndexedDBBackingStore() { IndexedDBBackingStore::~IndexedDBBackingStore() {
...@@ -834,7 +837,8 @@ V2SchemaCorruptionStatus IndexedDBBackingStore::HasV2SchemaCorruption() { ...@@ -834,7 +837,8 @@ V2SchemaCorruptionStatus IndexedDBBackingStore::HasV2SchemaCorruption() {
std::unique_ptr<IndexedDBBackingStore::Transaction> std::unique_ptr<IndexedDBBackingStore::Transaction>
IndexedDBBackingStore::CreateTransaction( IndexedDBBackingStore::CreateTransaction(
blink::mojom::IDBTransactionDurability durability) { blink::mojom::IDBTransactionDurability durability) {
return std::make_unique<IndexedDBBackingStore::Transaction>(this, durability); return std::make_unique<IndexedDBBackingStore::Transaction>(
weak_factory_.GetWeakPtr(), durability);
} }
// static // static
...@@ -1780,9 +1784,9 @@ Status IndexedDBBackingStore::CleanUpBlobJournal( ...@@ -1780,9 +1784,9 @@ Status IndexedDBBackingStore::CleanUpBlobJournal(
ClearBlobJournal(journal_transaction.get(), level_db_key); ClearBlobJournal(journal_transaction.get(), level_db_key);
s = journal_transaction->Commit(); s = journal_transaction->Commit();
// Notify blob files cleaned even if commit fails, as files could still be // Notify blob files cleaned even if commit fails, as files could still be
// deleted. |indexed_db_factory_| is null for in-memory backing stores. // deleted.
if (!is_incognito()) if (!is_incognito())
indexed_db_factory_->BlobFilesCleaned(origin_); blob_files_cleaned_.Run();
return s; return s;
} }
...@@ -1883,6 +1887,11 @@ Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord( ...@@ -1883,6 +1887,11 @@ Status IndexedDBBackingStore::Transaction::GetBlobInfoForRecord(
return Status::OK(); return Status::OK();
} }
base::WeakPtr<IndexedDBBackingStore::Transaction>
IndexedDBBackingStore::Transaction::AsWeakPtr() {
return ptr_factory_.GetWeakPtr();
}
void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() { void IndexedDBBackingStore::CleanPrimaryJournalIgnoreReturn() {
// While a transaction is busy it is not safe to clean the journal. // While a transaction is busy it is not safe to clean the journal.
if (committing_transaction_count_ > 0) { if (committing_transaction_count_ > 0) {
...@@ -2088,11 +2097,11 @@ Status IndexedDBBackingStore::KeyExistsInIndex( ...@@ -2088,11 +2097,11 @@ Status IndexedDBBackingStore::KeyExistsInIndex(
IndexedDBBackingStore::Cursor::Cursor( IndexedDBBackingStore::Cursor::Cursor(
const IndexedDBBackingStore::Cursor* other) const IndexedDBBackingStore::Cursor* other)
: backing_store_(other->backing_store_), : transaction_(other->transaction_),
transaction_(other->transaction_),
database_id_(other->database_id_), database_id_(other->database_id_),
cursor_options_(other->cursor_options_), cursor_options_(other->cursor_options_),
current_key_(std::make_unique<IndexedDBKey>(*other->current_key_)) { current_key_(std::make_unique<IndexedDBKey>(*other->current_key_)) {
DCHECK(transaction_);
if (other->iterator_) { if (other->iterator_) {
iterator_ = transaction_->transaction()->CreateIterator(); iterator_ = transaction_->transaction()->CreateIterator();
...@@ -2104,18 +2113,18 @@ IndexedDBBackingStore::Cursor::Cursor( ...@@ -2104,18 +2113,18 @@ IndexedDBBackingStore::Cursor::Cursor(
} }
} }
IndexedDBBackingStore::Cursor::Cursor( IndexedDBBackingStore::Cursor::Cursor(base::WeakPtr<Transaction> transaction,
IndexedDBBackingStore* backing_store,
IndexedDBBackingStore::Transaction* transaction,
int64_t database_id, int64_t database_id,
const CursorOptions& cursor_options) const CursorOptions& cursor_options)
: backing_store_(backing_store), : transaction_(std::move(transaction)),
transaction_(transaction),
database_id_(database_id), database_id_(database_id),
cursor_options_(cursor_options) {} cursor_options_(cursor_options) {
DCHECK(transaction_);
}
IndexedDBBackingStore::Cursor::~Cursor() {} IndexedDBBackingStore::Cursor::~Cursor() {}
bool IndexedDBBackingStore::Cursor::FirstSeek(Status* s) { bool IndexedDBBackingStore::Cursor::FirstSeek(Status* s) {
DCHECK(transaction_);
iterator_ = transaction_->transaction()->CreateIterator(); iterator_ = transaction_->transaction()->CreateIterator();
{ {
IDB_TRACE("IndexedDBBackingStore::Cursor::FirstSeek::Seek"); IDB_TRACE("IndexedDBBackingStore::Cursor::FirstSeek::Seek");
...@@ -2366,12 +2375,10 @@ const IndexedDBKey& IndexedDBBackingStore::Cursor::primary_key() const { ...@@ -2366,12 +2375,10 @@ const IndexedDBKey& IndexedDBBackingStore::Cursor::primary_key() const {
class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor { class ObjectStoreKeyCursorImpl : public IndexedDBBackingStore::Cursor {
public: public:
ObjectStoreKeyCursorImpl( ObjectStoreKeyCursorImpl(
IndexedDBBackingStore* backing_store, base::WeakPtr<IndexedDBBackingStore::Transaction> transaction,
IndexedDBBackingStore::Transaction* transaction,
int64_t database_id, int64_t database_id,
const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
: IndexedDBBackingStore::Cursor(backing_store, : IndexedDBBackingStore::Cursor(std::move(transaction),
transaction,
database_id, database_id,
cursor_options) {} cursor_options) {}
...@@ -2443,12 +2450,10 @@ bool ObjectStoreKeyCursorImpl::LoadCurrentRow(Status* s) { ...@@ -2443,12 +2450,10 @@ bool ObjectStoreKeyCursorImpl::LoadCurrentRow(Status* s) {
class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
public: public:
ObjectStoreCursorImpl( ObjectStoreCursorImpl(
IndexedDBBackingStore* backing_store, base::WeakPtr<IndexedDBBackingStore::Transaction> transaction,
IndexedDBBackingStore::Transaction* transaction,
int64_t database_id, int64_t database_id,
const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
: IndexedDBBackingStore::Cursor(backing_store, : IndexedDBBackingStore::Cursor(std::move(transaction),
transaction,
database_id, database_id,
cursor_options) {} cursor_options) {}
...@@ -2482,6 +2487,7 @@ class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor { ...@@ -2482,6 +2487,7 @@ class ObjectStoreCursorImpl : public IndexedDBBackingStore::Cursor {
}; };
bool ObjectStoreCursorImpl::LoadCurrentRow(Status* s) { bool ObjectStoreCursorImpl::LoadCurrentRow(Status* s) {
DCHECK(transaction_);
StringPiece key_slice(iterator_->Key()); StringPiece key_slice(iterator_->Key());
ObjectStoreDataKey object_store_data_key; ObjectStoreDataKey object_store_data_key;
if (!ObjectStoreDataKey::Decode(&key_slice, &object_store_data_key)) { if (!ObjectStoreDataKey::Decode(&key_slice, &object_store_data_key)) {
...@@ -2517,12 +2523,10 @@ bool ObjectStoreCursorImpl::LoadCurrentRow(Status* s) { ...@@ -2517,12 +2523,10 @@ bool ObjectStoreCursorImpl::LoadCurrentRow(Status* s) {
class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
public: public:
IndexKeyCursorImpl( IndexKeyCursorImpl(
IndexedDBBackingStore* backing_store, base::WeakPtr<IndexedDBBackingStore::Transaction> transaction,
IndexedDBBackingStore::Transaction* transaction,
int64_t database_id, int64_t database_id,
const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
: IndexedDBBackingStore::Cursor(backing_store, : IndexedDBBackingStore::Cursor(std::move(transaction),
transaction,
database_id, database_id,
cursor_options) {} cursor_options) {}
...@@ -2567,6 +2571,7 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor { ...@@ -2567,6 +2571,7 @@ class IndexKeyCursorImpl : public IndexedDBBackingStore::Cursor {
}; };
bool IndexKeyCursorImpl::LoadCurrentRow(Status* s) { bool IndexKeyCursorImpl::LoadCurrentRow(Status* s) {
DCHECK(transaction_);
StringPiece slice(iterator_->Key()); StringPiece slice(iterator_->Key());
IndexDataKey index_data_key; IndexDataKey index_data_key;
if (!IndexDataKey::Decode(&slice, &index_data_key)) { if (!IndexDataKey::Decode(&slice, &index_data_key)) {
...@@ -2631,12 +2636,10 @@ bool IndexKeyCursorImpl::LoadCurrentRow(Status* s) { ...@@ -2631,12 +2636,10 @@ bool IndexKeyCursorImpl::LoadCurrentRow(Status* s) {
class IndexCursorImpl : public IndexedDBBackingStore::Cursor { class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
public: public:
IndexCursorImpl( IndexCursorImpl(
IndexedDBBackingStore* backing_store, base::WeakPtr<IndexedDBBackingStore::Transaction> transaction,
IndexedDBBackingStore::Transaction* transaction,
int64_t database_id, int64_t database_id,
const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options) const IndexedDBBackingStore::Cursor::CursorOptions& cursor_options)
: IndexedDBBackingStore::Cursor(backing_store, : IndexedDBBackingStore::Cursor(std::move(transaction),
transaction,
database_id, database_id,
cursor_options) {} cursor_options) {}
...@@ -2682,6 +2685,7 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor { ...@@ -2682,6 +2685,7 @@ class IndexCursorImpl : public IndexedDBBackingStore::Cursor {
}; };
bool IndexCursorImpl::LoadCurrentRow(Status* s) { bool IndexCursorImpl::LoadCurrentRow(Status* s) {
DCHECK(transaction_);
StringPiece slice(iterator_->Key()); StringPiece slice(iterator_->Key());
IndexDataKey index_data_key; IndexDataKey index_data_key;
if (!IndexDataKey::Decode(&slice, &index_data_key)) { if (!IndexDataKey::Decode(&slice, &index_data_key)) {
...@@ -2765,8 +2769,8 @@ IndexedDBBackingStore::OpenObjectStoreCursor( ...@@ -2765,8 +2769,8 @@ IndexedDBBackingStore::OpenObjectStoreCursor(
return std::unique_ptr<IndexedDBBackingStore::Cursor>(); return std::unique_ptr<IndexedDBBackingStore::Cursor>();
} }
std::unique_ptr<ObjectStoreCursorImpl> cursor( std::unique_ptr<ObjectStoreCursorImpl> cursor(
std::make_unique<ObjectStoreCursorImpl>(this, transaction, database_id, std::make_unique<ObjectStoreCursorImpl>(transaction->AsWeakPtr(),
cursor_options)); database_id, cursor_options));
if (!cursor->FirstSeek(s)) if (!cursor->FirstSeek(s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>(); return std::unique_ptr<IndexedDBBackingStore::Cursor>();
...@@ -2792,8 +2796,8 @@ IndexedDBBackingStore::OpenObjectStoreKeyCursor( ...@@ -2792,8 +2796,8 @@ IndexedDBBackingStore::OpenObjectStoreKeyCursor(
return std::unique_ptr<IndexedDBBackingStore::Cursor>(); return std::unique_ptr<IndexedDBBackingStore::Cursor>();
} }
std::unique_ptr<ObjectStoreKeyCursorImpl> cursor( std::unique_ptr<ObjectStoreKeyCursorImpl> cursor(
std::make_unique<ObjectStoreKeyCursorImpl>(this, transaction, database_id, std::make_unique<ObjectStoreKeyCursorImpl>(transaction->AsWeakPtr(),
cursor_options)); database_id, cursor_options));
if (!cursor->FirstSeek(s)) if (!cursor->FirstSeek(s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>(); return std::unique_ptr<IndexedDBBackingStore::Cursor>();
...@@ -2818,8 +2822,8 @@ IndexedDBBackingStore::OpenIndexKeyCursor( ...@@ -2818,8 +2822,8 @@ IndexedDBBackingStore::OpenIndexKeyCursor(
index_id, range, direction, &cursor_options, s)) index_id, range, direction, &cursor_options, s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>(); return std::unique_ptr<IndexedDBBackingStore::Cursor>();
std::unique_ptr<IndexKeyCursorImpl> cursor( std::unique_ptr<IndexKeyCursorImpl> cursor(
std::make_unique<IndexKeyCursorImpl>(this, transaction, database_id, std::make_unique<IndexKeyCursorImpl>(transaction->AsWeakPtr(),
cursor_options)); database_id, cursor_options));
if (!cursor->FirstSeek(s)) if (!cursor->FirstSeek(s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>(); return std::unique_ptr<IndexedDBBackingStore::Cursor>();
...@@ -2842,8 +2846,8 @@ IndexedDBBackingStore::OpenIndexCursor( ...@@ -2842,8 +2846,8 @@ IndexedDBBackingStore::OpenIndexCursor(
if (!IndexCursorOptions(leveldb_transaction, database_id, object_store_id, if (!IndexCursorOptions(leveldb_transaction, database_id, object_store_id,
index_id, range, direction, &cursor_options, s)) index_id, range, direction, &cursor_options, s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>(); return std::unique_ptr<IndexedDBBackingStore::Cursor>();
std::unique_ptr<IndexCursorImpl> cursor( std::unique_ptr<IndexCursorImpl> cursor(new IndexCursorImpl(
new IndexCursorImpl(this, transaction, database_id, cursor_options)); transaction->AsWeakPtr(), database_id, cursor_options));
if (!cursor->FirstSeek(s)) if (!cursor->FirstSeek(s))
return std::unique_ptr<IndexedDBBackingStore::Cursor>(); return std::unique_ptr<IndexedDBBackingStore::Cursor>();
...@@ -2860,11 +2864,11 @@ void IndexedDBBackingStore::ForceRunBlobCleanup() { ...@@ -2860,11 +2864,11 @@ void IndexedDBBackingStore::ForceRunBlobCleanup() {
// |backing_store| can be null in unittests (see FakeTransaction). // |backing_store| can be null in unittests (see FakeTransaction).
IndexedDBBackingStore::Transaction::Transaction( IndexedDBBackingStore::Transaction::Transaction(
IndexedDBBackingStore* backing_store, base::WeakPtr<IndexedDBBackingStore> backing_store,
blink::mojom::IDBTransactionDurability durability) blink::mojom::IDBTransactionDurability durability)
: backing_store_(backing_store), : backing_store_(std::move(backing_store)),
transactional_leveldb_factory_( transactional_leveldb_factory_(
backing_store ? backing_store->transactional_leveldb_factory_ backing_store_ ? backing_store_->transactional_leveldb_factory_
: nullptr), : nullptr),
database_id_(-1), database_id_(-1),
committing_(false), committing_(false),
...@@ -2876,6 +2880,7 @@ IndexedDBBackingStore::Transaction::~Transaction() { ...@@ -2876,6 +2880,7 @@ IndexedDBBackingStore::Transaction::~Transaction() {
void IndexedDBBackingStore::Transaction::Begin(std::vector<ScopeLock> locks) { void IndexedDBBackingStore::Transaction::Begin(std::vector<ScopeLock> locks) {
IDB_TRACE("IndexedDBBackingStore::Transaction::Begin"); IDB_TRACE("IndexedDBBackingStore::Transaction::Begin");
DCHECK(backing_store_);
DCHECK(!transaction_.get()); DCHECK(!transaction_.get());
transaction_ = transactional_leveldb_factory_->CreateLevelDBTransaction( transaction_ = transactional_leveldb_factory_->CreateLevelDBTransaction(
backing_store_->db_.get(), backing_store_->db_.get(),
...@@ -2891,6 +2896,7 @@ void IndexedDBBackingStore::Transaction::Begin(std::vector<ScopeLock> locks) { ...@@ -2891,6 +2896,7 @@ void IndexedDBBackingStore::Transaction::Begin(std::vector<ScopeLock> locks) {
Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction( Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction(
BlobEntryKeyValuePairVec* new_blob_entries, BlobEntryKeyValuePairVec* new_blob_entries,
WriteDescriptorVec* new_files_to_write) { WriteDescriptorVec* new_files_to_write) {
DCHECK(backing_store_);
if (backing_store_->is_incognito()) if (backing_store_->is_incognito())
return Status::OK(); return Status::OK();
...@@ -2942,6 +2948,7 @@ Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction( ...@@ -2942,6 +2948,7 @@ Status IndexedDBBackingStore::Transaction::HandleBlobPreTransaction(
} }
bool IndexedDBBackingStore::Transaction::CollectBlobFilesToRemove() { bool IndexedDBBackingStore::Transaction::CollectBlobFilesToRemove() {
DCHECK(backing_store_);
if (backing_store_->is_incognito()) if (backing_store_->is_incognito())
return true; return true;
...@@ -2988,6 +2995,7 @@ bool IndexedDBBackingStore::Transaction::CollectBlobFilesToRemove() { ...@@ -2988,6 +2995,7 @@ bool IndexedDBBackingStore::Transaction::CollectBlobFilesToRemove() {
void IndexedDBBackingStore::Transaction::PartitionBlobsToRemove( void IndexedDBBackingStore::Transaction::PartitionBlobsToRemove(
BlobJournalType* dead_blobs, BlobJournalType* dead_blobs,
BlobJournalType* live_blobs) const { BlobJournalType* live_blobs) const {
DCHECK(backing_store_);
IndexedDBActiveBlobRegistry* registry = IndexedDBActiveBlobRegistry* registry =
backing_store_->active_blob_registry(); backing_store_->active_blob_registry();
for (const auto& iter : blobs_to_remove_) { for (const auto& iter : blobs_to_remove_) {
...@@ -3002,6 +3010,7 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseOne( ...@@ -3002,6 +3010,7 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseOne(
BlobWriteCallback callback) { BlobWriteCallback callback) {
IDB_TRACE("IndexedDBBackingStore::Transaction::CommitPhaseOne"); IDB_TRACE("IndexedDBBackingStore::Transaction::CommitPhaseOne");
DCHECK(transaction_.get()); DCHECK(transaction_.get());
DCHECK(backing_store_);
DCHECK(backing_store_->task_runner()->RunsTasksInCurrentSequence()); DCHECK(backing_store_->task_runner()->RunsTasksInCurrentSequence());
Status s; Status s;
...@@ -3039,6 +3048,7 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseOne( ...@@ -3039,6 +3048,7 @@ Status IndexedDBBackingStore::Transaction::CommitPhaseOne(
Status IndexedDBBackingStore::Transaction::CommitPhaseTwo() { Status IndexedDBBackingStore::Transaction::CommitPhaseTwo() {
IDB_TRACE("IndexedDBBackingStore::Transaction::CommitPhaseTwo"); IDB_TRACE("IndexedDBBackingStore::Transaction::CommitPhaseTwo");
DCHECK(backing_store_);
Status s; Status s;
DCHECK(committing_); DCHECK(committing_);
...@@ -3143,6 +3153,7 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs( ...@@ -3143,6 +3153,7 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs(
BlobWriteCallback callback) { BlobWriteCallback callback) {
IDB_ASYNC_TRACE_BEGIN("IndexedDBBackingStore::Transaction::WriteNewBlobs", IDB_ASYNC_TRACE_BEGIN("IndexedDBBackingStore::Transaction::WriteNewBlobs",
this); this);
DCHECK(backing_store_);
DCHECK(!new_files_to_write->empty()); DCHECK(!new_files_to_write->empty());
DCHECK_GT(database_id_, 0); DCHECK_GT(database_id_, 0);
leveldb::Status s; leveldb::Status s;
...@@ -3188,12 +3199,14 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs( ...@@ -3188,12 +3199,14 @@ leveldb::Status IndexedDBBackingStore::Transaction::WriteNewBlobs(
} }
void IndexedDBBackingStore::Transaction::Reset() { void IndexedDBBackingStore::Transaction::Reset() {
backing_store_ = nullptr; backing_store_.reset();
transaction_ = nullptr; transaction_ = nullptr;
} }
leveldb::Status IndexedDBBackingStore::Transaction::Rollback() { leveldb::Status IndexedDBBackingStore::Transaction::Rollback() {
IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback"); IDB_TRACE("IndexedDBBackingStore::Transaction::Rollback");
DCHECK(backing_store_);
if (committing_) { if (committing_) {
committing_ = false; committing_ = false;
backing_store_->DidCommitTransaction(); backing_store_->DidCommitTransaction();
......
...@@ -24,7 +24,6 @@ ...@@ -24,7 +24,6 @@
#include "base/time/time.h" #include "base/time/time.h"
#include "base/timer/timer.h" #include "base/timer/timer.h"
#include "content/browser/indexed_db/indexed_db.h" #include "content/browser/indexed_db/indexed_db.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "content/browser/indexed_db/indexed_db_blob_info.h" #include "content/browser/indexed_db/indexed_db_blob_info.h"
#include "content/browser/indexed_db/indexed_db_leveldb_coding.h" #include "content/browser/indexed_db/indexed_db_leveldb_coding.h"
#include "content/browser/indexed_db/scopes/scope_lock.h" #include "content/browser/indexed_db/scopes/scope_lock.h"
...@@ -51,12 +50,12 @@ class FileWriterDelegate; ...@@ -51,12 +50,12 @@ class FileWriterDelegate;
} }
namespace content { namespace content {
class IndexedDBFactory; class IndexedDBActiveBlobRegistry;
struct IndexedDBValue;
class TransactionalLevelDBDatabase; class TransactionalLevelDBDatabase;
class TransactionalLevelDBFactory; class TransactionalLevelDBFactory;
class TransactionalLevelDBIterator; class TransactionalLevelDBIterator;
class TransactionalLevelDBTransaction; class TransactionalLevelDBTransaction;
struct IndexedDBValue;
namespace indexed_db_backing_store_unittest { namespace indexed_db_backing_store_unittest {
class IndexedDBBackingStoreTest; class IndexedDBBackingStoreTest;
...@@ -133,7 +132,7 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -133,7 +132,7 @@ class CONTENT_EXPORT IndexedDBBackingStore {
class CONTENT_EXPORT Transaction { class CONTENT_EXPORT Transaction {
public: public:
explicit Transaction(IndexedDBBackingStore* backing_store, explicit Transaction(base::WeakPtr<IndexedDBBackingStore> backing_store,
blink::mojom::IDBTransactionDurability durability); blink::mojom::IDBTransactionDurability durability);
virtual ~Transaction(); virtual ~Transaction();
...@@ -179,6 +178,8 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -179,6 +178,8 @@ class CONTENT_EXPORT IndexedDBBackingStore {
const std::string& object_store_data_key, const std::string& object_store_data_key,
IndexedDBValue* value); IndexedDBValue* value);
base::WeakPtr<Transaction> AsWeakPtr();
// This holds a BlobEntryKey and the encoded IndexedDBBlobInfo vector stored // This holds a BlobEntryKey and the encoded IndexedDBBlobInfo vector stored
// under that key. // under that key.
typedef std::vector<std::pair<BlobEntryKey, std::string> > typedef std::vector<std::pair<BlobEntryKey, std::string> >
...@@ -270,10 +271,11 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -270,10 +271,11 @@ class CONTENT_EXPORT IndexedDBBackingStore {
void PartitionBlobsToRemove(BlobJournalType* dead_blobs, void PartitionBlobsToRemove(BlobJournalType* dead_blobs,
BlobJournalType* live_blobs) const; BlobJournalType* live_blobs) const;
// The raw pointer is not inherently safe, but IndexedDB destroys // This does NOT mean that this class can outlive the IndexedDBBackingStore.
// transactions & connections before destroying the backing store. // This is only to protect against security issues before this class is
// TODO(dmurph): Convert to WeakPtr. https://crbug.com/960992 // refactored away and this isn't necessary.
IndexedDBBackingStore* backing_store_; // https://crbug.com/1012918
base::WeakPtr<IndexedDBBackingStore> backing_store_;
TransactionalLevelDBFactory* const transactional_leveldb_factory_; TransactionalLevelDBFactory* const transactional_leveldb_factory_;
scoped_refptr<TransactionalLevelDBTransaction> transaction_; scoped_refptr<TransactionalLevelDBTransaction> transaction_;
std::map<std::string, std::unique_ptr<BlobChangeRecord>> blob_change_map_; std::map<std::string, std::unique_ptr<BlobChangeRecord>> blob_change_map_;
...@@ -348,8 +350,7 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -348,8 +350,7 @@ class CONTENT_EXPORT IndexedDBBackingStore {
virtual bool LoadCurrentRow(leveldb::Status* s) = 0; virtual bool LoadCurrentRow(leveldb::Status* s) = 0;
protected: protected:
Cursor(IndexedDBBackingStore* backing_store, Cursor(base::WeakPtr<Transaction> transaction,
Transaction* transaction,
int64_t database_id, int64_t database_id,
const CursorOptions& cursor_options); const CursorOptions& cursor_options);
explicit Cursor(const IndexedDBBackingStore::Cursor* other); explicit Cursor(const IndexedDBBackingStore::Cursor* other);
...@@ -361,14 +362,11 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -361,14 +362,11 @@ class CONTENT_EXPORT IndexedDBBackingStore {
bool IsPastBounds() const; bool IsPastBounds() const;
bool HaveEnteredRange() const; bool HaveEnteredRange() const;
// The raw pointer is not inherently safe, but IndexedDB destroys // This does NOT mean that this class can outlive the Transaction.
// transactions & connections before destroying the backing store. // This is only to protect against security issues before this class is
// TODO(dmurph): Convert to WeakPtr. https://crbug.com/960992 // refactored away and this isn't necessary.
IndexedDBBackingStore* backing_store_; // https://crbug.com/1012918
// The raw pointer is not inherently safe, but IndexedDB destroys base::WeakPtr<Transaction> transaction_;
// transactions before cursors.
// TODO(dmurph): Convert to WeakPtr. https://crbug.com/960992
Transaction* transaction_;
int64_t database_id_; int64_t database_id_;
const CursorOptions cursor_options_; const CursorOptions cursor_options_;
std::unique_ptr<TransactionalLevelDBIterator> iterator_; std::unique_ptr<TransactionalLevelDBIterator> iterator_;
...@@ -391,9 +389,15 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -391,9 +389,15 @@ class CONTENT_EXPORT IndexedDBBackingStore {
IteratorState state, IteratorState state,
leveldb::Status*); leveldb::Status*);
base::WeakPtrFactory<Cursor> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(Cursor); DISALLOW_COPY_AND_ASSIGN(Cursor);
}; };
using BlobFilesCleanedCallback = base::RepeatingClosure;
using ReportOutstandingBlobsCallback =
base::RepeatingCallback<void(/*outstanding_blobs=*/bool)>;
enum class Mode { kInMemory, kOnDisk }; enum class Mode { kInMemory, kOnDisk };
// Schedule an immediate blob journal cleanup if we reach this number of // Schedule an immediate blob journal cleanup if we reach this number of
...@@ -409,11 +413,12 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -409,11 +413,12 @@ class CONTENT_EXPORT IndexedDBBackingStore {
IndexedDBBackingStore( IndexedDBBackingStore(
Mode backing_store_mode, Mode backing_store_mode,
IndexedDBFactory* indexed_db_factory,
TransactionalLevelDBFactory* transactional_leveldb_factory, TransactionalLevelDBFactory* transactional_leveldb_factory,
const url::Origin& origin, const url::Origin& origin,
const base::FilePath& blob_path, const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db, std::unique_ptr<TransactionalLevelDBDatabase> db,
BlobFilesCleanedCallback blob_files_cleaned,
ReportOutstandingBlobsCallback report_outstanding_blobs,
base::SequencedTaskRunner* task_runner); base::SequencedTaskRunner* task_runner);
virtual ~IndexedDBBackingStore(); virtual ~IndexedDBBackingStore();
...@@ -422,10 +427,9 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -422,10 +427,9 @@ class CONTENT_EXPORT IndexedDBBackingStore {
leveldb::Status Initialize(bool clean_live_blob_journal); leveldb::Status Initialize(bool clean_live_blob_journal);
const url::Origin& origin() const { return origin_; } const url::Origin& origin() const { return origin_; }
IndexedDBFactory* factory() const { return indexed_db_factory_; }
base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); } base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); }
IndexedDBActiveBlobRegistry* active_blob_registry() { IndexedDBActiveBlobRegistry* active_blob_registry() {
return &active_blob_registry_; return active_blob_registry_.get();
} }
void GrantChildProcessPermissions(int child_process_id); void GrantChildProcessPermissions(int child_process_id);
...@@ -650,7 +654,6 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -650,7 +654,6 @@ class CONTENT_EXPORT IndexedDBBackingStore {
void DidCommitTransaction(); void DidCommitTransaction();
Mode backing_store_mode_; Mode backing_store_mode_;
IndexedDBFactory* indexed_db_factory_;
TransactionalLevelDBFactory* const transactional_leveldb_factory_; TransactionalLevelDBFactory* const transactional_leveldb_factory_;
const url::Origin origin_; const url::Origin origin_;
base::FilePath blob_path_; base::FilePath blob_path_;
...@@ -677,9 +680,12 @@ class CONTENT_EXPORT IndexedDBBackingStore { ...@@ -677,9 +680,12 @@ class CONTENT_EXPORT IndexedDBBackingStore {
#endif #endif
std::unique_ptr<TransactionalLevelDBDatabase> db_; std::unique_ptr<TransactionalLevelDBDatabase> db_;
BlobFilesCleanedCallback blob_files_cleaned_;
// Whenever blobs are registered in active_blob_registry_, // Whenever blobs are registered in active_blob_registry_,
// indexed_db_factory_ will hold a reference to this backing store. // indexed_db_factory_ will hold a reference to this backing store.
IndexedDBActiveBlobRegistry active_blob_registry_; std::unique_ptr<IndexedDBActiveBlobRegistry> active_blob_registry_;
// Incremented whenever a transaction starts committing, decremented when // Incremented whenever a transaction starts committing, decremented when
// complete. While > 0, temporary journal entries may exist so out-of-band // complete. While > 0, temporary journal entries may exist so out-of-band
......
...@@ -68,18 +68,20 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore { ...@@ -68,18 +68,20 @@ class TestableIndexedDBBackingStore : public IndexedDBBackingStore {
public: public:
TestableIndexedDBBackingStore( TestableIndexedDBBackingStore(
IndexedDBBackingStore::Mode backing_store_mode, IndexedDBBackingStore::Mode backing_store_mode,
IndexedDBFactory* indexed_db_factory,
TransactionalLevelDBFactory* leveldb_factory, TransactionalLevelDBFactory* leveldb_factory,
const url::Origin& origin, const url::Origin& origin,
const base::FilePath& blob_path, const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db, std::unique_ptr<TransactionalLevelDBDatabase> db,
BlobFilesCleanedCallback blob_files_cleaned,
ReportOutstandingBlobsCallback report_outstanding_blobs,
base::SequencedTaskRunner* task_runner) base::SequencedTaskRunner* task_runner)
: IndexedDBBackingStore(backing_store_mode, : IndexedDBBackingStore(backing_store_mode,
indexed_db_factory,
leveldb_factory, leveldb_factory,
origin, origin,
blob_path, blob_path,
std::move(db), std::move(db),
std::move(blob_files_cleaned),
std::move(report_outstanding_blobs),
task_runner), task_runner),
database_id_(0) {} database_id_(0) {}
~TestableIndexedDBBackingStore() override = default; ~TestableIndexedDBBackingStore() override = default;
...@@ -153,10 +155,14 @@ class TestIDBFactory : public IndexedDBFactoryImpl { ...@@ -153,10 +155,14 @@ class TestIDBFactory : public IndexedDBFactoryImpl {
const url::Origin& origin, const url::Origin& origin,
const base::FilePath& blob_path, const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db, std::unique_ptr<TransactionalLevelDBDatabase> db,
IndexedDBBackingStore::BlobFilesCleanedCallback blob_files_cleaned,
IndexedDBBackingStore::ReportOutstandingBlobsCallback
report_outstanding_blobs,
base::SequencedTaskRunner* task_runner) override { base::SequencedTaskRunner* task_runner) override {
return std::make_unique<TestableIndexedDBBackingStore>( return std::make_unique<TestableIndexedDBBackingStore>(
backing_store_mode, this, leveldb_factory, origin, blob_path, backing_store_mode, leveldb_factory, origin, blob_path, std::move(db),
std::move(db), task_runner); std::move(blob_files_cleaned), std::move(report_outstanding_blobs),
task_runner);
} }
private: private:
...@@ -466,7 +472,8 @@ TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) { ...@@ -466,7 +472,8 @@ TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) {
IndexedDBValue value = value1_; IndexedDBValue value = value1_;
{ {
IndexedDBBackingStore::Transaction transaction1( IndexedDBBackingStore::Transaction transaction1(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1.Begin(CreateDummyLock()); transaction1.Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
leveldb::Status s = backing_store()->PutRecord(&transaction1, 1, 1, leveldb::Status s = backing_store()->PutRecord(&transaction1, 1, 1,
...@@ -483,7 +490,8 @@ TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) { ...@@ -483,7 +490,8 @@ TEST_F(IndexedDBBackingStoreTest, PutGetConsistency) {
{ {
IndexedDBBackingStore::Transaction transaction2( IndexedDBBackingStore::Transaction transaction2(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction2.Begin(CreateDummyLock()); transaction2.Begin(CreateDummyLock());
IndexedDBValue result_value; IndexedDBValue result_value;
EXPECT_TRUE(backing_store() EXPECT_TRUE(backing_store()
...@@ -515,7 +523,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) { ...@@ -515,7 +523,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) {
FROM_HERE, base::BindLambdaForTesting([&]() { FROM_HERE, base::BindLambdaForTesting([&]() {
// Initiate transaction1 - writing blobs. // Initiate transaction1 - writing blobs.
transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1->Begin(CreateDummyLock()); transaction1->Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
EXPECT_TRUE( EXPECT_TRUE(
...@@ -538,7 +547,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) { ...@@ -538,7 +547,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) {
// Initiate transaction2, reading blobs. // Initiate transaction2, reading blobs.
IndexedDBBackingStore::Transaction transaction2( IndexedDBBackingStore::Transaction transaction2(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction2.Begin(CreateDummyLock()); transaction2.Begin(CreateDummyLock());
IndexedDBValue result_value; IndexedDBValue result_value;
EXPECT_TRUE(backing_store() EXPECT_TRUE(backing_store()
...@@ -559,7 +569,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) { ...@@ -559,7 +569,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, PutGetConsistencyWithBlobs) {
// Initiate transaction3, deleting blobs. // Initiate transaction3, deleting blobs.
transaction3 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction3 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction3->Begin(CreateDummyLock()); transaction3->Begin(CreateDummyLock());
EXPECT_TRUE(backing_store() EXPECT_TRUE(backing_store()
->DeleteRange(transaction3.get(), 1, 1, ->DeleteRange(transaction3.get(), 1, 1,
...@@ -640,7 +651,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, DeleteRange) { ...@@ -640,7 +651,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, DeleteRange) {
// Initiate transaction1 - write records. // Initiate transaction1 - write records.
transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1->Begin(CreateDummyLock()); transaction1->Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
for (size_t i = 0; i < values.size(); ++i) { for (size_t i = 0; i < values.size(); ++i) {
...@@ -667,7 +679,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, DeleteRange) { ...@@ -667,7 +679,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, DeleteRange) {
// Initiate transaction 2 - delete range. // Initiate transaction 2 - delete range.
transaction2 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction2 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction2->Begin(CreateDummyLock()); transaction2->Begin(CreateDummyLock());
IndexedDBValue result_value; IndexedDBValue result_value;
EXPECT_TRUE(backing_store() EXPECT_TRUE(backing_store()
...@@ -759,7 +772,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, DeleteRangeEmptyRange) { ...@@ -759,7 +772,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, DeleteRangeEmptyRange) {
// Initiate transaction1 - write records. // Initiate transaction1 - write records.
transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1->Begin(CreateDummyLock()); transaction1->Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
...@@ -786,7 +800,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, DeleteRangeEmptyRange) { ...@@ -786,7 +800,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, DeleteRangeEmptyRange) {
// Initiate transaction 2 - delete range. // Initiate transaction 2 - delete range.
transaction2 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction2 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction2->Begin(CreateDummyLock()); transaction2->Begin(CreateDummyLock());
IndexedDBValue result_value; IndexedDBValue result_value;
EXPECT_TRUE(backing_store() EXPECT_TRUE(backing_store()
...@@ -829,7 +844,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) { ...@@ -829,7 +844,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) {
FROM_HERE, base::BindLambdaForTesting([&]() { FROM_HERE, base::BindLambdaForTesting([&]() {
// Initiate transaction1. // Initiate transaction1.
transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1->Begin(CreateDummyLock()); transaction1->Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record1; IndexedDBBackingStore::RecordIdentifier record1;
EXPECT_TRUE( EXPECT_TRUE(
...@@ -852,7 +868,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) { ...@@ -852,7 +868,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, BlobJournalInterleavedTransactions) {
// Initiate transaction2. // Initiate transaction2.
transaction2 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction2 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction2->Begin(CreateDummyLock()); transaction2->Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record2; IndexedDBBackingStore::RecordIdentifier record2;
EXPECT_TRUE( EXPECT_TRUE(
...@@ -897,7 +914,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) { ...@@ -897,7 +914,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) {
idb_context_->TaskRunner()->PostTask( idb_context_->TaskRunner()->PostTask(
FROM_HERE, base::BindLambdaForTesting([&]() { FROM_HERE, base::BindLambdaForTesting([&]() {
transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1->Begin(CreateDummyLock()); transaction1->Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
EXPECT_TRUE( EXPECT_TRUE(
...@@ -918,7 +936,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) { ...@@ -918,7 +936,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) {
EXPECT_TRUE(transaction1->CommitPhaseTwo().ok()); EXPECT_TRUE(transaction1->CommitPhaseTwo().ok());
IndexedDBBackingStore::Transaction transaction2( IndexedDBBackingStore::Transaction transaction2(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction2.Begin(CreateDummyLock()); transaction2.Begin(CreateDummyLock());
EXPECT_TRUE( EXPECT_TRUE(
backing_store() backing_store()
...@@ -939,7 +958,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) { ...@@ -939,7 +958,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, LiveBlobJournal) {
} }
transaction3 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction3 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction3->Begin(CreateDummyLock()); transaction3->Begin(CreateDummyLock());
EXPECT_TRUE(backing_store() EXPECT_TRUE(backing_store()
->DeleteRange(transaction3.get(), 1, 1, ->DeleteRange(transaction3.get(), 1, 1,
...@@ -1013,7 +1033,8 @@ TEST_F(IndexedDBBackingStoreTest, HighIds) { ...@@ -1013,7 +1033,8 @@ TEST_F(IndexedDBBackingStoreTest, HighIds) {
EncodeIDBKey(index_key, &index_key_raw); EncodeIDBKey(index_key, &index_key_raw);
{ {
IndexedDBBackingStore::Transaction transaction1( IndexedDBBackingStore::Transaction transaction1(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1.Begin(CreateDummyLock()); transaction1.Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
leveldb::Status s = backing_store()->PutRecord( leveldb::Status s = backing_store()->PutRecord(
...@@ -1042,7 +1063,8 @@ TEST_F(IndexedDBBackingStoreTest, HighIds) { ...@@ -1042,7 +1063,8 @@ TEST_F(IndexedDBBackingStoreTest, HighIds) {
{ {
IndexedDBBackingStore::Transaction transaction2( IndexedDBBackingStore::Transaction transaction2(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction2.Begin(CreateDummyLock()); transaction2.Begin(CreateDummyLock());
IndexedDBValue result_value; IndexedDBValue result_value;
leveldb::Status s = backing_store()->GetRecord( leveldb::Status s = backing_store()->GetRecord(
...@@ -1095,7 +1117,8 @@ TEST_F(IndexedDBBackingStoreTest, InvalidIds) { ...@@ -1095,7 +1117,8 @@ TEST_F(IndexedDBBackingStoreTest, InvalidIds) {
IndexedDBValue result_value; IndexedDBValue result_value;
IndexedDBBackingStore::Transaction transaction1( IndexedDBBackingStore::Transaction transaction1(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1.Begin(CreateDummyLock()); transaction1.Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
...@@ -1186,7 +1209,8 @@ TEST_F(IndexedDBBackingStoreTest, CreateDatabase) { ...@@ -1186,7 +1209,8 @@ TEST_F(IndexedDBBackingStoreTest, CreateDatabase) {
database_id = database.id; database_id = database.id;
IndexedDBBackingStore::Transaction transaction( IndexedDBBackingStore::Transaction transaction(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction.Begin(CreateDummyLock()); transaction.Begin(CreateDummyLock());
IndexedDBObjectStoreMetadata object_store; IndexedDBObjectStoreMetadata object_store;
...@@ -1387,7 +1411,8 @@ TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) { ...@@ -1387,7 +1411,8 @@ TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) {
database_id = database.id; database_id = database.id;
IndexedDBBackingStore::Transaction transaction( IndexedDBBackingStore::Transaction transaction(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction.Begin(CreateDummyLock()); transaction.Begin(CreateDummyLock());
IndexedDBObjectStoreMetadata object_store; IndexedDBObjectStoreMetadata object_store;
...@@ -1414,7 +1439,8 @@ TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) { ...@@ -1414,7 +1439,8 @@ TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) {
// Save a value. // Save a value.
IndexedDBBackingStore::Transaction transaction1( IndexedDBBackingStore::Transaction transaction1(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1.Begin(CreateDummyLock()); transaction1.Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
leveldb::Status s = backing_store()->PutRecord( leveldb::Status s = backing_store()->PutRecord(
...@@ -1447,7 +1473,8 @@ TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) { ...@@ -1447,7 +1473,8 @@ TEST_F(IndexedDBBackingStoreTest, SchemaUpgradeWithoutBlobsSurvives) {
IndexedDBValue value = value1_; IndexedDBValue value = value1_;
IndexedDBBackingStore::Transaction transaction2( IndexedDBBackingStore::Transaction transaction2(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction2.Begin(CreateDummyLock()); transaction2.Begin(CreateDummyLock());
IndexedDBValue result_value; IndexedDBValue result_value;
EXPECT_TRUE(backing_store() EXPECT_TRUE(backing_store()
...@@ -1514,7 +1541,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, SchemaUpgradeWithBlobsCorrupt) { ...@@ -1514,7 +1541,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, SchemaUpgradeWithBlobsCorrupt) {
database_id = database.id; database_id = database.id;
IndexedDBBackingStore::Transaction transaction( IndexedDBBackingStore::Transaction transaction(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction.Begin(CreateDummyLock()); transaction.Begin(CreateDummyLock());
IndexedDBObjectStoreMetadata object_store; IndexedDBObjectStoreMetadata object_store;
...@@ -1539,7 +1567,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, SchemaUpgradeWithBlobsCorrupt) { ...@@ -1539,7 +1567,8 @@ TEST_F(IndexedDBBackingStoreTestWithBlobs, SchemaUpgradeWithBlobsCorrupt) {
FROM_HERE, base::BindLambdaForTesting([&]() { FROM_HERE, base::BindLambdaForTesting([&]() {
// Initiate transaction1 - writing blobs. // Initiate transaction1 - writing blobs.
transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>( transaction1 = std::make_unique<IndexedDBBackingStore::Transaction>(
backing_store(), blink::mojom::IDBTransactionDurability::Relaxed); backing_store()->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed);
transaction1->Begin(CreateDummyLock()); transaction1->Begin(CreateDummyLock());
IndexedDBBackingStore::RecordIdentifier record; IndexedDBBackingStore::RecordIdentifier record;
EXPECT_TRUE(backing_store() EXPECT_TRUE(backing_store()
......
...@@ -44,13 +44,15 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) { ...@@ -44,13 +44,15 @@ TEST(IndexedDBIOErrorTest, CleanUpTest) {
auto task_runner = base::SequencedTaskRunnerHandle::Get(); auto task_runner = base::SequencedTaskRunnerHandle::Get();
std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique< std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique<
IndexedDBBackingStore>( IndexedDBBackingStore>(
IndexedDBBackingStore::Mode::kInMemory, nullptr, IndexedDBBackingStore::Mode::kInMemory, &transactional_leveldb_factory,
&transactional_leveldb_factory, origin, path, origin, path,
transactional_leveldb_factory.CreateLevelDBDatabase( transactional_leveldb_factory.CreateLevelDBDatabase(
FakeLevelDBFactory::GetBrokenLevelDB( FakeLevelDBFactory::GetBrokenLevelDB(
leveldb::Status::IOError("It's broken!"), path), leveldb::Status::IOError("It's broken!"), path),
nullptr, task_runner.get(), nullptr, task_runner.get(),
TransactionalLevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase), TransactionalLevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase),
IndexedDBBackingStore::BlobFilesCleanedCallback(),
IndexedDBBackingStore::ReportOutstandingBlobsCallback(),
task_runner.get()); task_runner.get());
leveldb::Status s = backing_store->Initialize(false); leveldb::Status s = backing_store->Initialize(false);
EXPECT_FALSE(s.ok()); EXPECT_FALSE(s.ok());
...@@ -79,12 +81,14 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) { ...@@ -79,12 +81,14 @@ TEST(IndexedDBNonRecoverableIOErrorTest, NuancedCleanupTest) {
for (leveldb::Status error_status : errors) { for (leveldb::Status error_status : errors) {
std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique< std::unique_ptr<IndexedDBBackingStore> backing_store = std::make_unique<
IndexedDBBackingStore>( IndexedDBBackingStore>(
IndexedDBBackingStore::Mode::kInMemory, nullptr, IndexedDBBackingStore::Mode::kInMemory, &transactional_leveldb_factory,
&transactional_leveldb_factory, origin, path, origin, path,
transactional_leveldb_factory.CreateLevelDBDatabase( transactional_leveldb_factory.CreateLevelDBDatabase(
FakeLevelDBFactory::GetBrokenLevelDB(error_status, path), nullptr, FakeLevelDBFactory::GetBrokenLevelDB(error_status, path), nullptr,
task_runner.get(), task_runner.get(),
TransactionalLevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase), TransactionalLevelDBDatabase::kDefaultMaxOpenIteratorsPerDatabase),
IndexedDBBackingStore::BlobFilesCleanedCallback(),
IndexedDBBackingStore::ReportOutstandingBlobsCallback(),
task_runner.get()); task_runner.get());
leveldb::Status s = backing_store->Initialize(false); leveldb::Status s = backing_store->Initialize(false);
ASSERT_TRUE(s.IsIOError()); ASSERT_TRUE(s.IsIOError());
......
...@@ -188,7 +188,7 @@ TEST_F(IndexedDBDatabaseTest, ForcedClose) { ...@@ -188,7 +188,7 @@ TEST_F(IndexedDBDatabaseTest, ForcedClose) {
transaction_id, std::set<int64_t>(scope.begin(), scope.end()), transaction_id, std::set<int64_t>(scope.begin(), scope.end()),
blink::mojom::IDBTransactionMode::ReadOnly, blink::mojom::IDBTransactionMode::ReadOnly,
new IndexedDBBackingStore::Transaction( new IndexedDBBackingStore::Transaction(
backing_store_.get(), backing_store_->AsWeakPtr(),
blink::mojom::IDBTransactionDurability::Relaxed)); blink::mojom::IDBTransactionDurability::Relaxed));
db_->RegisterAndScheduleTransaction(transaction); db_->RegisterAndScheduleTransaction(transaction);
......
...@@ -778,10 +778,14 @@ std::unique_ptr<IndexedDBBackingStore> IndexedDBFactoryImpl::CreateBackingStore( ...@@ -778,10 +778,14 @@ std::unique_ptr<IndexedDBBackingStore> IndexedDBFactoryImpl::CreateBackingStore(
const url::Origin& origin, const url::Origin& origin,
const base::FilePath& blob_path, const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db, std::unique_ptr<TransactionalLevelDBDatabase> db,
IndexedDBBackingStore::BlobFilesCleanedCallback blob_files_cleaned,
IndexedDBBackingStore::ReportOutstandingBlobsCallback
report_outstanding_blobs,
base::SequencedTaskRunner* task_runner) { base::SequencedTaskRunner* task_runner) {
return std::make_unique<IndexedDBBackingStore>( return std::make_unique<IndexedDBBackingStore>(
backing_store_mode, this, transactional_leveldb_factory, origin, backing_store_mode, transactional_leveldb_factory, origin, blob_path,
blob_path, std::move(db), task_runner); std::move(db), std::move(blob_files_cleaned),
std::move(report_outstanding_blobs), task_runner);
} }
std::tuple<std::unique_ptr<IndexedDBBackingStore>, std::tuple<std::unique_ptr<IndexedDBBackingStore>,
...@@ -908,7 +912,12 @@ IndexedDBFactoryImpl::OpenAndVerifyIndexedDBBackingStore( ...@@ -908,7 +912,12 @@ IndexedDBFactoryImpl::OpenAndVerifyIndexedDBBackingStore(
: IndexedDBBackingStore::Mode::kOnDisk; : IndexedDBBackingStore::Mode::kOnDisk;
std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore( std::unique_ptr<IndexedDBBackingStore> backing_store = CreateBackingStore(
backing_store_mode, &class_factory_->transactional_leveldb_factory(), backing_store_mode, &class_factory_->transactional_leveldb_factory(),
origin, blob_path, std::move(database), context_->TaskRunner()); origin, blob_path, std::move(database),
base::BindRepeating(&IndexedDBFactoryImpl::BlobFilesCleaned,
weak_factory_.GetWeakPtr(), origin),
base::BindRepeating(&IndexedDBFactoryImpl::ReportOutstandingBlobs,
weak_factory_.GetWeakPtr(), origin),
context_->TaskRunner());
status = backing_store->Initialize( status = backing_store->Initialize(
/*cleanup_live_journal=*/(!is_incognito_and_in_memory && /*cleanup_live_journal=*/(!is_incognito_and_in_memory &&
first_open_since_startup)); first_open_since_startup));
......
...@@ -146,6 +146,9 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory { ...@@ -146,6 +146,9 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
const url::Origin& origin, const url::Origin& origin,
const base::FilePath& blob_path, const base::FilePath& blob_path,
std::unique_ptr<TransactionalLevelDBDatabase> db, std::unique_ptr<TransactionalLevelDBDatabase> db,
IndexedDBBackingStore::BlobFilesCleanedCallback blob_files_cleaned,
IndexedDBBackingStore::ReportOutstandingBlobsCallback
report_outstanding_blobs,
base::SequencedTaskRunner* task_runner); base::SequencedTaskRunner* task_runner);
IndexedDBContextImpl* context() const { return context_; } IndexedDBContextImpl* context() const { return context_; }
...@@ -205,6 +208,7 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory { ...@@ -205,6 +208,7 @@ class CONTENT_EXPORT IndexedDBFactoryImpl : public IndexedDBFactory {
bool IsBackingStorePendingClose(const url::Origin& origin) const; bool IsBackingStorePendingClose(const url::Origin& origin) const;
SEQUENCE_CHECKER(sequence_checker_); SEQUENCE_CHECKER(sequence_checker_);
// Raw pointer is safe because IndexedDBContextImpl owns this object.
IndexedDBContextImpl* context_; IndexedDBContextImpl* context_;
IndexedDBClassFactory* const class_factory_; IndexedDBClassFactory* const class_factory_;
base::Clock* const clock_; base::Clock* const clock_;
......
...@@ -28,21 +28,24 @@ TransactionalLevelDBFactory* GetTransactionalLevelDBFactory() { ...@@ -28,21 +28,24 @@ TransactionalLevelDBFactory* GetTransactionalLevelDBFactory() {
IndexedDBFakeBackingStore::IndexedDBFakeBackingStore() IndexedDBFakeBackingStore::IndexedDBFakeBackingStore()
: IndexedDBBackingStore(IndexedDBBackingStore::Mode::kInMemory, : IndexedDBBackingStore(IndexedDBBackingStore::Mode::kInMemory,
nullptr /* indexed_db_factory */,
GetTransactionalLevelDBFactory(), GetTransactionalLevelDBFactory(),
url::Origin::Create(GURL("http://localhost:81")), url::Origin::Create(GURL("http://localhost:81")),
base::FilePath(), base::FilePath(),
std::unique_ptr<TransactionalLevelDBDatabase>(), std::unique_ptr<TransactionalLevelDBDatabase>(),
BlobFilesCleanedCallback(),
ReportOutstandingBlobsCallback(),
base::SequencedTaskRunnerHandle::Get().get()) {} base::SequencedTaskRunnerHandle::Get().get()) {}
IndexedDBFakeBackingStore::IndexedDBFakeBackingStore( IndexedDBFakeBackingStore::IndexedDBFakeBackingStore(
IndexedDBFactory* factory, BlobFilesCleanedCallback blob_files_cleaned,
ReportOutstandingBlobsCallback report_outstanding_blobs,
base::SequencedTaskRunner* task_runner) base::SequencedTaskRunner* task_runner)
: IndexedDBBackingStore(IndexedDBBackingStore::Mode::kOnDisk, : IndexedDBBackingStore(IndexedDBBackingStore::Mode::kOnDisk,
factory,
GetTransactionalLevelDBFactory(), GetTransactionalLevelDBFactory(),
url::Origin::Create(GURL("http://localhost:81")), url::Origin::Create(GURL("http://localhost:81")),
base::FilePath(), base::FilePath(),
std::unique_ptr<TransactionalLevelDBDatabase>(), std::unique_ptr<TransactionalLevelDBDatabase>(),
std::move(blob_files_cleaned),
std::move(report_outstanding_blobs),
task_runner) {} task_runner) {}
IndexedDBFakeBackingStore::~IndexedDBFakeBackingStore() {} IndexedDBFakeBackingStore::~IndexedDBFakeBackingStore() {}
......
...@@ -24,12 +24,12 @@ class IndexedDBKeyRange; ...@@ -24,12 +24,12 @@ class IndexedDBKeyRange;
namespace content { namespace content {
class IndexedDBFactory;
class IndexedDBFakeBackingStore : public IndexedDBBackingStore { class IndexedDBFakeBackingStore : public IndexedDBBackingStore {
public: public:
IndexedDBFakeBackingStore(); IndexedDBFakeBackingStore();
IndexedDBFakeBackingStore(IndexedDBFactory* factory, IndexedDBFakeBackingStore(
BlobFilesCleanedCallback blob_files_cleaned,
ReportOutstandingBlobsCallback report_outstanding_blobs,
base::SequencedTaskRunner* task_runner); base::SequencedTaskRunner* task_runner);
~IndexedDBFakeBackingStore() override; ~IndexedDBFakeBackingStore() override;
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
#include "base/feature_list.h" #include "base/feature_list.h"
#include "base/rand_util.h" #include "base/rand_util.h"
#include "base/stl_util.h" #include "base/stl_util.h"
#include "content/browser/indexed_db/indexed_db_active_blob_registry.h"
#include "content/browser/indexed_db/indexed_db_backing_store.h" #include "content/browser/indexed_db/indexed_db_backing_store.h"
#include "content/browser/indexed_db/indexed_db_class_factory.h" #include "content/browser/indexed_db/indexed_db_class_factory.h"
#include "content/browser/indexed_db/indexed_db_connection.h" #include "content/browser/indexed_db/indexed_db_connection.h"
......
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