| 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..7a764c018fac0fec514cb98df7cf691483b4562f 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,43 @@ 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);
|
| + }
|
| + 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())
|
| return;
|
|
|
| DCHECK(!used_ || state_ == STARTED);
|
| @@ -224,6 +255,25 @@ 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);
|
| + state_ = FINISHED;
|
| +
|
| // 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 +284,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 +336,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 +352,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_)
|
| Commit();
|
| }
|
|
|
|
|