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