| 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.
|
|
|