Chromium Code Reviews| Index: content/browser/indexed_db/indexed_db_transaction.cc |
| diff --git a/content/browser/indexed_db/indexed_db_transaction.cc b/content/browser/indexed_db/indexed_db_transaction.cc |
| index 28f8378f54dfc022e126cbb8897491509dca52c1..5dc02bc2c7b2547e0f23332a002a1ec043685c51 100644 |
| --- a/content/browser/indexed_db/indexed_db_transaction.cc |
| +++ b/content/browser/indexed_db/indexed_db_transaction.cc |
| @@ -60,6 +60,7 @@ IndexedDBTransaction::IndexedDBTransaction( |
| used_(false), |
| state_(CREATED), |
| commit_pending_(false), |
| + blob_write_success_(false), |
| callbacks_(callbacks), |
| database_(database), |
| transaction_(database->backing_store()), |
| @@ -95,7 +96,7 @@ void IndexedDBTransaction::ScheduleTask(Operation task, Operation abort_task) { |
| void IndexedDBTransaction::ScheduleTask(IndexedDBDatabase::TaskType type, |
| Operation task) { |
| - if (state_ == FINISHED) |
| + if (IsStatePastRunning()) |
| return; |
| used_ = true; |
| @@ -206,13 +207,37 @@ void IndexedDBTransaction::Start() { |
| RunTasksIfStarted(); |
| } |
| +class BlobWriteCallbackImpl : public IndexedDBBackingStore::BlobWriteCallback { |
| + public: |
| + BlobWriteCallbackImpl(scoped_refptr<IndexedDBTransaction> transaction) |
| + : transaction_(transaction) {} |
| + virtual ~BlobWriteCallbackImpl() {} |
| + virtual void didSucceed() { transaction_->BlobWriteComplete(true); } |
|
jsbell
2013/12/20 00:44:20
Nit: Chromium naming style
ericu
2014/02/20 00:50:29
Done.
|
| + virtual void didFail() { transaction_->BlobWriteComplete(false); } |
| + |
| + private: |
| + scoped_refptr<IndexedDBTransaction> transaction_; |
| +}; |
| + |
| +void IndexedDBTransaction::BlobWriteComplete(bool success) { |
| + IDB_TRACE("IndexedDBTransaction::BlobWriteComplete"); |
| + if (state_ == FINISHED) // aborted |
| + return; |
| + DCHECK_EQ(state_, COMMITTING); |
| + if (success) |
| + CommitPhaseTwo(); |
| + else |
| + Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError, |
| + "Failed to write blobs.")); |
| +} |
| + |
| void IndexedDBTransaction::Commit() { |
| IDB_TRACE("IndexedDBTransaction::Commit"); |
| // In multiprocess ports, front-end may have requested a commit but |
| // an abort has already been initiated asynchronously by the |
| // back-end. |
| - if (state_ == FINISHED) |
| + if (IsStatePastRunning()) |
|
jsbell
2013/12/20 00:44:20
Can state_ ever be COMMITTING here? The DCHECK(!us
ericu
2014/02/20 00:50:29
You're right that it shouldn't ever happen. Howev
|
| return; |
| DCHECK(!used_ || state_ == STARTED); |
| @@ -224,6 +249,24 @@ void IndexedDBTransaction::Commit() { |
| if (HasPendingTasks()) |
| return; |
| + state_ = COMMITTING; |
| + |
| + if (!used_) |
| + CommitPhaseTwo(); |
| + else { |
| + scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback( |
| + new BlobWriteCallbackImpl(this)); |
| + // CommitPhaseOne will call the callback synchronously if there are no blobs |
| + // to write. |
| + if (!transaction_.CommitPhaseOne(callback)) |
| + Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError, |
| + "Error processing blob journal.")); |
| + } |
| +} |
| + |
| +void IndexedDBTransaction::CommitPhaseTwo() { |
| + DCHECK_EQ(state_, COMMITTING); |
| + |
| // The last reference to this object may be released while performing the |
| // commit steps below. We therefore take a self reference to keep ourselves |
| // alive while executing this method. |
| @@ -234,7 +277,7 @@ void IndexedDBTransaction::Commit() { |
| state_ = FINISHED; |
| - bool committed = !used_ || transaction_.Commit(); |
| + bool committed = !used_ || transaction_.CommitPhaseTwo(); |
| // Backing store resources (held via cursors) must be released |
| // before script callbacks are fired, as the script callbacks may |
| @@ -286,8 +329,8 @@ void IndexedDBTransaction::ProcessTaskQueue() { |
| TaskQueue* task_queue = |
| pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_; |
| - while (!task_queue->empty() && state_ != FINISHED) { |
| - DCHECK_EQ(STARTED, state_); |
| + while (!task_queue->empty() && !IsStatePastRunning()) { |
| + DCHECK_EQ(state_, STARTED); |
| Operation task(task_queue->pop()); |
| task.Run(this); |
| if (!pending_preemptive_events_) { |
| @@ -302,7 +345,7 @@ void IndexedDBTransaction::ProcessTaskQueue() { |
| // If there are no pending tasks, we haven't already committed/aborted, |
| // and the front-end requested a commit, it is now safe to do so. |
| - if (!HasPendingTasks() && state_ != FINISHED && commit_pending_) |
| + if (!HasPendingTasks() && !IsStatePastRunning() && commit_pending_) |
|
jsbell
2013/12/20 00:44:20
FYI, if you rebase, a test will appear below this
ericu
2014/02/20 00:50:29
Hmm...I'm not sure about that one. It looks like
jsbell
2014/02/20 22:55:50
There shouldn't be; commit_pending_ should only be
|
| Commit(); |
| } |