Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(202)

Unified Diff: content/browser/indexed_db/indexed_db_transaction.cc

Issue 18023022: Blob support for IDB [Chromium] (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: More small build fixes. Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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 457a7807726c54bac4326ca933793ec79c38d5d4..fe29ef70a201cf7af92b160ba4dfad3a8c2b66d1 100644
--- a/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -88,7 +88,7 @@ IndexedDBTransaction::~IndexedDBTransaction() {
void IndexedDBTransaction::ScheduleTask(IndexedDBDatabase::TaskType type,
Operation task) {
- if (state_ == FINISHED)
+ if (IsStatePastStarted())
jsbell 2014/05/28 21:29:15 Since Abort() is synchronous, should be able to DC
ericu 2014/05/28 22:50:42 Does the front end guarantee that we never get any
jsbell 2014/05/28 23:35:18 Yes; the front-end tries to commit when it goes in
return;
timeout_timer_.Stop();
@@ -206,14 +206,43 @@ void IndexedDBTransaction::Start() {
RunTasksIfStarted();
}
+class BlobWriteCallbackImpl : public IndexedDBBackingStore::BlobWriteCallback {
+ public:
+ BlobWriteCallbackImpl(scoped_refptr<IndexedDBTransaction> transaction)
+ : transaction_(transaction) {}
+ virtual void Run(bool succeeded) OVERRIDE {
+ transaction_->BlobWriteComplete(succeeded);
+ }
+
+ protected:
+ virtual ~BlobWriteCallbackImpl() {}
+
+ 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 (IsStatePastStarted()) {
+ DCHECK(state_ == FINISHED);
return;
+ }
DCHECK(!used_ || state_ == STARTED);
commit_pending_ = true;
@@ -224,6 +253,28 @@ 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).ok())
+ Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError,
+ "Error processing blob journal."));
+ }
+}
+
+void IndexedDBTransaction::CommitPhaseTwo() {
+ // Abort may have been called just as the blob write completed.
+ if (state_ == FINISHED)
+ return;
+
+ 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.
@@ -233,7 +284,7 @@ void IndexedDBTransaction::Commit() {
state_ = FINISHED;
- bool committed = !used_ || transaction_->Commit().ok();
+ bool committed = !used_ || transaction_->CommitPhaseTwo().ok();
// Backing store resources (held via cursors) must be released
// before script callbacks are fired, as the script callbacks may
@@ -288,8 +339,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() && !IsStatePastStarted()) {
+ DCHECK_EQ(state_, STARTED);
Operation task(task_queue->pop());
task.Run(this);
if (!pending_preemptive_events_) {
@@ -304,7 +355,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() && !IsStatePastStarted() && commit_pending_) {
jsbell 2014/05/28 21:29:15 Should be able to DCHECK_NE(state_, COMMITTING) ab
ericu 2014/05/28 22:50:42 Is it the case that the only way IsStatePastStarte
jsbell 2014/05/28 23:35:18 Yes. To get into the method we must have tasks, so
ericu 2014/05/28 23:49:13 Removed.
Commit();
return;
}

Powered by Google App Engine
This is Rietveld 408576698