| Index: content/browser/indexed_db/indexed_db_database.cc | 
| diff --git a/content/browser/indexed_db/indexed_db_database.cc b/content/browser/indexed_db/indexed_db_database.cc | 
| index 516dfc4f7760978c5da234e04ed9302b53ee9453..aa8040ce09c55d88f09ddc9f6c628d0cca01fb93 100644 | 
| --- a/content/browser/indexed_db/indexed_db_database.cc | 
| +++ b/content/browser/indexed_db/indexed_db_database.cc | 
| @@ -97,7 +97,8 @@ class IndexedDBDatabase::ConnectionRequest { | 
| virtual void OnConnectionClosed(IndexedDBConnection* connection) = 0; | 
|  | 
| // Called when the upgrade transaction has started executing. | 
| -  virtual void UpgradeTransactionStarted(int64_t old_version) = 0; | 
| +  virtual void UpgradeTransactionStarted(int64_t old_version, | 
| +                                         IndexedDBTransaction* transaction) = 0; | 
|  | 
| // Called when the upgrade transaction has finished. | 
| virtual void UpgradeTransactionFinished(bool committed) = 0; | 
| @@ -156,7 +157,7 @@ class IndexedDBDatabase::OpenRequest | 
| DCHECK(is_new_database); | 
| pending_->callbacks->OnSuccess( | 
| db_->CreateConnection(pending_->database_callbacks, | 
| -                                pending_->child_process_id), | 
| +                                pending_->child_process_id, pending_->origin), | 
| db_->metadata_); | 
| db_->RequestComplete(this); | 
| return; | 
| @@ -167,7 +168,7 @@ class IndexedDBDatabase::OpenRequest | 
| new_version == IndexedDBDatabaseMetadata::NO_VERSION)) { | 
| pending_->callbacks->OnSuccess( | 
| db_->CreateConnection(pending_->database_callbacks, | 
| -                                pending_->child_process_id), | 
| +                                pending_->child_process_id, pending_->origin), | 
| db_->metadata_); | 
| db_->RequestComplete(this); | 
| return; | 
| @@ -235,8 +236,9 @@ class IndexedDBDatabase::OpenRequest | 
| // IndexedDBDatabase::VersionChangeOperation in order to kick the | 
| // transaction into the correct state. | 
| void StartUpgrade() { | 
| -    connection_ = db_->CreateConnection(pending_->database_callbacks, | 
| -                                        pending_->child_process_id); | 
| +    connection_ = | 
| +        db_->CreateConnection(pending_->database_callbacks, | 
| +                              pending_->child_process_id, pending_->origin); | 
| DCHECK_EQ(db_->connections_.count(connection_.get()), 1UL); | 
|  | 
| std::vector<int64_t> object_store_ids; | 
| @@ -251,10 +253,11 @@ class IndexedDBDatabase::OpenRequest | 
| } | 
|  | 
| // Called when the upgrade transaction has started executing. | 
| -  void UpgradeTransactionStarted(int64_t old_version) override { | 
| +  void UpgradeTransactionStarted(int64_t old_version, | 
| +                                 IndexedDBTransaction* transaction) override { | 
| DCHECK(connection_); | 
| pending_->callbacks->OnUpgradeNeeded(old_version, std::move(connection_), | 
| -                                         db_->metadata_, | 
| +                                         transaction, db_->metadata_, | 
| pending_->data_loss_info); | 
| } | 
|  | 
| @@ -346,7 +349,10 @@ class IndexedDBDatabase::DeleteRequest | 
| db_->RequestComplete(this); | 
| } | 
|  | 
| -  void UpgradeTransactionStarted(int64_t old_version) override { NOTREACHED(); } | 
| +  void UpgradeTransactionStarted(int64_t old_version, | 
| +                                 IndexedDBTransaction* transaction) override { | 
| +    NOTREACHED(); | 
| +  } | 
|  | 
| void UpgradeTransactionFinished(bool committed) override { NOTREACHED(); } | 
|  | 
| @@ -468,7 +474,6 @@ leveldb::Status IndexedDBDatabase::OpenInternal() { | 
| } | 
|  | 
| IndexedDBDatabase::~IndexedDBDatabase() { | 
| -  DCHECK(transactions_.empty()); | 
| DCHECK(!active_request_); | 
| DCHECK(pending_requests_.empty()); | 
| } | 
| @@ -479,22 +484,16 @@ size_t IndexedDBDatabase::GetMaxMessageSizeInBytes() const { | 
|  | 
| std::unique_ptr<IndexedDBConnection> IndexedDBDatabase::CreateConnection( | 
| scoped_refptr<IndexedDBDatabaseCallbacks> database_callbacks, | 
| -    int child_process_id) { | 
| +    int child_process_id, | 
| +    const url::Origin& origin) { | 
| std::unique_ptr<IndexedDBConnection> connection( | 
| -      base::MakeUnique<IndexedDBConnection>(this, database_callbacks)); | 
| +      base::MakeUnique<IndexedDBConnection>(child_process_id, origin, this, | 
| +                                            database_callbacks)); | 
| connections_.insert(connection.get()); | 
| backing_store_->GrantChildProcessPermissions(child_process_id); | 
| return connection; | 
| } | 
|  | 
| -IndexedDBTransaction* IndexedDBDatabase::GetTransaction( | 
| -    int64_t transaction_id) const { | 
| -  const auto& trans_iterator = transactions_.find(transaction_id); | 
| -  if (trans_iterator == transactions_.end()) | 
| -    return NULL; | 
| -  return trans_iterator->second; | 
| -} | 
| - | 
| bool IndexedDBDatabase::ValidateObjectStoreId(int64_t object_store_id) const { | 
| if (!base::ContainsKey(metadata_.object_stores, object_store_id)) { | 
| DLOG(ERROR) << "Invalid object_store_id"; | 
| @@ -546,15 +545,15 @@ bool IndexedDBDatabase::ValidateObjectStoreIdAndNewIndexId( | 
| return true; | 
| } | 
|  | 
| -void IndexedDBDatabase::CreateObjectStore(int64_t transaction_id, | 
| +void IndexedDBDatabase::CreateObjectStore(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| const base::string16& name, | 
| const IndexedDBKeyPath& key_path, | 
| bool auto_increment) { | 
| -  IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::CreateObjectStore", "txn.id", | 
| +             transaction->id()); | 
| DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 
|  | 
| if (base::ContainsKey(metadata_.object_stores, object_store_id)) { | 
| @@ -602,12 +601,12 @@ void IndexedDBDatabase::CreateObjectStore(int64_t transaction_id, | 
| object_store_id)); | 
| } | 
|  | 
| -void IndexedDBDatabase::DeleteObjectStore(int64_t transaction_id, | 
| +void IndexedDBDatabase::DeleteObjectStore(IndexedDBTransaction* transaction, | 
| int64_t object_store_id) { | 
| -  IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::DeleteObjectStore", "txn.id", | 
| +             transaction->id()); | 
| DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 
|  | 
| if (!ValidateObjectStoreId(object_store_id)) | 
| @@ -619,13 +618,13 @@ void IndexedDBDatabase::DeleteObjectStore(int64_t transaction_id, | 
| object_store_id)); | 
| } | 
|  | 
| -void IndexedDBDatabase::RenameObjectStore(int64_t transaction_id, | 
| +void IndexedDBDatabase::RenameObjectStore(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| const base::string16& new_name) { | 
| -  IDB_TRACE1("IndexedDBDatabase::RenameObjectStore", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::RenameObjectStore", "txn.id", | 
| +             transaction->id()); | 
| DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 
|  | 
| if (!ValidateObjectStoreId(object_store_id)) | 
| @@ -661,17 +660,16 @@ void IndexedDBDatabase::RenameObjectStore(int64_t transaction_id, | 
| SetObjectStoreName(object_store_id, new_name); | 
| } | 
|  | 
| -void IndexedDBDatabase::CreateIndex(int64_t transaction_id, | 
| +void IndexedDBDatabase::CreateIndex(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| int64_t index_id, | 
| const base::string16& name, | 
| const IndexedDBKeyPath& key_path, | 
| bool unique, | 
| bool multi_entry) { | 
| -  IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::CreateIndex", "txn.id", transaction->id()); | 
| DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 
|  | 
| if (!ValidateObjectStoreIdAndNewIndexId(object_store_id, index_id)) | 
| @@ -721,13 +719,12 @@ void IndexedDBDatabase::CreateIndexAbortOperation( | 
| RemoveIndex(object_store_id, index_id); | 
| } | 
|  | 
| -void IndexedDBDatabase::DeleteIndex(int64_t transaction_id, | 
| +void IndexedDBDatabase::DeleteIndex(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| int64_t index_id) { | 
| -  IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::DeleteIndex", "txn.id", transaction->id()); | 
| DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 
|  | 
| if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) | 
| @@ -784,14 +781,13 @@ void IndexedDBDatabase::DeleteIndexAbortOperation( | 
| AddIndex(object_store_id, index_metadata, IndexedDBIndexMetadata::kInvalidId); | 
| } | 
|  | 
| -void IndexedDBDatabase::RenameIndex(int64_t transaction_id, | 
| +void IndexedDBDatabase::RenameIndex(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| int64_t index_id, | 
| const base::string16& new_name) { | 
| -  IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::RenameIndex", "txn.id", transaction->id()); | 
| DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 
|  | 
| if (!ValidateObjectStoreIdAndIndexId(object_store_id, index_id)) | 
| @@ -838,12 +834,11 @@ void IndexedDBDatabase::RenameIndexAbortOperation( | 
| SetIndexName(object_store_id, index_id, old_name); | 
| } | 
|  | 
| -void IndexedDBDatabase::Commit(int64_t transaction_id) { | 
| +void IndexedDBDatabase::Commit(IndexedDBTransaction* transaction) { | 
| // The frontend suggests that we commit, but we may have previously initiated | 
| // an abort, and so have disposed of the transaction. on_abort has already | 
| // been dispatched to the frontend, so it will find out about that | 
| // asynchronously. | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (transaction) { | 
| scoped_refptr<IndexedDBFactory> factory = factory_; | 
| leveldb::Status s = transaction->Commit(); | 
| @@ -855,46 +850,15 @@ void IndexedDBDatabase::Commit(int64_t transaction_id) { | 
| } | 
| } | 
|  | 
| -void IndexedDBDatabase::Abort(int64_t transaction_id) { | 
| -  // If the transaction is unknown, then it has already been aborted by the | 
| -  // backend before this call so it is safe to ignore it. | 
| -  IDB_TRACE1("IndexedDBDatabase::Abort", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| -  if (transaction) | 
| -    transaction->Abort(); | 
| -} | 
| - | 
| -void IndexedDBDatabase::Abort(int64_t transaction_id, | 
| -                              const IndexedDBDatabaseError& error) { | 
| -  IDB_TRACE1("IndexedDBDatabase::Abort(error)", "txn.id", transaction_id); | 
| -  // If the transaction is unknown, then it has already been aborted by the | 
| -  // backend before this call so it is safe to ignore it. | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| -  if (transaction) | 
| -    transaction->Abort(error); | 
| -} | 
| - | 
| void IndexedDBDatabase::AddPendingObserver( | 
| -    int64_t transaction_id, | 
| +    IndexedDBTransaction* transaction, | 
| int32_t observer_id, | 
| const IndexedDBObserver::Options& options) { | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| transaction->AddPendingObserver(observer_id, options); | 
| } | 
|  | 
| -void IndexedDBDatabase::RemovePendingObservers( | 
| -    IndexedDBConnection* connection, | 
| -    const std::vector<int32_t>& pending_observer_ids) { | 
| -  for (const auto& it : transactions_) { | 
| -    // Avoid call to RemovePendingObservers for transactions on other | 
| -    // connections. | 
| -    if (it.second->connection() == connection) | 
| -      it.second->RemovePendingObservers(pending_observer_ids); | 
| -  } | 
| -} | 
| - | 
| // TODO(palakj): Augment the function with IDBValue later. Issue | 
| // crbug.com/609934. | 
| void IndexedDBDatabase::FilterObservation(IndexedDBTransaction* transaction, | 
| @@ -934,17 +898,16 @@ void IndexedDBDatabase::SendObservations( | 
| } | 
| } | 
|  | 
| -void IndexedDBDatabase::GetAll(int64_t transaction_id, | 
| +void IndexedDBDatabase::GetAll(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| int64_t index_id, | 
| std::unique_ptr<IndexedDBKeyRange> key_range, | 
| bool key_only, | 
| int64_t max_count, | 
| scoped_refptr<IndexedDBCallbacks> callbacks) { | 
| -  IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::GetAll", "txn.id", transaction->id()); | 
|  | 
| if (!ValidateObjectStoreId(object_store_id)) | 
| return; | 
| @@ -956,16 +919,15 @@ void IndexedDBDatabase::GetAll(int64_t transaction_id, | 
| max_count, callbacks)); | 
| } | 
|  | 
| -void IndexedDBDatabase::Get(int64_t transaction_id, | 
| +void IndexedDBDatabase::Get(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| int64_t index_id, | 
| std::unique_ptr<IndexedDBKeyRange> key_range, | 
| bool key_only, | 
| scoped_refptr<IndexedDBCallbacks> callbacks) { | 
| -  IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::Get", "txn.id", transaction->id()); | 
|  | 
| if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) | 
| return; | 
| @@ -1326,7 +1288,7 @@ struct IndexedDBDatabase::PutOperationParams { | 
| }; | 
|  | 
| void IndexedDBDatabase::Put( | 
| -    int64_t transaction_id, | 
| +    IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| IndexedDBValue* value, | 
| std::vector<std::unique_ptr<storage::BlobDataHandle>>* handles, | 
| @@ -1334,10 +1296,9 @@ void IndexedDBDatabase::Put( | 
| blink::WebIDBPutMode put_mode, | 
| scoped_refptr<IndexedDBCallbacks> callbacks, | 
| const std::vector<IndexKeys>& index_keys) { | 
| -  IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::Put", "txn.id", transaction->id()); | 
| DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); | 
|  | 
| if (!ValidateObjectStoreId(object_store_id)) | 
| @@ -1501,14 +1462,13 @@ void IndexedDBDatabase::PutOperation(std::unique_ptr<PutOperationParams> params, | 
| IndexedDBKeyRange(*key)); | 
| } | 
|  | 
| -void IndexedDBDatabase::SetIndexKeys(int64_t transaction_id, | 
| +void IndexedDBDatabase::SetIndexKeys(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| std::unique_ptr<IndexedDBKey> primary_key, | 
| const std::vector<IndexKeys>& index_keys) { | 
| -  IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::SetIndexKeys", "txn.id", transaction->id()); | 
| DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 
|  | 
| // TODO(alecflett): This method could be asynchronous, but we need to | 
| @@ -1573,10 +1533,9 @@ void IndexedDBDatabase::SetIndexKeys(int64_t transaction_id, | 
| } | 
| } | 
|  | 
| -void IndexedDBDatabase::SetIndexesReady(int64_t transaction_id, | 
| +void IndexedDBDatabase::SetIndexesReady(IndexedDBTransaction* transaction, | 
| int64_t, | 
| const std::vector<int64_t>& index_ids) { | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| DCHECK_EQ(transaction->mode(), blink::WebIDBTransactionModeVersionChange); | 
| @@ -1610,7 +1569,7 @@ struct IndexedDBDatabase::OpenCursorOperationParams { | 
| }; | 
|  | 
| void IndexedDBDatabase::OpenCursor( | 
| -    int64_t transaction_id, | 
| +    IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| int64_t index_id, | 
| std::unique_ptr<IndexedDBKeyRange> key_range, | 
| @@ -1618,10 +1577,9 @@ void IndexedDBDatabase::OpenCursor( | 
| bool key_only, | 
| blink::WebIDBTaskType task_type, | 
| scoped_refptr<IndexedDBCallbacks> callbacks) { | 
| -  IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::OpenCursor", "txn.id", transaction->id()); | 
|  | 
| if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) | 
| return; | 
| @@ -1712,22 +1670,23 @@ void IndexedDBDatabase::OpenCursorOperation( | 
| return; | 
| } | 
|  | 
| -  scoped_refptr<IndexedDBCursor> cursor = | 
| -      new IndexedDBCursor(std::move(backing_store_cursor), params->cursor_type, | 
| -                          params->task_type, transaction); | 
| -  params->callbacks->OnSuccess( | 
| -      cursor, cursor->key(), cursor->primary_key(), cursor->Value()); | 
| +  std::unique_ptr<IndexedDBCursor> cursor = base::MakeUnique<IndexedDBCursor>( | 
| +      std::move(backing_store_cursor), params->cursor_type, params->task_type, | 
| +      transaction); | 
| +  IndexedDBCursor* cursor_ptr = cursor.get(); | 
| +  transaction->RegisterOpenCursor(cursor_ptr); | 
| +  params->callbacks->OnSuccess(std::move(cursor), cursor_ptr->key(), | 
| +                               cursor_ptr->primary_key(), cursor_ptr->Value()); | 
| } | 
|  | 
| -void IndexedDBDatabase::Count(int64_t transaction_id, | 
| +void IndexedDBDatabase::Count(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| int64_t index_id, | 
| std::unique_ptr<IndexedDBKeyRange> key_range, | 
| scoped_refptr<IndexedDBCallbacks> callbacks) { | 
| -  IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::Count", "txn.id", transaction->id()); | 
|  | 
| if (!ValidateObjectStoreIdAndOptionalIndexId(object_store_id, index_id)) | 
| return; | 
| @@ -1792,14 +1751,13 @@ void IndexedDBDatabase::CountOperation( | 
| } | 
|  | 
| void IndexedDBDatabase::DeleteRange( | 
| -    int64_t transaction_id, | 
| +    IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| std::unique_ptr<IndexedDBKeyRange> key_range, | 
| scoped_refptr<IndexedDBCallbacks> callbacks) { | 
| -  IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::DeleteRange", "txn.id", transaction->id()); | 
| DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); | 
|  | 
| if (!ValidateObjectStoreId(object_store_id)) | 
| @@ -1839,13 +1797,12 @@ void IndexedDBDatabase::DeleteRangeOperation( | 
| *key_range); | 
| } | 
|  | 
| -void IndexedDBDatabase::Clear(int64_t transaction_id, | 
| +void IndexedDBDatabase::Clear(IndexedDBTransaction* transaction, | 
| int64_t object_store_id, | 
| scoped_refptr<IndexedDBCallbacks> callbacks) { | 
| -  IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction_id); | 
| -  IndexedDBTransaction* transaction = GetTransaction(transaction_id); | 
| if (!transaction) | 
| return; | 
| +  IDB_TRACE1("IndexedDBDatabase::Clear", "txn.id", transaction->id()); | 
| DCHECK_NE(transaction->mode(), blink::WebIDBTransactionModeReadOnly); | 
|  | 
| if (!ValidateObjectStoreId(object_store_id)) | 
| @@ -1935,15 +1892,15 @@ void IndexedDBDatabase::VersionChangeOperation( | 
| metadata_.version)); | 
| metadata_.version = version; | 
|  | 
| -  active_request_->UpgradeTransactionStarted(old_version); | 
| +  active_request_->UpgradeTransactionStarted(old_version, transaction); | 
| } | 
|  | 
| void IndexedDBDatabase::TransactionFinished(IndexedDBTransaction* transaction, | 
| bool committed) { | 
| -  IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", id()); | 
| -  DCHECK(transactions_.find(transaction->id()) != transactions_.end()); | 
| -  DCHECK_EQ(transactions_[transaction->id()], transaction); | 
| -  transactions_.erase(transaction->id()); | 
| +  IDB_TRACE1("IndexedDBTransaction::TransactionFinished", "txn.id", | 
| +             transaction->id()); | 
| +  --transaction_count_; | 
| +  DCHECK_LE(0, transaction_count_); | 
|  | 
| // This may be an unrelated transaction finishing while waiting for | 
| // connections to close, or the actual upgrade transaction from an active | 
| @@ -2006,27 +1963,22 @@ IndexedDBTransaction* IndexedDBDatabase::CreateTransaction( | 
| blink::WebIDBTransactionMode mode) { | 
| IDB_TRACE1("IndexedDBDatabase::CreateTransaction", "txn.id", transaction_id); | 
| DCHECK(connections_.count(connection)); | 
| -  DCHECK(transactions_.find(transaction_id) == transactions_.end()); | 
| -  if (transactions_.find(transaction_id) != transactions_.end()) | 
| -    return nullptr; | 
|  | 
| UMA_HISTOGRAM_COUNTS_1000( | 
| "WebCore.IndexedDB.Database.OutstandingTransactionCount", | 
| -      transactions_.size()); | 
| - | 
| -  // The transaction will add itself to this database's coordinator, which | 
| -  // manages the lifetime of the object. | 
| -  IndexedDBTransaction* transaction = | 
| -      IndexedDBClassFactory::Get()->CreateIndexedDBTransaction( | 
| -          transaction_id, connection->GetWeakPtr(), | 
| -          std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), | 
| -          mode, new IndexedDBBackingStore::Transaction(backing_store_.get())); | 
| +      transaction_count_); | 
| + | 
| +  IndexedDBTransaction* transaction = connection->CreateTransaction( | 
| +      transaction_id, | 
| +      std::set<int64_t>(object_store_ids.begin(), object_store_ids.end()), mode, | 
| +      new IndexedDBBackingStore::Transaction(backing_store_.get())); | 
| TransactionCreated(transaction); | 
| return transaction; | 
| } | 
|  | 
| void IndexedDBDatabase::TransactionCreated(IndexedDBTransaction* transaction) { | 
| -  transactions_[transaction->id()] = transaction; | 
| +  transaction_count_++; | 
| +  transaction_coordinator_.DidCreateTransaction(transaction); | 
| } | 
|  | 
| void IndexedDBDatabase::OpenConnection( | 
| @@ -2066,15 +2018,8 @@ void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) { | 
| // happen if the close is requested by the connection itself as the | 
| // front-end defers the close until all transactions are complete, but can | 
| // occur on process termination or forced close. | 
| -  { | 
| -    auto transactions(transactions_); | 
| -    for (const auto& it : transactions) { | 
| -      if (it.second->callbacks() == connection->callbacks()) | 
| -        it.second->Abort( | 
| -            IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 
| -                                   "Connection is closing.")); | 
| -    } | 
| -  } | 
| +  connection->AbortAllTransactions(IndexedDBDatabaseError( | 
| +      blink::WebIDBDatabaseExceptionUnknownError, "Connection is closing.")); | 
|  | 
| // Abort transactions before removing the connection; aborting may complete | 
| // an upgrade, and thus allow the next open/delete requests to proceed. The | 
| @@ -2091,7 +2036,6 @@ void IndexedDBDatabase::Close(IndexedDBConnection* connection, bool forced) { | 
| // If there are no more connections (current, active, or pending), tell the | 
| // factory to clean us up. | 
| if (connections_.empty() && !active_request_ && pending_requests_.empty()) { | 
| -    DCHECK(transactions_.empty()); | 
| backing_store_ = nullptr; | 
| factory_->ReleaseDatabase(identifier_, forced); | 
| } | 
|  |