| 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
|
| deleted file mode 100644
|
| index 406eb5d3e7f2460cc0a85cc3fcf17aa013370555..0000000000000000000000000000000000000000
|
| --- a/content/browser/indexed_db/indexed_db_transaction.cc
|
| +++ /dev/null
|
| @@ -1,308 +0,0 @@
|
| -// Copyright (c) 2013 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "content/browser/indexed_db/indexed_db_transaction.h"
|
| -
|
| -#include <vector>
|
| -#include "base/logging.h"
|
| -#include "base/utf_string_conversions.h"
|
| -#include "content/browser/indexed_db/indexed_db_backing_store.h"
|
| -#include "content/browser/indexed_db/indexed_db_cursor_impl.h"
|
| -#include "content/browser/indexed_db/indexed_db_database_callbacks_wrapper.h"
|
| -#include "content/browser/indexed_db/indexed_db_database_impl.h"
|
| -#include "content/browser/indexed_db/indexed_db_tracing.h"
|
| -#include "content/browser/indexed_db/indexed_db_transaction_coordinator.h"
|
| -#include "third_party/WebKit/Source/Platform/chromium/public/WebIDBDatabaseException.h"
|
| -
|
| -namespace content {
|
| -
|
| -IndexedDBTransaction::TaskQueue::TaskQueue() {}
|
| -IndexedDBTransaction::TaskQueue::~TaskQueue() { clear(); }
|
| -
|
| -void IndexedDBTransaction::TaskQueue::clear() {
|
| - while (!queue_.empty())
|
| - scoped_ptr<Operation> task(pop());
|
| -}
|
| -
|
| -scoped_ptr<IndexedDBTransaction::Operation>
|
| -IndexedDBTransaction::TaskQueue::pop() {
|
| - DCHECK(!queue_.empty());
|
| - scoped_ptr<Operation> task(queue_.front());
|
| - queue_.pop();
|
| - return task.Pass();
|
| -}
|
| -
|
| -IndexedDBTransaction::TaskStack::TaskStack() {}
|
| -IndexedDBTransaction::TaskStack::~TaskStack() { clear(); }
|
| -
|
| -void IndexedDBTransaction::TaskStack::clear() {
|
| - while (!stack_.empty())
|
| - scoped_ptr<Operation> task(pop());
|
| -}
|
| -
|
| -scoped_ptr<IndexedDBTransaction::Operation>
|
| -IndexedDBTransaction::TaskStack::pop() {
|
| - DCHECK(!stack_.empty());
|
| - scoped_ptr<Operation> task(stack_.top());
|
| - stack_.pop();
|
| - return task.Pass();
|
| -}
|
| -
|
| -scoped_refptr<IndexedDBTransaction> IndexedDBTransaction::Create(
|
| - int64 id,
|
| - scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks,
|
| - const std::vector<int64>& object_store_ids,
|
| - indexed_db::TransactionMode mode,
|
| - IndexedDBDatabaseImpl* database) {
|
| - std::set<int64> object_store_hash_set;
|
| - for (size_t i = 0; i < object_store_ids.size(); ++i)
|
| - object_store_hash_set.insert(object_store_ids[i]);
|
| -
|
| - return make_scoped_refptr(new IndexedDBTransaction(
|
| - id, callbacks, object_store_hash_set, mode, database));
|
| -}
|
| -
|
| -IndexedDBTransaction::IndexedDBTransaction(
|
| - int64 id,
|
| - scoped_refptr<IndexedDBDatabaseCallbacksWrapper> callbacks,
|
| - const std::set<int64>& object_store_ids,
|
| - indexed_db::TransactionMode mode,
|
| - IndexedDBDatabaseImpl* database)
|
| - : id_(id),
|
| - object_store_ids_(object_store_ids),
|
| - mode_(mode),
|
| - state_(UNUSED),
|
| - commit_pending_(false),
|
| - callbacks_(callbacks),
|
| - database_(database),
|
| - transaction_(database->BackingStore().get()),
|
| - pending_preemptive_events_(0) {
|
| - 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.
|
| - DCHECK_EQ(state_, FINISHED);
|
| - DCHECK(preemptive_task_queue_.empty());
|
| - DCHECK(task_queue_.empty());
|
| - DCHECK(abort_task_stack_.empty());
|
| -}
|
| -
|
| -void IndexedDBTransaction::ScheduleTask(IndexedDBDatabase::TaskType type,
|
| - Operation* task,
|
| - Operation* abort_task) {
|
| - if (state_ == FINISHED)
|
| - return;
|
| -
|
| - if (type == IndexedDBDatabase::NORMAL_TASK)
|
| - task_queue_.push(task);
|
| - else
|
| - preemptive_task_queue_.push(task);
|
| -
|
| - if (abort_task)
|
| - abort_task_stack_.push(abort_task);
|
| -
|
| - if (state_ == UNUSED)
|
| - Start();
|
| - else if (state_ == RUNNING && !task_timer_.IsRunning())
|
| - task_timer_.Start(FROM_HERE,
|
| - base::TimeDelta::FromSeconds(0),
|
| - this,
|
| - &IndexedDBTransaction::TaskTimerFired);
|
| -}
|
| -
|
| -void IndexedDBTransaction::Abort() {
|
| - Abort(IndexedDBDatabaseError::Create(
|
| - WebKit::WebIDBDatabaseExceptionUnknownError,
|
| - ASCIIToUTF16("Internal error (unknown cause)")));
|
| -}
|
| -
|
| -void IndexedDBTransaction::Abort(scoped_refptr<IndexedDBDatabaseError> error) {
|
| - IDB_TRACE("IndexedDBTransaction::abort");
|
| - if (state_ == FINISHED)
|
| - return;
|
| -
|
| - bool was_running = state_ == RUNNING;
|
| -
|
| - // The last reference to this object may be released while performing the
|
| - // abort steps below. We therefore take a self reference to keep ourselves
|
| - // alive while executing this method.
|
| - scoped_refptr<IndexedDBTransaction> protect(this);
|
| -
|
| - state_ = FINISHED;
|
| - task_timer_.Stop();
|
| -
|
| - if (was_running)
|
| - transaction_.Rollback();
|
| -
|
| - // Run the abort tasks, if any.
|
| - while (!abort_task_stack_.empty()) {
|
| - scoped_ptr<Operation> task(abort_task_stack_.pop());
|
| - task->Perform(0);
|
| - }
|
| - preemptive_task_queue_.clear();
|
| - task_queue_.clear();
|
| -
|
| - // 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);
|
| -#ifndef NDEBUG
|
| - DCHECK(!database_->transaction_coordinator().IsActive(this));
|
| -#endif
|
| - database_->TransactionFinished(this);
|
| -
|
| - if (callbacks_)
|
| - callbacks_->OnAbort(id_, error);
|
| -
|
| - database_->TransactionFinishedAndAbortFired(this);
|
| -
|
| - database_ = NULL;
|
| -}
|
| -
|
| -bool IndexedDBTransaction::IsTaskQueueEmpty() const {
|
| - return preemptive_task_queue_.empty() && task_queue_.empty();
|
| -}
|
| -
|
| -bool IndexedDBTransaction::HasPendingTasks() const {
|
| - return pending_preemptive_events_ || !IsTaskQueueEmpty();
|
| -}
|
| -
|
| -void IndexedDBTransaction::RegisterOpenCursor(IndexedDBCursorImpl* cursor) {
|
| - open_cursors_.insert(cursor);
|
| -}
|
| -
|
| -void IndexedDBTransaction::UnregisterOpenCursor(IndexedDBCursorImpl* cursor) {
|
| - open_cursors_.erase(cursor);
|
| -}
|
| -
|
| -void IndexedDBTransaction::Run() {
|
| - // TransactionCoordinator has started this transaction. Schedule a timer
|
| - // to process the first task.
|
| - DCHECK(state_ == START_PENDING || state_ == RUNNING);
|
| - DCHECK(!task_timer_.IsRunning());
|
| -
|
| - task_timer_.Start(FROM_HERE,
|
| - base::TimeDelta::FromSeconds(0),
|
| - this,
|
| - &IndexedDBTransaction::TaskTimerFired);
|
| -}
|
| -
|
| -void IndexedDBTransaction::Start() {
|
| - DCHECK_EQ(state_, UNUSED);
|
| -
|
| - state_ = START_PENDING;
|
| - database_->transaction_coordinator().DidStartTransaction(this);
|
| - database_->TransactionStarted(this);
|
| -}
|
| -
|
| -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)
|
| - return;
|
| -
|
| - DCHECK(state_ == UNUSED || state_ == RUNNING);
|
| - commit_pending_ = true;
|
| -
|
| - // Front-end has requested a commit, but there may be tasks like
|
| - // create_index which are considered synchronous by the front-end
|
| - // but are processed asynchronously.
|
| - 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.
|
| - if (!unused)
|
| - database_->transaction_coordinator().DidFinishTransaction(this);
|
| - database_->TransactionFinished(this);
|
| -
|
| - if (committed) {
|
| - callbacks_->OnComplete(id_);
|
| - database_->TransactionFinishedAndCompleteFired(this);
|
| - } else {
|
| - callbacks_->OnAbort(
|
| - id_,
|
| - IndexedDBDatabaseError::Create(
|
| - WebKit::WebIDBDatabaseExceptionUnknownError,
|
| - ASCIIToUTF16("Internal error committing transaction.")));
|
| - database_->TransactionFinishedAndAbortFired(this);
|
| - }
|
| -
|
| - database_ = NULL;
|
| -}
|
| -
|
| -void IndexedDBTransaction::TaskTimerFired() {
|
| - IDB_TRACE("IndexedDBTransaction::task_timer_fired");
|
| - DCHECK(!IsTaskQueueEmpty());
|
| -
|
| - if (state_ == START_PENDING) {
|
| - transaction_.begin();
|
| - state_ = RUNNING;
|
| - }
|
| -
|
| - // The last reference to this object may be released while performing the
|
| - // tasks. Take take a self reference to keep this object alive so that
|
| - // the loop termination conditions can be checked.
|
| - scoped_refptr<IndexedDBTransaction> protect(this);
|
| -
|
| - TaskQueue* task_queue =
|
| - pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_;
|
| - while (!task_queue->empty() && state_ != FINISHED) {
|
| - DCHECK_EQ(state_, RUNNING);
|
| - scoped_ptr<Operation> task(task_queue->pop());
|
| - task->Perform(this);
|
| -
|
| - // Event itself may change which queue should be processed next.
|
| - task_queue =
|
| - pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_;
|
| - }
|
| -
|
| - // 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_)
|
| - Commit();
|
| -}
|
| -
|
| -void IndexedDBTransaction::CloseOpenCursors() {
|
| - for (std::set<IndexedDBCursorImpl*>::iterator i = open_cursors_.begin();
|
| - i != open_cursors_.end();
|
| - ++i)
|
| - (*i)->Close();
|
| - open_cursors_.clear();
|
| -}
|
| -
|
| -} // namespace content
|
|
|