Index: webkit/dom_storage/dom_storage_area.cc |
diff --git a/webkit/dom_storage/dom_storage_area.cc b/webkit/dom_storage/dom_storage_area.cc |
index f589d88987cc54a7d9079fd00cfc6b16f926c6c0..43f22f16cc7debb89f1ddf36d8001ed3f7df1f07 100644 |
--- a/webkit/dom_storage/dom_storage_area.cc |
+++ b/webkit/dom_storage/dom_storage_area.cc |
@@ -60,7 +60,8 @@ DomStorageArea::DomStorageArea( |
task_runner_(task_runner), |
map_(new DomStorageMap(kPerAreaQuota)), |
is_initial_import_done_(true), |
- is_shutdown_(false) { |
+ is_shutdown_(false), |
+ commit_batches_in_flight_(0) { |
if (namespace_id == kLocalStorageNamespaceId && !directory.empty()) { |
FilePath path = directory.Append(DatabaseFileNameFromOrigin(origin_)); |
backing_.reset(new DomStorageDatabase(path)); |
@@ -161,7 +162,7 @@ DomStorageArea* DomStorageArea::ShallowCopy(int64 destination_namespace_id) { |
bool DomStorageArea::HasUncommittedChanges() const { |
DCHECK(!is_shutdown_); |
- return commit_batch_.get() || in_flight_commit_batch_.get(); |
+ return commit_batch_.get() || commit_batches_in_flight_; |
} |
void DomStorageArea::DeleteOrigin() { |
@@ -233,10 +234,10 @@ DomStorageArea::CommitBatch* DomStorageArea::CreateCommitBatchIfNeeded() { |
if (!commit_batch_.get()) { |
commit_batch_.reset(new CommitBatch()); |
- // Start a timer to commit any changes that accrue in the batch, |
- // but only if a commit is not currently in flight. In that case |
- // the timer will be started after the current commit has happened. |
- if (!in_flight_commit_batch_.get()) { |
+ // Start a timer to commit any changes that accrue in the batch, but only if |
+ // no commits are currently in flight. In that case the timer will be |
+ // started after the commits have happened. |
+ if (!commit_batches_in_flight_) { |
task_runner_->PostDelayedTask( |
FROM_HERE, |
base::Bind(&DomStorageArea::OnCommitTimer, this), |
@@ -253,26 +254,25 @@ void DomStorageArea::OnCommitTimer() { |
DCHECK(backing_.get()); |
DCHECK(commit_batch_.get()); |
- DCHECK(!in_flight_commit_batch_.get()); |
+ DCHECK(!commit_batches_in_flight_); |
// This method executes on the primary sequence, we schedule |
// a task for immediate execution on the commit sequence. |
DCHECK(task_runner_->IsRunningOnPrimarySequence()); |
- in_flight_commit_batch_ = commit_batch_.Pass(); |
bool success = task_runner_->PostShutdownBlockingTask( |
FROM_HERE, |
DomStorageTaskRunner::COMMIT_SEQUENCE, |
- base::Bind(&DomStorageArea::CommitChanges, this)); |
+ base::Bind(&DomStorageArea::CommitChanges, this, |
+ base::Owned(commit_batch_.release()))); |
+ ++commit_batches_in_flight_; |
DCHECK(success); |
} |
-void DomStorageArea::CommitChanges() { |
+void DomStorageArea::CommitChanges(const CommitBatch* commit_batch) { |
// This method executes on the commit sequence. |
DCHECK(task_runner_->IsRunningOnCommitSequence()); |
- DCHECK(in_flight_commit_batch_.get()); |
- bool success = backing_->CommitChanges( |
- in_flight_commit_batch_->clear_all_first, |
- in_flight_commit_batch_->changed_values); |
+ bool success = backing_->CommitChanges(commit_batch->clear_all_first, |
+ commit_batch->changed_values); |
DCHECK(success); // TODO(michaeln): what if it fails? |
task_runner_->PostTask( |
FROM_HERE, |
@@ -284,8 +284,8 @@ void DomStorageArea::OnCommitComplete() { |
DCHECK(task_runner_->IsRunningOnPrimarySequence()); |
if (is_shutdown_) |
return; |
- in_flight_commit_batch_.reset(); |
- if (commit_batch_.get()) { |
+ --commit_batches_in_flight_; |
+ if (commit_batch_.get() && !commit_batches_in_flight_) { |
// More changes have accrued, restart the timer. |
task_runner_->PostDelayedTask( |
FROM_HERE, |
@@ -306,7 +306,6 @@ void DomStorageArea::ShutdownInCommitSequence() { |
DCHECK(success); |
} |
commit_batch_.reset(); |
- in_flight_commit_batch_.reset(); |
backing_.reset(); |
} |