Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(164)

Unified Diff: chrome/browser/browser_process_impl.cc

Issue 2788813002: Try to flush DOMStorage too when ending the browsing session.
Patch Set: fixes Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/browser_process_impl.cc
diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
index 39dc70edf71dbc9bbb7802e5129715c43cb1c344..8c3272e24499a2587bc2ad66e12756d829ae1007 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,17 @@ 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)));
+}
+
} // namespace
void BrowserProcessImpl::EndSession() {
@@ -473,8 +504,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();
@@ -527,15 +557,31 @@ void BrowserProcessImpl::EndSession() {
// processes to launch, this can result in a hang. See
// http://crbug.com/318527.
const base::TimeTicks end_time = base::TimeTicks::Now() + kEndSessionTimeout;
- const bool timed_out = !rundown_counter->TimedWaitUntil(end_time);
- if (timed_out || !pref_service_enabled)
+ if (!rundown_counter->TimedWaitUntil(end_time))
return;
- scoped_refptr<RundownTaskCounter> profile_write_rundown_counter(
+ if (pref_service_enabled) {
+ scoped_refptr<RundownTaskCounter> profile_write_rundown_counter(
+ new RundownTaskCounter());
+ for (auto& profile_writer_runner : profile_writer_runners)
+ profile_write_rundown_counter->Post(profile_writer_runner.get());
+ if (!profile_write_rundown_counter->TimedWaitUntil(end_time))
+ return;
+ }
+
+ // Time permitting, give other storage systems a chance to flush caches.
+ auto flush_function = [](scoped_refptr<RundownTaskCounter> rundown_counter,
+ content::StoragePartition* partition) {
+ rundown_counter->PostSerially(partition->Flush());
+ };
+ scoped_refptr<RundownTaskCounter> flush_storage_rundown_counter(
new RundownTaskCounter());
- for (auto& profile_writer_runner : profile_writer_runners)
- profile_write_rundown_counter->Post(profile_writer_runner.get());
- profile_write_rundown_counter->TimedWaitUntil(end_time);
+ for (Profile* profile : profiles) {
+ content::BrowserContext::ForEachStoragePartition(
+ profile,
+ base::BindRepeating(flush_function, flush_storage_rundown_counter));
+ }
+ flush_storage_rundown_counter->TimedWaitUntil(end_time);
#else
NOTIMPLEMENTED();
#endif

Powered by Google App Engine
This is Rietveld 408576698