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

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

Issue 2472213003: [IndexedDB] Refactoring to remove ref ptrs and host transaction ids. (Closed)
Patch Set: comments Created 4 years 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 40de131f4f3045af60cc4d11f519ba1286d0fb93..064d5a0a50d9c321fe758e624fdceef84a2aea62 100644
--- a/content/browser/indexed_db/indexed_db_transaction.cc
+++ b/content/browser/indexed_db/indexed_db_transaction.cc
@@ -30,7 +30,9 @@ const int64_t kInactivityTimeoutPeriodSeconds = 60;
// Helper for posting a task to call IndexedDBTransaction::Commit when we know
// the transaction had no requests and therefore the commit must succeed.
-void CommitUnused(scoped_refptr<IndexedDBTransaction> transaction) {
+void CommitUnused(base::WeakPtr<IndexedDBTransaction> transaction) {
+ if (!transaction)
+ return;
leveldb::Status status = transaction->Commit();
DCHECK(status.ok());
}
@@ -85,7 +87,7 @@ IndexedDBTransaction::AbortOperation IndexedDBTransaction::TaskStack::pop() {
IndexedDBTransaction::IndexedDBTransaction(
int64_t id,
- base::WeakPtr<IndexedDBConnection> connection,
+ IndexedDBConnection* connection,
const std::set<int64_t>& object_store_ids,
blink::WebIDBTransactionMode mode,
IndexedDBBackingStore::Transaction* backing_store_transaction)
@@ -93,12 +95,11 @@ IndexedDBTransaction::IndexedDBTransaction(
object_store_ids_(object_store_ids),
mode_(mode),
connection_(std::move(connection)),
- transaction_(backing_store_transaction) {
+ transaction_(backing_store_transaction),
+ ptr_factory_(this) {
callbacks_ = connection_->callbacks();
database_ = connection_->database();
- database_->transaction_coordinator().DidCreateTransaction(this);
-
diagnostics_.tasks_scheduled = 0;
diagnostics_.tasks_completed = 0;
diagnostics_.creation_time = base::Time::Now();
@@ -112,7 +113,6 @@ IndexedDBTransaction::~IndexedDBTransaction() {
DCHECK_EQ(pending_preemptive_events_, 0);
DCHECK(task_queue_.empty());
DCHECK(abort_task_stack_.empty());
- DCHECK(pending_observers_.empty());
DCHECK(!processing_event_queue_);
}
@@ -152,7 +152,8 @@ void IndexedDBTransaction::RunTasksIfStarted() {
should_process_queue_ = true;
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&IndexedDBTransaction::ProcessTaskQueue, this));
+ FROM_HERE, base::Bind(&IndexedDBTransaction::ProcessTaskQueue,
+ ptr_factory_.GetWeakPtr()));
}
void IndexedDBTransaction::Abort() {
@@ -162,14 +163,10 @@ void IndexedDBTransaction::Abort() {
void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) {
IDB_TRACE1("IndexedDBTransaction::Abort", "txn.id", id());
+ DCHECK(!processing_event_queue_);
if (state_ == FINISHED)
return;
- // 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);
-
timeout_timer_.Stop();
state_ = FINISHED;
@@ -202,13 +199,12 @@ void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) {
#endif
if (callbacks_.get())
- callbacks_->OnAbort(id_, error);
+ callbacks_->OnAbort(*this, error);
database_->TransactionFinished(this, false);
- database_ = NULL;
- connection_ = nullptr;
- pending_observers_.clear();
+ // RemoveTransaction will delete |this|.
+ connection_->RemoveTransaction(id_);
}
bool IndexedDBTransaction::IsTaskQueueEmpty() const {
@@ -239,7 +235,7 @@ void IndexedDBTransaction::Start() {
// front-end previously requested a commit; do the commit now, but not
// re-entrantly as that may renter the coordinator.
base::ThreadTaskRunnerHandle::Get()->PostTask(
- FROM_HERE, base::Bind(&CommitUnused, make_scoped_refptr(this)));
+ FROM_HERE, base::Bind(&CommitUnused, ptr_factory_.GetWeakPtr()));
}
return;
}
@@ -250,35 +246,50 @@ void IndexedDBTransaction::Start() {
class BlobWriteCallbackImpl : public IndexedDBBackingStore::BlobWriteCallback {
public:
explicit BlobWriteCallbackImpl(
- scoped_refptr<IndexedDBTransaction> transaction)
- : transaction_(transaction) {}
- void Run(bool succeeded) override {
- transaction_->BlobWriteComplete(succeeded);
+ base::WeakPtr<IndexedDBTransaction> transaction)
+ : transaction_(std::move(transaction)) {}
+
+ leveldb::Status Run(IndexedDBBackingStore::BlobWriteResult result) override {
+ if (!transaction_)
+ return leveldb::Status::OK();
+ return transaction_->BlobWriteComplete(result);
}
protected:
~BlobWriteCallbackImpl() override {}
private:
- scoped_refptr<IndexedDBTransaction> transaction_;
+ base::WeakPtr<IndexedDBTransaction> transaction_;
};
-void IndexedDBTransaction::BlobWriteComplete(bool success) {
+leveldb::Status IndexedDBTransaction::BlobWriteComplete(
+ IndexedDBBackingStore::BlobWriteResult result) {
IDB_TRACE("IndexedDBTransaction::BlobWriteComplete");
if (state_ == FINISHED) // aborted
- return;
+ return leveldb::Status::OK();
DCHECK_EQ(state_, COMMITTING);
- if (!success) {
- Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError,
- "Failed to write blobs."));
- return;
+ leveldb::Status s = leveldb::Status::OK();
+ // Switch statement to protect against adding new enum values.
+ switch (result) {
+ case IndexedDBBackingStore::BlobWriteResult::FAILURE_ASYNC:
+ Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError,
+ "Failed to write blobs."));
+ return leveldb::Status::OK();
+ case IndexedDBBackingStore::BlobWriteResult::SUCCESS_ASYNC:
+ case IndexedDBBackingStore::BlobWriteResult::SUCCESS_SYNC: {
+ // Save the database as |this| can be destroyed in the next line. We also
+ // make
+ // sure to handle the error if we're not being called synchronously.
+ scoped_refptr<IndexedDBDatabase> database = database_;
+ s = CommitPhaseTwo();
+ if (!s.ok() &&
+ result == IndexedDBBackingStore::BlobWriteResult::SUCCESS_ASYNC)
+ ReportError(s, database, database->factory());
+ break;
+ }
}
- // Save the database as |this| can be destroyed in the next line.
- scoped_refptr<IndexedDBDatabase> database = database_;
- leveldb::Status s = CommitPhaseTwo();
- if (!s.ok())
- ReportError(s, database, database->factory());
+ return s;
}
leveldb::Status IndexedDBTransaction::Commit() {
@@ -315,13 +326,10 @@ leveldb::Status IndexedDBTransaction::Commit() {
s = CommitPhaseTwo();
} else {
scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback(
- new BlobWriteCallbackImpl(this));
+ new BlobWriteCallbackImpl(ptr_factory_.GetWeakPtr()));
// CommitPhaseOne will call the callback synchronously if there are no blobs
// to write.
s = transaction_->CommitPhaseOne(callback);
- if (!s.ok())
- Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError,
- "Error processing blob journal."));
}
return s;
@@ -334,11 +342,6 @@ leveldb::Status 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.
- scoped_refptr<IndexedDBTransaction> protect(this);
-
state_ = FINISHED;
leveldb::Status s;
@@ -375,7 +378,7 @@ leveldb::Status IndexedDBTransaction::CommitPhaseTwo() {
IDB_TRACE1(
"IndexedDBTransaction::CommitPhaseTwo.TransactionCompleteCallbacks",
"txn.id", id());
- callbacks_->OnComplete(id_);
+ callbacks_->OnComplete(*this);
}
if (!pending_observers_.empty() && connection_) {
connection_->ActivatePendingObservers(std::move(pending_observers_));
@@ -383,6 +386,9 @@ leveldb::Status IndexedDBTransaction::CommitPhaseTwo() {
}
database_->TransactionFinished(this, true);
+ // RemoveTransaction will delete |this|.
+ connection_->RemoveTransaction(id_);
+ return s;
} else {
while (!abort_task_stack_.empty())
abort_task_stack_.pop().Run();
@@ -396,12 +402,9 @@ leveldb::Status IndexedDBTransaction::CommitPhaseTwo() {
error = IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError,
"Internal error committing transaction.");
}
- callbacks_->OnAbort(id_, error);
-
+ callbacks_->OnAbort(*this, error);
database_->TransactionFinished(this, false);
}
-
- database_ = NULL;
return s;
}
@@ -424,11 +427,6 @@ void IndexedDBTransaction::ProcessTaskQueue() {
backing_store_transaction_begun_ = true;
}
- // 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) {
@@ -441,8 +439,7 @@ void IndexedDBTransaction::ProcessTaskQueue() {
}
if (!result.ok()) {
processing_event_queue_ = false;
- if (!result.ok())
- ReportError(result, database_, database_->factory());
+ ReportError(result, database_, database_->factory());
return;
}
@@ -454,8 +451,9 @@ 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_) {
- leveldb::Status result = Commit();
processing_event_queue_ = false;
+ // This can delete |this|.
+ leveldb::Status result = Commit();
if (!result.ok())
ReportError(result, database_, database_->factory());
return;
@@ -473,8 +471,9 @@ void IndexedDBTransaction::ProcessTaskQueue() {
// never requests further activity. Read-only transactions don't
// block other transactions, so don't time those out.
if (mode_ != blink::WebIDBTransactionModeReadOnly) {
- timeout_timer_.Start(FROM_HERE, GetInactivityTimeout(),
- base::Bind(&IndexedDBTransaction::Timeout, this));
+ timeout_timer_.Start(
+ FROM_HERE, GetInactivityTimeout(),
+ base::Bind(&IndexedDBTransaction::Timeout, ptr_factory_.GetWeakPtr()));
}
processing_event_queue_ = false;
}

Powered by Google App Engine
This is Rietveld 408576698