| Index: content/browser/indexed_db/indexed_db_backing_store.cc
|
| diff --git a/content/browser/indexed_db/indexed_db_backing_store.cc b/content/browser/indexed_db/indexed_db_backing_store.cc
|
| index e09458913785c85a1b5e963db68819147f48c3a4..13b01cca70dfa6dde19f1ebcc9bcecddd824cfad 100644
|
| --- a/content/browser/indexed_db/indexed_db_backing_store.cc
|
| +++ b/content/browser/indexed_db/indexed_db_backing_store.cc
|
| @@ -4066,8 +4066,10 @@ IndexedDBBackingStore::OpenIndexCursor(
|
|
|
| IndexedDBBackingStore::Transaction::Transaction(
|
| IndexedDBBackingStore* backing_store)
|
| - : backing_store_(backing_store), database_id_(-1), committing_(false) {
|
| -}
|
| + : backing_store_(backing_store),
|
| + database_id_(-1),
|
| + committing_(false),
|
| + ptr_factory_(this) {}
|
|
|
| IndexedDBBackingStore::Transaction::~Transaction() {
|
| DCHECK(!committing_);
|
| @@ -4341,22 +4343,27 @@ leveldb::Status IndexedDBBackingStore::Transaction::CommitPhaseTwo() {
|
| class IndexedDBBackingStore::Transaction::BlobWriteCallbackWrapper
|
| : public IndexedDBBackingStore::BlobWriteCallback {
|
| public:
|
| - BlobWriteCallbackWrapper(IndexedDBBackingStore::Transaction* transaction,
|
| - scoped_refptr<BlobWriteCallback> callback)
|
| - : transaction_(transaction), callback_(callback) {}
|
| + BlobWriteCallbackWrapper(
|
| + base::WeakPtr<IndexedDBBackingStore::Transaction> transaction,
|
| + void* tracing_end_ptr,
|
| + scoped_refptr<BlobWriteCallback> callback)
|
| + : transaction_(std::move(transaction)),
|
| + tracing_end_ptr_(tracing_end_ptr),
|
| + callback_(callback) {}
|
| void Run(bool succeeded) override {
|
| IDB_ASYNC_TRACE_END("IndexedDBBackingStore::Transaction::WriteNewBlobs",
|
| - transaction_);
|
| + tracing_end_ptr_);
|
| callback_->Run(succeeded);
|
| - if (succeeded) // Else it's already been deleted during rollback.
|
| - transaction_->chained_blob_writer_ = NULL;
|
| + if (transaction_ && succeeded)
|
| + transaction_->chained_blob_writer_ = nullptr;
|
| }
|
|
|
| private:
|
| ~BlobWriteCallbackWrapper() override {}
|
| friend class base::RefCounted<IndexedDBBackingStore::BlobWriteCallback>;
|
|
|
| - IndexedDBBackingStore::Transaction* transaction_;
|
| + base::WeakPtr<IndexedDBBackingStore::Transaction> transaction_;
|
| + const void* const tracing_end_ptr_;
|
| scoped_refptr<BlobWriteCallback> callback_;
|
|
|
| DISALLOW_COPY_AND_ASSIGN(BlobWriteCallbackWrapper);
|
| @@ -4379,12 +4386,11 @@ void IndexedDBBackingStore::Transaction::WriteNewBlobs(
|
| transaction_->Put(blob_entry_iter.first.Encode(),
|
| &blob_entry_iter.second);
|
| }
|
| - // Creating the writer will start it going asynchronously.
|
| - chained_blob_writer_ =
|
| - new ChainedBlobWriterImpl(database_id_,
|
| - backing_store_,
|
| - new_files_to_write,
|
| - new BlobWriteCallbackWrapper(this, callback));
|
| + // Creating the writer will start it going asynchronously. The transaction
|
| + // can be destructed before the callback is triggered.
|
| + chained_blob_writer_ = new ChainedBlobWriterImpl(
|
| + database_id_, backing_store_, new_files_to_write,
|
| + new BlobWriteCallbackWrapper(ptr_factory_.GetWeakPtr(), this, callback));
|
| }
|
|
|
| void IndexedDBBackingStore::Transaction::Rollback() {
|
| @@ -4399,7 +4405,7 @@ void IndexedDBBackingStore::Transaction::Rollback() {
|
| chained_blob_writer_->Abort();
|
| chained_blob_writer_ = NULL;
|
| }
|
| - if (transaction_.get() == NULL)
|
| + if (!transaction_)
|
| return;
|
| transaction_->Rollback();
|
| transaction_ = NULL;
|
|
|