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/memory/ptr_util.h" |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 #include "third_party/leveldatabase/env_chromium.h" | 24 #include "third_party/leveldatabase/env_chromium.h" |
| 25 | 25 |
| 26 namespace content { | 26 namespace content { |
| 27 | 27 |
| 28 namespace { | 28 namespace { |
| 29 | 29 |
| 30 const int64_t kInactivityTimeoutPeriodSeconds = 60; | 30 const int64_t kInactivityTimeoutPeriodSeconds = 60; |
| 31 | 31 |
| 32 // Helper for posting a task to call IndexedDBTransaction::Commit when we know | 32 // Helper for posting a task to call IndexedDBTransaction::Commit when we know |
| 33 // the transaction had no requests and therefore the commit must succeed. | 33 // the transaction had no requests and therefore the commit must succeed. |
| 34 void CommitUnused(scoped_refptr<IndexedDBTransaction> transaction) { | 34 void CommitUnused(base::WeakPtr<IndexedDBTransaction> transaction) { |
| 35 if (!transaction) | |
| 36 return; | |
| 35 leveldb::Status status = transaction->Commit(); | 37 leveldb::Status status = transaction->Commit(); |
| 36 DCHECK(status.ok()); | 38 DCHECK(status.ok()); |
| 37 } | 39 } |
| 38 | 40 |
| 39 } // namespace | 41 } // namespace |
| 40 | 42 |
| 41 IndexedDBTransaction::TaskQueue::TaskQueue() {} | 43 IndexedDBTransaction::TaskQueue::TaskQueue() {} |
| 42 IndexedDBTransaction::TaskQueue::~TaskQueue() { clear(); } | 44 IndexedDBTransaction::TaskQueue::~TaskQueue() { clear(); } |
| 43 | 45 |
| 44 void IndexedDBTransaction::TaskQueue::clear() { | 46 void IndexedDBTransaction::TaskQueue::clear() { |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 63 | 65 |
| 64 IndexedDBTransaction::Operation IndexedDBTransaction::TaskStack::pop() { | 66 IndexedDBTransaction::Operation IndexedDBTransaction::TaskStack::pop() { |
| 65 DCHECK(!stack_.empty()); | 67 DCHECK(!stack_.empty()); |
| 66 Operation task(stack_.top()); | 68 Operation task(stack_.top()); |
| 67 stack_.pop(); | 69 stack_.pop(); |
| 68 return task; | 70 return task; |
| 69 } | 71 } |
| 70 | 72 |
| 71 IndexedDBTransaction::IndexedDBTransaction( | 73 IndexedDBTransaction::IndexedDBTransaction( |
| 72 int64_t id, | 74 int64_t id, |
| 73 base::WeakPtr<IndexedDBConnection> connection, | 75 IndexedDBConnection* connection, |
| 74 const std::set<int64_t>& object_store_ids, | 76 const std::set<int64_t>& object_store_ids, |
| 75 blink::WebIDBTransactionMode mode, | 77 blink::WebIDBTransactionMode mode, |
| 76 IndexedDBBackingStore::Transaction* backing_store_transaction) | 78 IndexedDBBackingStore::Transaction* backing_store_transaction) |
| 77 : id_(id), | 79 : id_(id), |
| 78 object_store_ids_(object_store_ids), | 80 object_store_ids_(object_store_ids), |
| 79 mode_(mode), | 81 mode_(mode), |
| 80 used_(false), | 82 used_(false), |
| 81 state_(CREATED), | 83 state_(CREATED), |
| 82 commit_pending_(false), | 84 commit_pending_(false), |
| 83 connection_(std::move(connection)), | 85 connection_(std::move(connection)), |
| 86 size_(0), | |
| 84 transaction_(backing_store_transaction), | 87 transaction_(backing_store_transaction), |
| 85 backing_store_transaction_begun_(false), | 88 backing_store_transaction_begun_(false), |
| 86 should_process_queue_(false), | 89 should_process_queue_(false), |
| 87 pending_preemptive_events_(0) { | 90 pending_preemptive_events_(0), |
| 91 ptr_factory_(this) { | |
| 88 callbacks_ = connection_->callbacks(); | 92 callbacks_ = connection_->callbacks(); |
| 89 database_ = connection_->database(); | 93 database_ = connection_->database(); |
| 90 | 94 |
| 91 database_->transaction_coordinator().DidCreateTransaction(this); | |
| 92 | |
| 93 diagnostics_.tasks_scheduled = 0; | 95 diagnostics_.tasks_scheduled = 0; |
| 94 diagnostics_.tasks_completed = 0; | 96 diagnostics_.tasks_completed = 0; |
| 95 diagnostics_.creation_time = base::Time::Now(); | 97 diagnostics_.creation_time = base::Time::Now(); |
| 96 } | 98 } |
| 97 | 99 |
| 98 IndexedDBTransaction::~IndexedDBTransaction() { | 100 IndexedDBTransaction::~IndexedDBTransaction() { |
| 99 // It shouldn't be possible for this object to get deleted until it's either | 101 // It shouldn't be possible for this object to get deleted until it's either |
| 100 // complete or aborted. | 102 // complete or aborted. |
| 101 DCHECK_EQ(state_, FINISHED); | 103 DCHECK_EQ(state_, FINISHED); |
| 102 DCHECK(preemptive_task_queue_.empty()); | 104 DCHECK(preemptive_task_queue_.empty()); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 135 // Not started by the coordinator yet. | 137 // Not started by the coordinator yet. |
| 136 if (state_ != STARTED) | 138 if (state_ != STARTED) |
| 137 return; | 139 return; |
| 138 | 140 |
| 139 // A task is already posted. | 141 // A task is already posted. |
| 140 if (should_process_queue_) | 142 if (should_process_queue_) |
| 141 return; | 143 return; |
| 142 | 144 |
| 143 should_process_queue_ = true; | 145 should_process_queue_ = true; |
| 144 base::ThreadTaskRunnerHandle::Get()->PostTask( | 146 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 145 FROM_HERE, base::Bind(&IndexedDBTransaction::ProcessTaskQueue, this)); | 147 FROM_HERE, base::Bind(&IndexedDBTransaction::ProcessTaskQueue, |
| 148 ptr_factory_.GetWeakPtr())); | |
| 146 } | 149 } |
| 147 | 150 |
| 148 void IndexedDBTransaction::Abort() { | 151 void IndexedDBTransaction::Abort() { |
| 149 Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 152 Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
| 150 "Internal error (unknown cause)")); | 153 "Internal error (unknown cause)")); |
| 151 } | 154 } |
| 152 | 155 |
| 153 void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) { | 156 void IndexedDBTransaction::Abort(const IndexedDBDatabaseError& error) { |
| 154 IDB_TRACE1("IndexedDBTransaction::Abort", "txn.id", id()); | 157 IDB_TRACE1("IndexedDBTransaction::Abort", "txn.id", id()); |
| 155 if (state_ == FINISHED) | 158 if (state_ == FINISHED) |
| 156 return; | 159 return; |
| 157 | 160 |
| 158 // The last reference to this object may be released while performing the | |
| 159 // abort steps below. We therefore take a self reference to keep ourselves | |
| 160 // alive while executing this method. | |
| 161 scoped_refptr<IndexedDBTransaction> protect(this); | |
| 162 | |
| 163 timeout_timer_.Stop(); | 161 timeout_timer_.Stop(); |
| 164 | 162 |
| 165 state_ = FINISHED; | 163 state_ = FINISHED; |
| 166 should_process_queue_ = false; | 164 should_process_queue_ = false; |
| 167 | 165 |
| 168 if (backing_store_transaction_begun_) | 166 if (backing_store_transaction_begun_) |
| 169 transaction_->Rollback(); | 167 transaction_->Rollback(); |
| 170 | 168 |
| 171 // Run the abort tasks, if any. | 169 // Run the abort tasks, if any. |
| 172 while (!abort_task_stack_.empty()) | 170 while (!abort_task_stack_.empty()) |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 185 | 183 |
| 186 // Transactions must also be marked as completed before the | 184 // Transactions must also be marked as completed before the |
| 187 // front-end is notified, as the transaction completion unblocks | 185 // front-end is notified, as the transaction completion unblocks |
| 188 // operations like closing connections. | 186 // operations like closing connections. |
| 189 database_->transaction_coordinator().DidFinishTransaction(this); | 187 database_->transaction_coordinator().DidFinishTransaction(this); |
| 190 #ifndef NDEBUG | 188 #ifndef NDEBUG |
| 191 DCHECK(!database_->transaction_coordinator().IsActive(this)); | 189 DCHECK(!database_->transaction_coordinator().IsActive(this)); |
| 192 #endif | 190 #endif |
| 193 | 191 |
| 194 if (callbacks_.get()) | 192 if (callbacks_.get()) |
| 195 callbacks_->OnAbort(id_, error); | 193 callbacks_->OnAbort(*this, error); |
| 196 | 194 |
| 197 database_->TransactionFinished(this, false); | 195 database_->TransactionFinished(this, false); |
| 198 | 196 |
| 199 database_ = NULL; | |
| 200 connection_ = nullptr; | |
| 201 pending_observers_.clear(); | 197 pending_observers_.clear(); |
| 198 // This destroys our object. | |
|
cmumford
2016/11/04 23:33:13
Nit: avoid first person language. Maybe something
dmurph
2016/11/07 20:05:23
Done.
| |
| 199 connection_->EraseTransaction(id_); | |
| 202 } | 200 } |
| 203 | 201 |
| 204 bool IndexedDBTransaction::IsTaskQueueEmpty() const { | 202 bool IndexedDBTransaction::IsTaskQueueEmpty() const { |
| 205 return preemptive_task_queue_.empty() && task_queue_.empty(); | 203 return preemptive_task_queue_.empty() && task_queue_.empty(); |
| 206 } | 204 } |
| 207 | 205 |
| 208 bool IndexedDBTransaction::HasPendingTasks() const { | 206 bool IndexedDBTransaction::HasPendingTasks() const { |
| 209 return pending_preemptive_events_ || !IsTaskQueueEmpty(); | 207 return pending_preemptive_events_ || !IsTaskQueueEmpty(); |
| 210 } | 208 } |
| 211 | 209 |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 222 DCHECK_EQ(CREATED, state_); | 220 DCHECK_EQ(CREATED, state_); |
| 223 state_ = STARTED; | 221 state_ = STARTED; |
| 224 diagnostics_.start_time = base::Time::Now(); | 222 diagnostics_.start_time = base::Time::Now(); |
| 225 | 223 |
| 226 if (!used_) { | 224 if (!used_) { |
| 227 if (commit_pending_) { | 225 if (commit_pending_) { |
| 228 // The transaction has never had requests issued against it, but the | 226 // The transaction has never had requests issued against it, but the |
| 229 // front-end previously requested a commit; do the commit now, but not | 227 // front-end previously requested a commit; do the commit now, but not |
| 230 // re-entrantly as that may renter the coordinator. | 228 // re-entrantly as that may renter the coordinator. |
| 231 base::ThreadTaskRunnerHandle::Get()->PostTask( | 229 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 232 FROM_HERE, base::Bind(&CommitUnused, make_scoped_refptr(this))); | 230 FROM_HERE, base::Bind(&CommitUnused, ptr_factory_.GetWeakPtr())); |
| 233 } | 231 } |
| 234 return; | 232 return; |
| 235 } | 233 } |
| 236 | 234 |
| 237 RunTasksIfStarted(); | 235 RunTasksIfStarted(); |
| 238 } | 236 } |
| 239 | 237 |
| 240 class BlobWriteCallbackImpl : public IndexedDBBackingStore::BlobWriteCallback { | 238 class BlobWriteCallbackImpl : public IndexedDBBackingStore::BlobWriteCallback { |
| 241 public: | 239 public: |
| 242 explicit BlobWriteCallbackImpl( | 240 explicit BlobWriteCallbackImpl( |
| 243 scoped_refptr<IndexedDBTransaction> transaction) | 241 base::WeakPtr<IndexedDBTransaction> transaction) |
| 244 : transaction_(transaction) {} | 242 : transaction_(std::move(transaction)) {} |
| 245 void Run(bool succeeded) override { | 243 void Run(bool succeeded) override { |
| 244 if (!transaction_) | |
| 245 return; | |
| 246 transaction_->BlobWriteComplete(succeeded); | 246 transaction_->BlobWriteComplete(succeeded); |
| 247 } | 247 } |
| 248 | 248 |
| 249 protected: | 249 protected: |
| 250 ~BlobWriteCallbackImpl() override {} | 250 ~BlobWriteCallbackImpl() override {} |
| 251 | 251 |
| 252 private: | 252 private: |
| 253 scoped_refptr<IndexedDBTransaction> transaction_; | 253 base::WeakPtr<IndexedDBTransaction> transaction_; |
| 254 }; | 254 }; |
| 255 | 255 |
| 256 void IndexedDBTransaction::BlobWriteComplete(bool success) { | 256 void IndexedDBTransaction::BlobWriteComplete(bool success) { |
| 257 IDB_TRACE("IndexedDBTransaction::BlobWriteComplete"); | 257 IDB_TRACE("IndexedDBTransaction::BlobWriteComplete"); |
| 258 if (state_ == FINISHED) // aborted | 258 if (state_ == FINISHED) // aborted |
| 259 return; | 259 return; |
| 260 DCHECK_EQ(state_, COMMITTING); | 260 DCHECK_EQ(state_, COMMITTING); |
| 261 if (success) | 261 if (success) |
| 262 CommitPhaseTwo(); | 262 CommitPhaseTwo(); |
| 263 else | 263 else |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 292 if (HasPendingTasks()) | 292 if (HasPendingTasks()) |
| 293 return leveldb::Status::OK(); | 293 return leveldb::Status::OK(); |
| 294 | 294 |
| 295 state_ = COMMITTING; | 295 state_ = COMMITTING; |
| 296 | 296 |
| 297 leveldb::Status s; | 297 leveldb::Status s; |
| 298 if (!used_) { | 298 if (!used_) { |
| 299 s = CommitPhaseTwo(); | 299 s = CommitPhaseTwo(); |
| 300 } else { | 300 } else { |
| 301 scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback( | 301 scoped_refptr<IndexedDBBackingStore::BlobWriteCallback> callback( |
| 302 new BlobWriteCallbackImpl(this)); | 302 new BlobWriteCallbackImpl(ptr_factory_.GetWeakPtr())); |
| 303 // CommitPhaseOne will call the callback synchronously if there are no blobs | 303 // CommitPhaseOne will call the callback synchronously if there are no blobs |
| 304 // to write. | 304 // to write. |
| 305 s = transaction_->CommitPhaseOne(callback); | 305 s = transaction_->CommitPhaseOne(callback); |
| 306 if (!s.ok()) | 306 if (!s.ok()) |
| 307 Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError, | 307 Abort(IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionDataError, |
| 308 "Error processing blob journal.")); | 308 "Error processing blob journal.")); |
| 309 } | 309 } |
| 310 | 310 |
| 311 return s; | 311 return s; |
| 312 } | 312 } |
| 313 | 313 |
| 314 leveldb::Status IndexedDBTransaction::CommitPhaseTwo() { | 314 leveldb::Status IndexedDBTransaction::CommitPhaseTwo() { |
| 315 // Abort may have been called just as the blob write completed. | 315 // Abort may have been called just as the blob write completed. |
| 316 if (state_ == FINISHED) | 316 if (state_ == FINISHED) |
| 317 return leveldb::Status::OK(); | 317 return leveldb::Status::OK(); |
| 318 | 318 |
| 319 DCHECK_EQ(state_, COMMITTING); | 319 DCHECK_EQ(state_, COMMITTING); |
| 320 | 320 |
| 321 // The last reference to this object may be released while performing the | |
| 322 // commit steps below. We therefore take a self reference to keep ourselves | |
| 323 // alive while executing this method. | |
| 324 scoped_refptr<IndexedDBTransaction> protect(this); | |
| 325 | |
| 326 state_ = FINISHED; | 321 state_ = FINISHED; |
| 327 | 322 |
| 328 leveldb::Status s; | 323 leveldb::Status s; |
| 329 bool committed; | 324 bool committed; |
| 330 if (!used_) { | 325 if (!used_) { |
| 331 committed = true; | 326 committed = true; |
| 332 } else { | 327 } else { |
| 333 s = transaction_->CommitPhaseTwo(); | 328 s = transaction_->CommitPhaseTwo(); |
| 334 committed = s.ok(); | 329 committed = s.ok(); |
| 335 } | 330 } |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 352 // SendObservations must be called before OnComplete to ensure consistency | 347 // SendObservations must be called before OnComplete to ensure consistency |
| 353 // of callbacks at renderer. | 348 // of callbacks at renderer. |
| 354 if (!connection_changes_map_.empty()) { | 349 if (!connection_changes_map_.empty()) { |
| 355 database_->SendObservations(std::move(connection_changes_map_)); | 350 database_->SendObservations(std::move(connection_changes_map_)); |
| 356 connection_changes_map_.clear(); | 351 connection_changes_map_.clear(); |
| 357 } | 352 } |
| 358 { | 353 { |
| 359 IDB_TRACE1( | 354 IDB_TRACE1( |
| 360 "IndexedDBTransaction::CommitPhaseTwo.TransactionCompleteCallbacks", | 355 "IndexedDBTransaction::CommitPhaseTwo.TransactionCompleteCallbacks", |
| 361 "txn.id", id()); | 356 "txn.id", id()); |
| 362 callbacks_->OnComplete(id_); | 357 callbacks_->OnComplete(*this); |
| 363 } | 358 } |
| 364 if (!pending_observers_.empty() && connection_) { | 359 if (!pending_observers_.empty() && connection_) { |
| 365 connection_->ActivatePendingObservers(std::move(pending_observers_)); | 360 connection_->ActivatePendingObservers(std::move(pending_observers_)); |
| 366 pending_observers_.clear(); | 361 pending_observers_.clear(); |
| 367 } | 362 } |
| 368 | 363 |
| 369 database_->TransactionFinished(this, true); | 364 database_->TransactionFinished(this, true); |
| 370 } else { | 365 } else { |
| 371 while (!abort_task_stack_.empty()) | 366 while (!abort_task_stack_.empty()) |
| 372 abort_task_stack_.pop().Run(NULL); | 367 abort_task_stack_.pop().Run(NULL); |
| 373 | 368 |
| 374 IndexedDBDatabaseError error; | 369 IndexedDBDatabaseError error; |
| 375 if (leveldb_env::IndicatesDiskFull(s)) { | 370 if (leveldb_env::IndicatesDiskFull(s)) { |
| 376 error = IndexedDBDatabaseError( | 371 error = IndexedDBDatabaseError( |
| 377 blink::WebIDBDatabaseExceptionQuotaError, | 372 blink::WebIDBDatabaseExceptionQuotaError, |
| 378 "Encountered disk full while committing transaction."); | 373 "Encountered disk full while committing transaction."); |
| 379 } else { | 374 } else { |
| 380 error = IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, | 375 error = IndexedDBDatabaseError(blink::WebIDBDatabaseExceptionUnknownError, |
| 381 "Internal error committing transaction."); | 376 "Internal error committing transaction."); |
| 382 } | 377 } |
| 383 callbacks_->OnAbort(id_, error); | 378 callbacks_->OnAbort(*this, error); |
| 384 | 379 |
| 385 database_->TransactionFinished(this, false); | 380 database_->TransactionFinished(this, false); |
| 386 database_->TransactionCommitFailed(s); | 381 database_->TransactionCommitFailed(s); |
| 387 } | 382 } |
| 388 | 383 |
| 389 database_ = NULL; | 384 pending_observers_.clear(); |
| 385 // This destroys our object. | |
| 386 connection_->EraseTransaction(id_); | |
| 390 return s; | 387 return s; |
| 391 } | 388 } |
| 392 | 389 |
| 393 void IndexedDBTransaction::ProcessTaskQueue() { | 390 void IndexedDBTransaction::ProcessTaskQueue() { |
| 394 IDB_TRACE1("IndexedDBTransaction::ProcessTaskQueue", "txn.id", id()); | 391 IDB_TRACE1("IndexedDBTransaction::ProcessTaskQueue", "txn.id", id()); |
| 395 | 392 |
| 396 // May have been aborted. | 393 // May have been aborted. |
| 397 if (!should_process_queue_) | 394 if (!should_process_queue_) |
| 398 return; | 395 return; |
| 399 | 396 |
| 400 DCHECK(!IsTaskQueueEmpty()); | 397 DCHECK(!IsTaskQueueEmpty()); |
| 401 should_process_queue_ = false; | 398 should_process_queue_ = false; |
| 402 | 399 |
| 403 if (!backing_store_transaction_begun_) { | 400 if (!backing_store_transaction_begun_) { |
| 404 transaction_->Begin(); | 401 transaction_->Begin(); |
| 405 backing_store_transaction_begun_ = true; | 402 backing_store_transaction_begun_ = true; |
| 406 } | 403 } |
| 407 | 404 |
| 408 // The last reference to this object may be released while performing the | |
| 409 // tasks. Take take a self reference to keep this object alive so that | |
| 410 // the loop termination conditions can be checked. | |
| 411 scoped_refptr<IndexedDBTransaction> protect(this); | |
| 412 | |
| 413 TaskQueue* task_queue = | 405 TaskQueue* task_queue = |
| 414 pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_; | 406 pending_preemptive_events_ ? &preemptive_task_queue_ : &task_queue_; |
| 415 while (!task_queue->empty() && state_ != FINISHED) { | 407 while (!task_queue->empty() && state_ != FINISHED) { |
| 416 DCHECK_EQ(state_, STARTED); | 408 DCHECK_EQ(state_, STARTED); |
| 417 Operation task(task_queue->pop()); | 409 Operation task(task_queue->pop()); |
| 418 task.Run(this); | 410 task.Run(this); |
| 419 if (!pending_preemptive_events_) { | 411 if (!pending_preemptive_events_) { |
| 420 DCHECK(diagnostics_.tasks_completed < diagnostics_.tasks_scheduled); | 412 DCHECK(diagnostics_.tasks_completed < diagnostics_.tasks_scheduled); |
| 421 ++diagnostics_.tasks_completed; | 413 ++diagnostics_.tasks_completed; |
| 422 } | 414 } |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 436 // The transaction may have been aborted while processing tasks. | 428 // The transaction may have been aborted while processing tasks. |
| 437 if (state_ == FINISHED) | 429 if (state_ == FINISHED) |
| 438 return; | 430 return; |
| 439 | 431 |
| 440 DCHECK(state_ == STARTED); | 432 DCHECK(state_ == STARTED); |
| 441 | 433 |
| 442 // Otherwise, start a timer in case the front-end gets wedged and | 434 // Otherwise, start a timer in case the front-end gets wedged and |
| 443 // never requests further activity. Read-only transactions don't | 435 // never requests further activity. Read-only transactions don't |
| 444 // block other transactions, so don't time those out. | 436 // block other transactions, so don't time those out. |
| 445 if (mode_ != blink::WebIDBTransactionModeReadOnly) { | 437 if (mode_ != blink::WebIDBTransactionModeReadOnly) { |
| 446 timeout_timer_.Start(FROM_HERE, GetInactivityTimeout(), | 438 timeout_timer_.Start( |
| 447 base::Bind(&IndexedDBTransaction::Timeout, this)); | 439 FROM_HERE, GetInactivityTimeout(), |
| 440 base::Bind(&IndexedDBTransaction::Timeout, ptr_factory_.GetWeakPtr())); | |
| 448 } | 441 } |
| 449 } | 442 } |
| 450 | 443 |
| 451 base::TimeDelta IndexedDBTransaction::GetInactivityTimeout() const { | 444 base::TimeDelta IndexedDBTransaction::GetInactivityTimeout() const { |
| 452 return base::TimeDelta::FromSeconds(kInactivityTimeoutPeriodSeconds); | 445 return base::TimeDelta::FromSeconds(kInactivityTimeoutPeriodSeconds); |
| 453 } | 446 } |
| 454 | 447 |
| 455 void IndexedDBTransaction::Timeout() { | 448 void IndexedDBTransaction::Timeout() { |
| 456 Abort(IndexedDBDatabaseError( | 449 Abort(IndexedDBDatabaseError( |
| 457 blink::WebIDBDatabaseExceptionTimeoutError, | 450 blink::WebIDBDatabaseExceptionTimeoutError, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 498 | 491 |
| 499 void IndexedDBTransaction::RecordObserverForLastObservation( | 492 void IndexedDBTransaction::RecordObserverForLastObservation( |
| 500 int32_t connection_id, | 493 int32_t connection_id, |
| 501 int32_t observer_id) { | 494 int32_t observer_id) { |
| 502 auto it = connection_changes_map_.find(connection_id); | 495 auto it = connection_changes_map_.find(connection_id); |
| 503 DCHECK(it != connection_changes_map_.end()); | 496 DCHECK(it != connection_changes_map_.end()); |
| 504 it->second->RecordObserverForLastObservation(observer_id); | 497 it->second->RecordObserverForLastObservation(observer_id); |
| 505 } | 498 } |
| 506 | 499 |
| 507 } // namespace content | 500 } // namespace content |
| OLD | NEW |