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