| Index: chrome/browser/browser_process_impl.cc
|
| diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
|
| index 27b7c5be0d5e0e6cce3a5077219abbcc0efb88f7..27f05b989c40593ee919521963ab633208d0a586 100644
|
| --- a/chrome/browser/browser_process_impl.cc
|
| +++ b/chrome/browser/browser_process_impl.cc
|
| @@ -15,6 +15,7 @@
|
| #include "base/debug/alias.h"
|
| #include "base/debug/leak_annotations.h"
|
| #include "base/files/file_path.h"
|
| +#include "base/metrics/field_trial.h"
|
| #include "base/path_service.h"
|
| #include "base/prefs/json_pref_store.h"
|
| #include "base/prefs/pref_registry_simple.h"
|
| @@ -441,9 +442,25 @@ bool RundownTaskCounter::TimedWait(const base::TimeDelta& max_time) {
|
| return waitable_event_.TimedWait(max_time);
|
| }
|
|
|
| +bool ExperimentUseBrokenSynchronization() {
|
| + // The logoff behavior used to have a race, whereby it would perform profile
|
| + // IO writes on the blocking thread pool, but would sycnhronize to the FILE
|
| + // thread. Windows feels free to terminate any process that's hidden or
|
| + // destroyed all it's windows, and sometimes Chrome would be terminated
|
| + // with pending profile IO due to this mis-synchronization.
|
| + // Under the "WindowsLogoffRace" experiment group, the broken behavior is
|
| + // emulated, in order to allow measuring what fraction of unclean shutdowns
|
| + // are due to this bug.
|
| + const std::string group_name =
|
| + base::FieldTrialList::FindFullName("WindowsLogoffRace");
|
| + return group_name == "BrokenSynchronization";
|
| +}
|
| +
|
| } // namespace
|
|
|
| void BrowserProcessImpl::EndSession() {
|
| + bool use_broken_synchronization = ExperimentUseBrokenSynchronization();
|
| +
|
| // Mark all the profiles as clean.
|
| ProfileManager* pm = profile_manager();
|
| std::vector<Profile*> profiles(pm->GetLoadedProfiles());
|
| @@ -452,7 +469,8 @@ void BrowserProcessImpl::EndSession() {
|
| Profile* profile = profiles[i];
|
| profile->SetExitType(Profile::EXIT_SESSION_ENDED);
|
|
|
| - rundown_counter->Post(profile->GetIOTaskRunner());
|
| + if (!use_broken_synchronization)
|
| + rundown_counter->Post(profile->GetIOTaskRunner());
|
| }
|
|
|
| // Tell the metrics service it was cleanly shutdown.
|
| @@ -465,7 +483,8 @@ void BrowserProcessImpl::EndSession() {
|
| // commit metrics::prefs::kStabilitySessionEndCompleted change immediately.
|
| local_state()->CommitPendingWrite();
|
|
|
| - rundown_counter->Post(local_state_task_runner_);
|
| + if (!use_broken_synchronization)
|
| + rundown_counter->Post(local_state_task_runner_);
|
| #endif
|
| }
|
|
|
| @@ -479,6 +498,11 @@ void BrowserProcessImpl::EndSession() {
|
| // If you change the condition here, be sure to also change
|
| // ProfileBrowserTests to match.
|
| #if defined(USE_X11) || defined(OS_WIN)
|
| + if (use_broken_synchronization) {
|
| + rundown_counter->Post(
|
| + BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
|
| + }
|
| +
|
| // Do a best-effort wait on the successful countdown of rundown tasks. Note
|
| // that if we don't complete "quickly enough", Windows will terminate our
|
| // process.
|
|
|