Chromium Code Reviews| Index: chrome/browser/browser_process_impl.cc |
| diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc |
| index 34edc3caa532928701879a7588c463a7aa92ac8d..cdc470e216a3b1f7c0978bf7d116fe9faa95ace8 100644 |
| --- a/chrome/browser/browser_process_impl.cc |
| +++ b/chrome/browser/browser_process_impl.cc |
| @@ -7,6 +7,7 @@ |
| #include <stddef.h> |
| #include <algorithm> |
| +#include <iterator> |
| #include <map> |
| #include <utility> |
| #include <vector> |
| @@ -398,6 +399,8 @@ void BrowserProcessImpl::PostDestroyThreads() { |
| namespace { |
| +using TaskRunnerVector = std::vector<scoped_refptr<base::SequencedTaskRunner>>; |
| + |
| // Used at the end of session to block the UI thread for completion of sentinel |
| // tasks on the set of threads used to persist profile data and local state. |
| // This is done to ensure that the data has been persisted to disk before |
| @@ -411,6 +414,10 @@ class RundownTaskCounter : |
| // 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(TaskRunnerVector runners); |
| + |
| // Waits until the count is zero or |end_time| is reached. |
| // This can only be called once per instance. Returns true if a count of zero |
| // is reached or false if the |end_time| is reached. It is valid to pass an |
| @@ -425,6 +432,9 @@ class RundownTaskCounter : |
| // zero. |
| void Decrement(); |
| + void RundownSerially(TaskRunnerVector::const_iterator it, |
| + TaskRunnerVector runner); |
| + |
| // The count starts at one to defer the possibility of one->zero transitions |
| // until TimedWait is called. |
| base::AtomicRefCount count_; |
| @@ -451,6 +461,16 @@ void RundownTaskCounter::Post(base::SequencedTaskRunner* task_runner) { |
| base::Bind(&RundownTaskCounter::Decrement, this)); |
| } |
| +void RundownTaskCounter::PostSerially(TaskRunnerVector runners) { |
| + if (runners.empty()) |
| + return; |
| + base::AtomicRefCountInc(&count_); |
| + TaskRunnerVector::const_iterator it = runners.begin(); |
| + (*it)->PostNonNestableTask( |
| + FROM_HERE, base::Bind(&RundownTaskCounter::RundownSerially, this, it + 1, |
| + base::Passed(&runners))); |
| +} |
| + |
| void RundownTaskCounter::Decrement() { |
| if (!base::AtomicRefCountDec(&count_)) |
| waitable_event_.Signal(); |
| @@ -463,6 +483,22 @@ bool RundownTaskCounter::TimedWaitUntil(const base::TimeTicks& end_time) { |
| return waitable_event_.TimedWaitUntil(end_time); |
| } |
| +void RundownTaskCounter::RundownSerially(TaskRunnerVector::const_iterator it, |
| + TaskRunnerVector runners) { |
| + if (it == runners.end()) { |
| + Decrement(); |
| + return; |
| + } |
| + (*it)->PostNonNestableTask( |
| + FROM_HERE, base::Bind(&RundownTaskCounter::RundownSerially, this, it + 1, |
| + base::Passed(&runners))); |
| +} |
| + |
| +void FlushStoragePartition(scoped_refptr<RundownTaskCounter> rundown_counter, |
| + content::StoragePartition* partition) { |
| + rundown_counter->PostSerially(partition->Flush()); |
| +} |
| + |
| } // namespace |
| void BrowserProcessImpl::EndSession() { |
| @@ -473,8 +509,7 @@ void BrowserProcessImpl::EndSession() { |
| const bool pref_service_enabled = |
| base::FeatureList::IsEnabled(features::kPrefService); |
| std::vector<scoped_refptr<base::SequencedTaskRunner>> profile_writer_runners; |
| - for (size_t i = 0; i < profiles.size(); ++i) { |
| - Profile* profile = profiles[i]; |
| + for (Profile* profile : profiles) { |
| profile->SetExitType(Profile::EXIT_SESSION_ENDED); |
| if (profile->GetPrefs()) { |
| profile->GetPrefs()->CommitPendingWrite(); |
| @@ -487,6 +522,8 @@ void BrowserProcessImpl::EndSession() { |
| rundown_counter->Post(profile->GetIOTaskRunner().get()); |
| } |
| } |
| + content::BrowserContext::ForEachStoragePartition( |
| + profile, base::Bind(&FlushStoragePartition, rundown_counter)); |
|
hashimoto
2017/04/04 09:23:24
This shouldn't be put before Local State.
Local St
|
| } |
| // Tell the metrics service it was cleanly shutdown. |