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

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: Merge fixes [builds, untested] Created 7 years, 3 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 ee38d0b914d84be5a3e9dceecde3a027bf60371e..4f3f0adeee3905ee3650ebe7fa79a54d24f5ac19 100644
--- a/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -59,17 +59,21 @@ IndexedDBTransaction::IndexedDBTransaction(
mode_(mode),
state_(UNUSED),
commit_pending_(false),
+ blob_write_success_(false),
callbacks_(callbacks),
database_(database),
transaction_(database->BackingStore().get()),
should_process_queue_(false),
pending_preemptive_events_(0) {
+ fprintf(stderr, "ERICU: IndexedDBTransaction::IndexedDBTransaction(%p).\n",
+ this);
database_->transaction_coordinator().DidCreateTransaction(this);
}
IndexedDBTransaction::~IndexedDBTransaction() {
// It shouldn't be possible for this object to get deleted until it's either
// complete or aborted.
+ fprintf(stderr, "ERICU: IndexedDBTransaction::~IndexedDBTransaction.\n");
DCHECK_EQ(state_, FINISHED);
DCHECK(preemptive_task_queue_.empty());
DCHECK(task_queue_.empty());
@@ -86,7 +90,7 @@ void IndexedDBTransaction::ScheduleTask(Operation task, Operation abort_task) {
void IndexedDBTransaction::ScheduleTask(IndexedDBDatabase::TaskType type,
Operation task) {
- if (state_ == FINISHED)
+ if (IsStatePastRunning())
return;
if (type == IndexedDBDatabase::NORMAL_TASK)
@@ -195,13 +199,29 @@ void IndexedDBTransaction::Start() {
database_->TransactionStarted(this);
}
+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::Commit() {
IDB_TRACE("IndexedDBTransaction::Commit");
+ fprintf(stderr, "ERICU: IndexedDBTransaction::Commit.\n");
// 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(state_ == UNUSED || state_ == RUNNING);
@@ -213,44 +233,19 @@ void IndexedDBTransaction::Commit() {
if (HasPendingTasks())
return;
- // 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.
- scoped_refptr<IndexedDBTransaction> protect(this);
-
- // TODO(jsbell): Run abort tasks if commit fails? http://crbug.com/241843
- abort_task_stack_.clear();
-
bool unused = state_ == UNUSED;
- state_ = FINISHED;
-
- bool committed = unused || transaction_.Commit();
-
- // Backing store resources (held via cursors) must be released
- // before script callbacks are fired, as the script callbacks may
- // release references and allow the backing store itself to be
- // released, and order is critical.
- CloseOpenCursors();
- transaction_.Reset();
-
- // Transactions must also be marked as completed before the
- // front-end is notified, as the transaction completion unblocks
- // operations like closing connections.
- database_->transaction_coordinator().DidFinishTransaction(this);
- database_->TransactionFinished(this);
-
- if (committed) {
- callbacks_->OnComplete(id_);
- database_->TransactionFinishedAndCompleteFired(this);
- } else {
- callbacks_->OnAbort(
- id_,
- IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError,
- "Internal error committing transaction."));
- database_->TransactionFinishedAndAbortFired(this);
+ state_ = COMMITTING;
+
+ if (unused)
+ CommitPhaseTwo(WAS_NOT_USED, DO_COMMIT);
+ 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))
+ CommitPhaseTwo(WAS_USED, SKIP_COMMIT);
}
-
- database_ = NULL;
}
void IndexedDBTransaction::ProcessTaskQueue() {
@@ -275,7 +270,7 @@ void IndexedDBTransaction::ProcessTaskQueue() {
TaskQueue* task_queue =
pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_;
- while (!task_queue->empty() && state_ != FINISHED) {
+ while (!task_queue->empty() && !IsStatePastRunning()) {
DCHECK_EQ(state_, RUNNING);
Operation task(task_queue->pop());
task.Run(this);
@@ -287,10 +282,23 @@ 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();
}
+void IndexedDBTransaction::BlobWriteComplete(bool success)
+{
+ IDB_TRACE("IndexedDBTransaction::BlobWriteComplete");
+ if (state_ == FINISHED) // aborted
+ return;
+ DCHECK_EQ(state_, COMMITTING);
+ if (success)
+ CommitPhaseTwo(WAS_USED, DO_COMMIT);
+ else
+ Abort(IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionDataError,
+ "Failed to write blobs"));
+}
+
void IndexedDBTransaction::CloseOpenCursors() {
for (std::set<IndexedDBCursor*>::iterator i = open_cursors_.begin();
i != open_cursors_.end();
@@ -299,4 +307,49 @@ void IndexedDBTransaction::CloseOpenCursors() {
open_cursors_.clear();
}
+void IndexedDBTransaction::CommitPhaseTwo(TransactionUseState use_state,
+ ShouldSkipCommit skip_commit) {
+ 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.
+ scoped_refptr<IndexedDBTransaction> protect(this);
+
+ // TODO(jsbell): Run abort tasks if commit fails? http://crbug.com/241843
+ abort_task_stack_.clear();
+
+ state_ = FINISHED;
+
+ bool committed = (use_state == WAS_NOT_USED) ||
jsbell 2013/09/13 00:12:21 Seems like use_state and skip_commit effectively h
ericu 2013/11/20 23:05:39 No--we skip_commit if we've failed or aborted, but
+ ((skip_commit == DO_COMMIT) && transaction_.CommitPhaseTwo());
+
+ // Backing store resources (held via cursors) must be released
+ // before script callbacks are fired, as the script callbacks may
+ // release references and allow the backing store itself to be
+ // released, and order is critical.
+ CloseOpenCursors();
+ transaction_.Reset();
+
+ // Transactions must also be marked as completed before the
+ // front-end is notified, as the transaction completion unblocks
+ // operations like closing connections.
+ database_->transaction_coordinator().DidFinishTransaction(this);
+ database_->TransactionFinished(this);
+
+ if (committed) {
+ callbacks_->OnComplete(id_);
+ database_->TransactionFinishedAndCompleteFired(this);
+ } else {
+ callbacks_->OnAbort(
+ id_,
+ IndexedDBDatabaseError(WebKit::WebIDBDatabaseExceptionUnknownError,
+ "Internal error committing transaction."));
+ database_->TransactionFinishedAndAbortFired(this);
+ }
+
+ database_ = NULL;
+}
+
} // namespace content

Powered by Google App Engine
This is Rietveld 408576698