Commit 7797b8c8 authored by Daniel Murphy's avatar Daniel Murphy Committed by Commit Bot

Reland "[IndexedDB] Moving IDBDatabase's PendingConnection to use ScopesLockManager"

This is a reland of 1bc0f674

Original change's description:
> [IndexedDB] Moving IDBDatabase's PendingConnection to use ScopesLockManager
> 
> This allows scopes to be used in the DeleteDatabase call, and cleans up
> some code in the IndexedDBDatabase class.
> 
> The last part of the codebase that doesn't have locks before being used
> is the IndexedDBBackingStore::Initialize call. Since this happens on the
> opening of the database, this can probably use just the raw database +
> a WriteBatch.
> 
> Bug: 862456
> Change-Id: I89c79ec89a4450e21f1ee700b007ec867b3a4f48
> Reviewed-on: https://chromium-review.googlesource.com/c/1478391
> Commit-Queue: Daniel Murphy <dmurph@chromium.org>
> Reviewed-by: Chase Phillips <cmp@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#634358}

Bug: 862456
Change-Id: I821c28b93fde903678737d49eaeb44c1b7369e08
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1506552Reviewed-by: default avatarChase Phillips <cmp@chromium.org>
Commit-Queue: Daniel Murphy <dmurph@chromium.org>
Cr-Commit-Position: refs/heads/master@{#638350}
parent 04c92af8
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include "base/bind.h" #include "base/bind.h"
#include "base/logging.h" #include "base/logging.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
#include "base/stl_util.h" #include "base/stl_util.h"
...@@ -32,6 +33,8 @@ ...@@ -32,6 +33,8 @@
#include "content/browser/indexed_db/indexed_db_tracing.h" #include "content/browser/indexed_db/indexed_db_tracing.h"
#include "content/browser/indexed_db/indexed_db_transaction.h" #include "content/browser/indexed_db/indexed_db_transaction.h"
#include "content/browser/indexed_db/indexed_db_value.h" #include "content/browser/indexed_db/indexed_db_value.h"
#include "content/browser/indexed_db/scopes/scope_lock.h"
#include "content/browser/indexed_db/scopes/scopes_lock_manager.h"
#include "content/public/common/content_switches.h" #include "content/public/common/content_switches.h"
#include "ipc/ipc_channel.h" #include "ipc/ipc_channel.h"
#include "storage/browser/blob/blob_data_handle.h" #include "storage/browser/blob/blob_data_handle.h"
...@@ -124,7 +127,9 @@ class IndexedDBDatabase::OpenRequest ...@@ -124,7 +127,9 @@ class IndexedDBDatabase::OpenRequest
public: public:
OpenRequest(scoped_refptr<IndexedDBDatabase> db, OpenRequest(scoped_refptr<IndexedDBDatabase> db,
std::unique_ptr<IndexedDBPendingConnection> pending_connection) std::unique_ptr<IndexedDBPendingConnection> pending_connection)
: ConnectionRequest(db), pending_(std::move(pending_connection)) {} : ConnectionRequest(db),
pending_(std::move(pending_connection)),
weak_factory_(this) {}
void Perform() override { void Perform() override {
if (db_->metadata_.id == kInvalidId) { if (db_->metadata_.id == kInvalidId) {
...@@ -200,7 +205,13 @@ class IndexedDBDatabase::OpenRequest ...@@ -200,7 +205,13 @@ class IndexedDBDatabase::OpenRequest
DCHECK_GT(new_version, old_version); DCHECK_GT(new_version, old_version);
if (db_->connections_.empty()) { if (db_->connections_.empty()) {
StartUpgrade(); std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
{kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
ScopesLockManager::LockType::kExclusive}};
db_->lock_manager_->AcquireLocks(
std::move(lock_requests),
base::BindOnce(&IndexedDBDatabase::OpenRequest::StartUpgrade,
weak_factory_.GetWeakPtr()));
return; return;
} }
...@@ -234,13 +245,19 @@ class IndexedDBDatabase::OpenRequest ...@@ -234,13 +245,19 @@ class IndexedDBDatabase::OpenRequest
if (!db_->connections_.empty()) if (!db_->connections_.empty())
return; return;
StartUpgrade(); std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
{kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
ScopesLockManager::LockType::kExclusive}};
db_->lock_manager_->AcquireLocks(
std::move(lock_requests),
base::BindOnce(&IndexedDBDatabase::OpenRequest::StartUpgrade,
weak_factory_.GetWeakPtr()));
} }
// Initiate the upgrade. The bulk of the work actually happens in // Initiate the upgrade. The bulk of the work actually happens in
// IndexedDBDatabase::VersionChangeOperation in order to kick the // IndexedDBDatabase::VersionChangeOperation in order to kick the
// transaction into the correct state. // transaction into the correct state.
void StartUpgrade() { void StartUpgrade(std::vector<ScopeLock> locks) {
connection_ = db_->CreateConnection(pending_->database_callbacks, connection_ = db_->CreateConnection(pending_->database_callbacks,
pending_->child_process_id); pending_->child_process_id);
DCHECK_EQ(db_->connections_.count(connection_.get()), 1UL); DCHECK_EQ(db_->connections_.count(connection_.get()), 1UL);
...@@ -252,11 +269,10 @@ class IndexedDBDatabase::OpenRequest ...@@ -252,11 +269,10 @@ class IndexedDBDatabase::OpenRequest
std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()),
blink::mojom::IDBTransactionMode::VersionChange, blink::mojom::IDBTransactionMode::VersionChange,
new IndexedDBBackingStore::Transaction(db_->backing_store())); new IndexedDBBackingStore::Transaction(db_->backing_store()));
db_->RegisterAndScheduleTransaction(transaction);
transaction->ScheduleTask( transaction->ScheduleTask(
base::BindOnce(&IndexedDBDatabase::VersionChangeOperation, db_, base::BindOnce(&IndexedDBDatabase::VersionChangeOperation, db_,
pending_->version, pending_->callbacks)); pending_->version, pending_->callbacks));
transaction->Start(std::move(locks));
} }
// Called when the upgrade transaction has started executing. // Called when the upgrade transaction has started executing.
...@@ -296,6 +312,7 @@ class IndexedDBDatabase::OpenRequest ...@@ -296,6 +312,7 @@ class IndexedDBDatabase::OpenRequest
// transferred to the IndexedDBDispatcherHost via OnUpgradeNeeded. // transferred to the IndexedDBDispatcherHost via OnUpgradeNeeded.
std::unique_ptr<IndexedDBConnection> connection_; std::unique_ptr<IndexedDBConnection> connection_;
base::WeakPtrFactory<OpenRequest> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(OpenRequest); DISALLOW_COPY_AND_ASSIGN(OpenRequest);
}; };
...@@ -304,12 +321,18 @@ class IndexedDBDatabase::DeleteRequest ...@@ -304,12 +321,18 @@ class IndexedDBDatabase::DeleteRequest
public: public:
DeleteRequest(scoped_refptr<IndexedDBDatabase> db, DeleteRequest(scoped_refptr<IndexedDBDatabase> db,
scoped_refptr<IndexedDBCallbacks> callbacks) scoped_refptr<IndexedDBCallbacks> callbacks)
: ConnectionRequest(db), callbacks_(callbacks) {} : ConnectionRequest(db), callbacks_(callbacks), weak_factory_(this) {}
void Perform() override { void Perform() override {
if (db_->connections_.empty()) { if (db_->connections_.empty()) {
// No connections, so delete immediately. // No connections, so delete immediately.
DoDelete(); std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
{kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
ScopesLockManager::LockType::kExclusive}};
db_->lock_manager_->AcquireLocks(
std::move(lock_requests),
base::BindOnce(&IndexedDBDatabase::DeleteRequest::DoDelete,
weak_factory_.GetWeakPtr()));
return; return;
} }
...@@ -328,10 +351,17 @@ class IndexedDBDatabase::DeleteRequest ...@@ -328,10 +351,17 @@ class IndexedDBDatabase::DeleteRequest
void OnConnectionClosed(IndexedDBConnection* connection) override { void OnConnectionClosed(IndexedDBConnection* connection) override {
if (!db_->connections_.empty()) if (!db_->connections_.empty())
return; return;
DoDelete();
std::vector<ScopesLockManager::ScopeLockRequest> lock_requests = {
{kDatabaseRangeLockLevel, GetDatabaseLockRange(db_->metadata_.id),
ScopesLockManager::LockType::kExclusive}};
db_->lock_manager_->AcquireLocks(
std::move(lock_requests),
base::BindOnce(&IndexedDBDatabase::DeleteRequest::DoDelete,
weak_factory_.GetWeakPtr()));
} }
void DoDelete() { void DoDelete(std::vector<ScopeLock> locks) {
Status s; Status s;
if (db_->backing_store_) if (db_->backing_store_)
s = db_->backing_store_->DeleteDatabase(db_->metadata_.name); s = db_->backing_store_->DeleteDatabase(db_->metadata_.name);
...@@ -374,6 +404,7 @@ class IndexedDBDatabase::DeleteRequest ...@@ -374,6 +404,7 @@ class IndexedDBDatabase::DeleteRequest
private: private:
scoped_refptr<IndexedDBCallbacks> callbacks_; scoped_refptr<IndexedDBCallbacks> callbacks_;
base::WeakPtrFactory<DeleteRequest> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DeleteRequest); DISALLOW_COPY_AND_ASSIGN(DeleteRequest);
}; };
...@@ -1806,18 +1837,28 @@ Status IndexedDBDatabase::VersionChangeOperation( ...@@ -1806,18 +1837,28 @@ Status IndexedDBDatabase::VersionChangeOperation(
return Status::OK(); return Status::OK();
} }
void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, void IndexedDBDatabase::TransactionCreated() {
UMA_HISTOGRAM_COUNTS_1000(
"WebCore.IndexedDB.Database.OutstandingTransactionCount",
transaction_count_);
++transaction_count_;
}
void IndexedDBDatabase::TransactionFinished(
blink::mojom::IDBTransactionMode mode,
bool committed) { bool committed) {
IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id",
transaction->id());
--transaction_count_; --transaction_count_;
DCHECK_GE(transaction_count_, 0); DCHECK_GE(transaction_count_, 0);
// TODO(dmurph): To help remove this integration with IndexedDBDatabase, make
// a 'committed' listener closure on all transactions. Then the request can
// just listen for that.
// This may be an unrelated transaction finishing while waiting for // This may be an unrelated transaction finishing while waiting for
// connections to close, or the actual upgrade transaction from an active // connections to close, or the actual upgrade transaction from an active
// request. Notify the active request if it's the latter. // request. Notify the active request if it's the latter.
if (active_request_ && if (active_request_ &&
transaction->mode() == blink::mojom::IDBTransactionMode::VersionChange) { mode == blink::mojom::IDBTransactionMode::VersionChange) {
active_request_->UpgradeTransactionFinished(committed); active_request_->UpgradeTransactionFinished(committed);
} }
} }
...@@ -1861,11 +1902,6 @@ void IndexedDBDatabase::RegisterAndScheduleTransaction( ...@@ -1861,11 +1902,6 @@ void IndexedDBDatabase::RegisterAndScheduleTransaction(
IndexedDBTransaction* transaction) { IndexedDBTransaction* transaction) {
IDB_TRACE1("IndexedDBDatabase::RegisterAndScheduleTransaction", "txn.id", IDB_TRACE1("IndexedDBDatabase::RegisterAndScheduleTransaction", "txn.id",
transaction->id()); transaction->id());
UMA_HISTOGRAM_COUNTS_1000(
"WebCore.IndexedDB.Database.OutstandingTransactionCount",
transaction_count_);
transaction_count_++;
std::vector<ScopesLockManager::ScopeLockRequest> lock_requests; std::vector<ScopesLockManager::ScopeLockRequest> lock_requests;
lock_requests.reserve(1 + transaction->scope().size()); lock_requests.reserve(1 + transaction->scope().size());
lock_requests.emplace_back( lock_requests.emplace_back(
......
...@@ -103,8 +103,8 @@ class CONTENT_EXPORT IndexedDBDatabase ...@@ -103,8 +103,8 @@ class CONTENT_EXPORT IndexedDBDatabase
int64_t object_store_id, int64_t object_store_id,
const base::string16& new_name); const base::string16& new_name);
// Returns a pointer to a newly created transaction. The object is owned // TODO(dmurph): Remove this method and have transactions be directly
// by the connection. // scheduled using the lock manager.
void RegisterAndScheduleTransaction(IndexedDBTransaction* transaction); void RegisterAndScheduleTransaction(IndexedDBTransaction* transaction);
void Close(IndexedDBConnection* connection, bool forced); void Close(IndexedDBConnection* connection, bool forced);
void ForceClose(); void ForceClose();
...@@ -136,7 +136,9 @@ class CONTENT_EXPORT IndexedDBDatabase ...@@ -136,7 +136,9 @@ class CONTENT_EXPORT IndexedDBDatabase
return lock_manager_; return lock_manager_;
} }
void TransactionFinished(IndexedDBTransaction* transaction, bool committed); void TransactionCreated();
void TransactionFinished(blink::mojom::IDBTransactionMode mode,
bool committed);
void AbortAllTransactionsForConnections(); void AbortAllTransactionsForConnections();
......
...@@ -119,6 +119,8 @@ IndexedDBTransaction::IndexedDBTransaction( ...@@ -119,6 +119,8 @@ IndexedDBTransaction::IndexedDBTransaction(
IDB_ASYNC_TRACE_BEGIN("IndexedDBTransaction::lifetime", this); IDB_ASYNC_TRACE_BEGIN("IndexedDBTransaction::lifetime", this);
callbacks_ = connection_->callbacks(); callbacks_ = connection_->callbacks();
database_ = connection_->database(); database_ = connection_->database();
if (database_)
database_->TransactionCreated();
diagnostics_.tasks_scheduled = 0; diagnostics_.tasks_scheduled = 0;
diagnostics_.tasks_completed = 0; diagnostics_.tasks_completed = 0;
...@@ -246,7 +248,7 @@ void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) { ...@@ -246,7 +248,7 @@ void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) {
if (callbacks_.get()) if (callbacks_.get())
callbacks_->OnAbort(*this, error); callbacks_->OnAbort(*this, error);
database_->TransactionFinished(this, false); database_->TransactionFinished(mode_, false);
// RemoveTransaction will delete |this|. // RemoveTransaction will delete |this|.
// Note: During force-close situations, the connection can be destroyed during // Note: During force-close situations, the connection can be destroyed during
...@@ -469,7 +471,7 @@ leveldb::Status IndexedDBTransaction::CommitPhaseTwo() { ...@@ -469,7 +471,7 @@ leveldb::Status IndexedDBTransaction::CommitPhaseTwo() {
if (!pending_observers_.empty() && connection_) if (!pending_observers_.empty() && connection_)
connection_->ActivatePendingObservers(std::move(pending_observers_)); connection_->ActivatePendingObservers(std::move(pending_observers_));
database_->TransactionFinished(this, true); database_->TransactionFinished(mode_, true);
// RemoveTransaction will delete |this|. // RemoveTransaction will delete |this|.
connection_->RemoveTransaction(id_); connection_->RemoveTransaction(id_);
return s; return s;
...@@ -488,7 +490,7 @@ leveldb::Status IndexedDBTransaction::CommitPhaseTwo() { ...@@ -488,7 +490,7 @@ leveldb::Status IndexedDBTransaction::CommitPhaseTwo() {
"Internal error committing transaction."); "Internal error committing transaction.");
} }
callbacks_->OnAbort(*this, error); callbacks_->OnAbort(*this, error);
database_->TransactionFinished(this, false); database_->TransactionFinished(mode_, false);
} }
return s; return s;
} }
......
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