Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "content/browser/indexed_db/indexed_db_transaction.h" | 5 #include "content/browser/indexed_db/indexed_db_transaction.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/location.h" | 8 #include "base/location.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | |
| 10 #include "base/single_thread_task_runner.h" | 11 #include "base/single_thread_task_runner.h" |
| 12 #include "base/stl_util.h" | |
| 11 #include "base/strings/utf_string_conversions.h" | 13 #include "base/strings/utf_string_conversions.h" |
| 12 #include "base/threading/thread_task_runner_handle.h" | 14 #include "base/threading/thread_task_runner_handle.h" |
| 13 #include "content/browser/indexed_db/indexed_db_backing_store.h" | 15 #include "content/browser/indexed_db/indexed_db_backing_store.h" |
| 14 #include "content/browser/indexed_db/indexed_db_cursor.h" | 16 #include "content/browser/indexed_db/indexed_db_cursor.h" |
| 15 #include "content/browser/indexed_db/indexed_db_database.h" | 17 #include "content/browser/indexed_db/indexed_db_database.h" |
| 16 #include "content/browser/indexed_db/indexed_db_database_callbacks.h" | 18 #include "content/browser/indexed_db/indexed_db_database_callbacks.h" |
| 19 #include "content/browser/indexed_db/indexed_db_observer.h" | |
| 17 #include "content/browser/indexed_db/indexed_db_tracing.h" | 20 #include "content/browser/indexed_db/indexed_db_tracing.h" |
| 18 #include "content/browser/indexed_db/indexed_db_transaction_coordinator.h" | 21 #include "content/browser/indexed_db/indexed_db_transaction_coordinator.h" |
| 19 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" | 22 #include "third_party/WebKit/public/platform/modules/indexeddb/WebIDBDatabaseExc eption.h" |
| 20 #include "third_party/leveldatabase/env_chromium.h" | 23 #include "third_party/leveldatabase/env_chromium.h" |
| 21 | 24 |
| 22 namespace content { | 25 namespace content { |
| 23 | 26 |
| 24 namespace { | 27 namespace { |
| 25 | 28 |
| 26 const int64_t kInactivityTimeoutPeriodSeconds = 60; | 29 const int64_t kInactivityTimeoutPeriodSeconds = 60; |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 59 | 62 |
| 60 IndexedDBTransaction::Operation IndexedDBTransaction::TaskStack::pop() { | 63 IndexedDBTransaction::Operation IndexedDBTransaction::TaskStack::pop() { |
| 61 DCHECK(!stack_.empty()); | 64 DCHECK(!stack_.empty()); |
| 62 Operation task(stack_.top()); | 65 Operation task(stack_.top()); |
| 63 stack_.pop(); | 66 stack_.pop(); |
| 64 return task; | 67 return task; |
| 65 } | 68 } |
| 66 | 69 |
| 67 IndexedDBTransaction::IndexedDBTransaction( | 70 IndexedDBTransaction::IndexedDBTransaction( |
| 68 int64_t id, | 71 int64_t id, |
| 69 scoped_refptr<IndexedDBDatabaseCallbacks> callbacks, | 72 base::WeakPtr<IndexedDBConnection> connection, |
| 70 const std::set<int64_t>& object_store_ids, | 73 const std::set<int64_t>& object_store_ids, |
| 71 blink::WebIDBTransactionMode mode, | 74 blink::WebIDBTransactionMode mode, |
| 72 IndexedDBDatabase* database, | |
| 73 IndexedDBBackingStore::Transaction* backing_store_transaction) | 75 IndexedDBBackingStore::Transaction* backing_store_transaction) |
| 74 : id_(id), | 76 : id_(id), |
| 75 object_store_ids_(object_store_ids), | 77 object_store_ids_(object_store_ids), |
| 76 mode_(mode), | 78 mode_(mode), |
| 77 used_(false), | 79 used_(false), |
| 78 state_(CREATED), | 80 state_(CREATED), |
| 79 commit_pending_(false), | 81 commit_pending_(false), |
| 80 callbacks_(callbacks), | 82 connection_(std::move(connection)), |
| 81 database_(database), | |
| 82 transaction_(backing_store_transaction), | 83 transaction_(backing_store_transaction), |
| 83 backing_store_transaction_begun_(false), | 84 backing_store_transaction_begun_(false), |
| 84 should_process_queue_(false), | 85 should_process_queue_(false), |
| 85 pending_preemptive_events_(0) { | 86 pending_preemptive_events_(0) { |
| 87 callbacks_ = connection_->callbacks(); | |
| 88 database_ = connection_->database(); | |
| 89 | |
| 86 database_->transaction_coordinator().DidCreateTransaction(this); | 90 database_->transaction_coordinator().DidCreateTransaction(this); |
| 87 | 91 |
| 88 diagnostics_.tasks_scheduled = 0; | 92 diagnostics_.tasks_scheduled = 0; |
| 89 diagnostics_.tasks_completed = 0; | 93 diagnostics_.tasks_completed = 0; |
| 90 diagnostics_.creation_time = base::Time::Now(); | 94 diagnostics_.creation_time = base::Time::Now(); |
| 91 } | 95 } |
| 92 | 96 |
| 93 IndexedDBTransaction::~IndexedDBTransaction() { | 97 IndexedDBTransaction::~IndexedDBTransaction() { |
| 94 // It shouldn't be possible for this object to get deleted until it's either | 98 // It shouldn't be possible for this object to get deleted until it's either |
| 95 // complete or aborted. | 99 // complete or aborted. |
| 96 DCHECK_EQ(state_, FINISHED); | 100 DCHECK_EQ(state_, FINISHED); |
| 97 DCHECK(preemptive_task_queue_.empty()); | 101 DCHECK(preemptive_task_queue_.empty()); |
| 98 DCHECK_EQ(pending_preemptive_events_, 0); | 102 DCHECK_EQ(pending_preemptive_events_, 0); |
| 99 DCHECK(task_queue_.empty()); | 103 DCHECK(task_queue_.empty()); |
| 100 DCHECK(abort_task_stack_.empty()); | 104 DCHECK(abort_task_stack_.empty()); |
| 105 DCHECK(pending_observers_.empty()); | |
| 101 } | 106 } |
| 102 | 107 |
| 103 void IndexedDBTransaction::ScheduleTask(blink::WebIDBTaskType type, | 108 void IndexedDBTransaction::ScheduleTask(blink::WebIDBTaskType type, |
| 104 Operation task) { | 109 Operation task) { |
| 105 DCHECK_NE(state_, COMMITTING); | 110 DCHECK_NE(state_, COMMITTING); |
| 106 if (state_ == FINISHED) | 111 if (state_ == FINISHED) |
| 107 return; | 112 return; |
| 108 | 113 |
| 109 timeout_timer_.Stop(); | 114 timeout_timer_.Stop(); |
| 110 used_ = true; | 115 used_ = true; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 184 #ifndef NDEBUG | 189 #ifndef NDEBUG |
| 185 DCHECK(!database_->transaction_coordinator().IsActive(this)); | 190 DCHECK(!database_->transaction_coordinator().IsActive(this)); |
| 186 #endif | 191 #endif |
| 187 | 192 |
| 188 if (callbacks_.get()) | 193 if (callbacks_.get()) |
| 189 callbacks_->OnAbort(id_, error); | 194 callbacks_->OnAbort(id_, error); |
| 190 | 195 |
| 191 database_->TransactionFinished(this, false); | 196 database_->TransactionFinished(this, false); |
| 192 | 197 |
| 193 database_ = NULL; | 198 database_ = NULL; |
| 199 connection_ = nullptr; | |
| 200 pending_observers_.clear(); | |
| 194 } | 201 } |
| 195 | 202 |
| 196 bool IndexedDBTransaction::IsTaskQueueEmpty() const { | 203 bool IndexedDBTransaction::IsTaskQueueEmpty() const { |
| 197 return preemptive_task_queue_.empty() && task_queue_.empty(); | 204 return preemptive_task_queue_.empty() && task_queue_.empty(); |
| 198 } | 205 } |
| 199 | 206 |
| 200 bool IndexedDBTransaction::HasPendingTasks() const { | 207 bool IndexedDBTransaction::HasPendingTasks() const { |
| 201 return pending_preemptive_events_ || !IsTaskQueueEmpty(); | 208 return pending_preemptive_events_ || !IsTaskQueueEmpty(); |
| 202 } | 209 } |
| 203 | 210 |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 332 // released, and order is critical. | 339 // released, and order is critical. |
| 333 CloseOpenCursors(); | 340 CloseOpenCursors(); |
| 334 transaction_->Reset(); | 341 transaction_->Reset(); |
| 335 | 342 |
| 336 // Transactions must also be marked as completed before the | 343 // Transactions must also be marked as completed before the |
| 337 // front-end is notified, as the transaction completion unblocks | 344 // front-end is notified, as the transaction completion unblocks |
| 338 // operations like closing connections. | 345 // operations like closing connections. |
| 339 database_->transaction_coordinator().DidFinishTransaction(this); | 346 database_->transaction_coordinator().DidFinishTransaction(this); |
| 340 | 347 |
| 341 if (committed) { | 348 if (committed) { |
| 349 // TODO (palakj) : Send Observations to observers | |
| 350 if (!pending_observers_.empty() && connection_) | |
| 351 connection_->ActivatePendingObservers(std::move(pending_observers_)); | |
| 342 abort_task_stack_.clear(); | 352 abort_task_stack_.clear(); |
| 343 { | 353 { |
| 344 IDB_TRACE1( | 354 IDB_TRACE1( |
| 345 "IndexedDBTransaction::CommitPhaseTwo.TransactionCompleteCallbacks", | 355 "IndexedDBTransaction::CommitPhaseTwo.TransactionCompleteCallbacks", |
| 346 "txn.id", id()); | 356 "txn.id", id()); |
| 347 callbacks_->OnComplete(id_); | 357 callbacks_->OnComplete(id_); |
| 348 } | 358 } |
| 349 database_->TransactionFinished(this, true); | 359 database_->TransactionFinished(this, true); |
| 350 } else { | 360 } else { |
| 351 while (!abort_task_stack_.empty()) | 361 while (!abort_task_stack_.empty()) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 438 base::ASCIIToUTF16("Transaction timed out due to inactivity."))); | 448 base::ASCIIToUTF16("Transaction timed out due to inactivity."))); |
| 439 } | 449 } |
| 440 | 450 |
| 441 void IndexedDBTransaction::CloseOpenCursors() { | 451 void IndexedDBTransaction::CloseOpenCursors() { |
| 442 IDB_TRACE1("IndexedDBTransaction::CloseOpenCursors", "txn.id", id()); | 452 IDB_TRACE1("IndexedDBTransaction::CloseOpenCursors", "txn.id", id()); |
| 443 for (auto* cursor : open_cursors_) | 453 for (auto* cursor : open_cursors_) |
| 444 cursor->Close(); | 454 cursor->Close(); |
| 445 open_cursors_.clear(); | 455 open_cursors_.clear(); |
| 446 } | 456 } |
| 447 | 457 |
| 458 void IndexedDBTransaction::AddPendingObserver(int32_t observer_id) { | |
| 459 pending_observers_.push_back( | |
| 460 base::WrapUnique(new IndexedDBObserver(observer_id))); | |
| 461 } | |
| 462 | |
| 463 void IndexedDBTransaction::RemovePendingObservers( | |
| 464 const std::vector<int32_t>& pending_observer_ids) { | |
| 465 const auto& it = std::remove_if( | |
| 466 pending_observers_.begin(), pending_observers_.end(), | |
| 467 [&pending_observer_ids](const std::unique_ptr<IndexedDBObserver>& o) { | |
| 468 return ContainsValue(pending_observer_ids, o->id()); | |
| 469 }); | |
| 470 if (it != pending_observers_.end()) | |
|
dmurph
2016/07/06 18:25:10
This code currently removes more than it should, I
palakj1
2016/07/06 18:58:44
remove_if doesn't really erase anything, it simply
dmurph
2016/07/06 19:03:32
Makes sense, I didn't fully read the spec. lgtm
| |
| 471 pending_observers_.erase(it, pending_observers_.end()); | |
| 472 } | |
| 473 | |
| 448 } // namespace content | 474 } // namespace content |
| OLD | NEW |