Index: chrome/browser/browser_process_impl.cc |
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc |
index 863c96a8c4e25b5ebef6c627001b884590d47815..4d39c00943fd04a6bc2890f8577156299c241f90 100644 |
--- a/chrome/browser/browser_process_impl.cc |
+++ b/chrome/browser/browser_process_impl.cc |
@@ -407,12 +407,19 @@ namespace { |
class RundownTaskCounter : |
public base::RefCountedThreadSafe<RundownTaskCounter> { |
public: |
+ using TaskRunnerVector = |
+ std::vector<scoped_refptr<base::SequencedTaskRunner>>; |
+ |
RundownTaskCounter(); |
// Posts a rundown task to |task_runner|, can be invoked an arbitrary number |
// of times before calling TimedWait. |
void Post(base::SequencedTaskRunner* task_runner); |
+ // Posts a rundown task to each runner in |runners|, where the rundown task |
+ // for runner[n+1] is posted during rundown task execution for runner[n]. |
+ void PostSerially(const TaskRunnerVector &runners); |
+ |
// Waits until the count is zero or |max_time| has passed. |
// This can only be called once per instance. |
bool TimedWait(const base::TimeDelta& max_time); |
@@ -421,6 +428,9 @@ class RundownTaskCounter : |
friend class base::RefCountedThreadSafe<RundownTaskCounter>; |
~RundownTaskCounter() {} |
+ void RundownNextSerially(TaskRunnerVector::const_iterator it, |
+ scoped_ptr<TaskRunnerVector> runners_ptr); |
+ |
// Decrements the counter and releases the waitable event on transition to |
// zero. |
void Decrement(); |
@@ -450,9 +460,14 @@ void RundownTaskCounter::Post(base::SequencedTaskRunner* task_runner) { |
base::Bind(&RundownTaskCounter::Decrement, this)); |
} |
-void RundownTaskCounter::Decrement() { |
- if (!base::AtomicRefCountDec(&count_)) |
- waitable_event_.Signal(); |
+void RundownTaskCounter::PostSerially(const TaskRunnerVector& runners) { |
+ DCHECK(!runners.empty()); |
+ base::AtomicRefCountInc(&count_); |
+ scoped_ptr<TaskRunnerVector> runners_ptr(new TaskRunnerVector(runners)); |
+ TaskRunnerVector::const_iterator it = runners_ptr->begin(); |
+ (*it)->PostNonNestableTask(FROM_HERE, |
+ base::Bind(&RundownTaskCounter::RundownNextSerially, |
+ this, it, base::Passed(runners_ptr.Pass()))); |
} |
bool RundownTaskCounter::TimedWait(const base::TimeDelta& max_time) { |
@@ -462,6 +477,31 @@ bool RundownTaskCounter::TimedWait(const base::TimeDelta& max_time) { |
return waitable_event_.TimedWait(max_time); |
} |
+void RundownTaskCounter::Decrement() { |
+ if (!base::AtomicRefCountDec(&count_)) |
+ waitable_event_.Signal(); |
+} |
+ |
+void RundownTaskCounter::RundownNextSerially( |
+ TaskRunnerVector::const_iterator it, |
+ scoped_ptr<TaskRunnerVector> runners_ptr) { |
+ TaskRunnerVector::const_iterator next = ++it; |
+ if (next == runners_ptr->end()) { |
+ Decrement(); |
+ return; |
+ } |
+ (*next)->PostNonNestableTask(FROM_HERE, |
+ base::Bind(&RundownTaskCounter::RundownNextSerially, |
+ this, next, base::Passed(runners_ptr.Pass()))); |
+} |
+ |
+void FlushStoragePartition( |
+ RundownTaskCounter* rundown_counter, |
+ content::StoragePartition* partition) { |
+ partition->Flush(); |
+ //rundown_counter->PostSerially(partition->GetFlushTaskRunners()); |
+} |
+ |
} // namespace |
void BrowserProcessImpl::EndSession() { |
@@ -476,6 +516,8 @@ void BrowserProcessImpl::EndSession() { |
profile->GetPrefs()->CommitPendingWrite(); |
rundown_counter->Post(profile->GetIOTaskRunner().get()); |
} |
+ content::BrowserContext::ForEachStoragePartition( |
+ profile, base::Bind(FlushStoragePartition, rundown_counter)); |
} |
// Tell the metrics service it was cleanly shutdown. |