Chromium Code Reviews| 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 4f80b83e53290b2d9824b6624aaf72c7af51679b..d9f06780130e3e873f50357740f8bb363cb434f9 100644 |
| --- a/content/browser/indexed_db/indexed_db_backing_store.cc |
| +++ b/content/browser/indexed_db/indexed_db_backing_store.cc |
| @@ -2268,7 +2268,7 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl |
| ++iter_; |
| WriteNextFile(); |
| } else { |
| - callback_->Run(false); |
| + callback_->Run(false, false); |
|
jsbell
2016/11/30 21:30:13
Comment these args, e.g. /* name */
Or maybe cons
dmurph
2016/11/30 23:13:07
Done.
|
| } |
| } |
| @@ -2290,11 +2290,11 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl |
| } |
| if (iter_ == blobs_.end()) { |
| DCHECK(!self_ref_.get()); |
| - callback_->Run(true); |
| + callback_->Run(true, false); |
|
jsbell
2016/11/30 21:30:13
ditto
dmurph
2016/11/30 23:13:07
Done.
|
| return; |
| } else { |
| if (!backing_store_->WriteBlobFile(database_id_, *iter_, this)) { |
| - callback_->Run(false); |
| + callback_->Run(false, false); |
|
jsbell
2016/11/30 21:30:13
ditto
dmurph
2016/11/30 23:13:06
Done.
|
| return; |
| } |
| waiting_for_callback_ = true; |
| @@ -2307,6 +2307,9 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl |
| WriteDescriptorVec::const_iterator iter_; |
| int64_t database_id_; |
| IndexedDBBackingStore* backing_store_; |
| + // Callback result is useless as call stack is no longer transaction's |
| + // operations queue. Errors are instead handled in |
| + // IndexedDBTransaction::BlobWriteComplete. |
| scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback_; |
| std::unique_ptr<FileWriterDelegate> delegate_; |
| bool aborted_; |
| @@ -4045,8 +4048,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_); |
| @@ -4215,7 +4220,7 @@ leveldb::Status IndexedDBBackingStore::Transaction::CommitPhaseOne( |
| // This call will zero out new_blob_entries and new_files_to_write. |
| WriteNewBlobs(&new_blob_entries, &new_files_to_write, callback); |
| } else { |
| - callback->Run(true); |
| + return callback->Run(true, true); |
| } |
| return leveldb::Status::OK(); |
| @@ -4320,22 +4325,29 @@ 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) {} |
| - void Run(bool succeeded) override { |
| + 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) {} |
| + leveldb::Status Run(bool succeeded, bool sync_call) override { |
| + DCHECK(!sync_call); |
| IDB_ASYNC_TRACE_END("IndexedDBBackingStore::Transaction::WriteNewBlobs", |
| - transaction_); |
| - callback_->Run(succeeded); |
| - if (succeeded) // Else it's already been deleted during rollback. |
| - transaction_->chained_blob_writer_ = NULL; |
| + tracing_end_ptr_); |
| + leveldb::Status result = callback_->Run(succeeded, false); |
|
jsbell
2016/11/30 21:30:13
sync_call ?
dmurph
2016/11/30 23:13:06
Done.
|
| + if (transaction_ && succeeded) |
| + transaction_->chained_blob_writer_ = nullptr; |
| + return result; |
| } |
| 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); |
| @@ -4358,12 +4370,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() { |
| @@ -4378,7 +4389,7 @@ void IndexedDBBackingStore::Transaction::Rollback() { |
| chained_blob_writer_->Abort(); |
| chained_blob_writer_ = NULL; |
| } |
| - if (transaction_.get() == NULL) |
| + if (!transaction_) |
| return; |
| transaction_->Rollback(); |
| transaction_ = NULL; |