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..56b28304515f33884a44b960403ffe7b95a766fe 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(BlobWriteResult::FAIILURE_ASYNC); |
} |
} |
@@ -2290,11 +2290,11 @@ class IndexedDBBackingStore::Transaction::ChainedBlobWriterImpl |
} |
if (iter_ == blobs_.end()) { |
DCHECK(!self_ref_.get()); |
- callback_->Run(true); |
+ callback_->Run(BlobWriteResult::SUCCESS_ASYNC); |
return; |
} else { |
if (!backing_store_->WriteBlobFile(database_id_, *iter_, this)) { |
- callback_->Run(false); |
+ callback_->Run(BlobWriteResult::FAIILURE_ASYNC); |
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(BlobWriteResult::SUCCESS_SYNC); |
} |
return leveldb::Status::OK(); |
@@ -4320,22 +4325,36 @@ 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(BlobWriteResult result) override { |
+ DCHECK_NE(result, BlobWriteResult::SUCCESS_SYNC); |
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 leveldb_result = callback_->Run(result); |
+ switch (result) { |
+ case IndexedDBBackingStore::BlobWriteResult::FAIILURE_ASYNC: |
cmumford
2016/12/01 19:14:50
Since this is a nested class inside of IndexedDBBa
dmurph
2016/12/01 21:12:23
Done.
|
+ break; |
+ case IndexedDBBackingStore::BlobWriteResult::SUCCESS_ASYNC: |
+ case IndexedDBBackingStore::BlobWriteResult::SUCCESS_SYNC: |
+ if (transaction_) |
+ transaction_->chained_blob_writer_ = nullptr; |
+ break; |
+ } |
+ return leveldb_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 +4377,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 +4396,7 @@ void IndexedDBBackingStore::Transaction::Rollback() { |
chained_blob_writer_->Abort(); |
chained_blob_writer_ = NULL; |
} |
- if (transaction_.get() == NULL) |
+ if (!transaction_) |
return; |
transaction_->Rollback(); |
transaction_ = NULL; |