Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/browser_process_impl.h" | 5 #include "chrome/browser/browser_process_impl.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <map> | 8 #include <map> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/atomic_ref_count.h" | 11 #include "base/atomic_ref_count.h" |
| 12 #include "base/bind.h" | 12 #include "base/bind.h" |
| 13 #include "base/bind_helpers.h" | 13 #include "base/bind_helpers.h" |
| 14 #include "base/command_line.h" | 14 #include "base/command_line.h" |
| 15 #include "base/debug/alias.h" | 15 #include "base/debug/alias.h" |
| 16 #include "base/debug/leak_annotations.h" | 16 #include "base/debug/leak_annotations.h" |
| 17 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
| 18 #include "base/metrics/field_trial.h" | |
| 18 #include "base/path_service.h" | 19 #include "base/path_service.h" |
| 19 #include "base/prefs/json_pref_store.h" | 20 #include "base/prefs/json_pref_store.h" |
| 20 #include "base/prefs/pref_registry_simple.h" | 21 #include "base/prefs/pref_registry_simple.h" |
| 21 #include "base/prefs/pref_service.h" | 22 #include "base/prefs/pref_service.h" |
| 22 #include "base/synchronization/waitable_event.h" | 23 #include "base/synchronization/waitable_event.h" |
| 23 #include "base/threading/thread.h" | 24 #include "base/threading/thread.h" |
| 24 #include "base/threading/thread_restrictions.h" | 25 #include "base/threading/thread_restrictions.h" |
| 25 #include "base/time/default_tick_clock.h" | 26 #include "base/time/default_tick_clock.h" |
| 26 #include "chrome/browser/apps/chrome_apps_client.h" | 27 #include "chrome/browser/apps/chrome_apps_client.h" |
| 27 #include "chrome/browser/background/background_mode_manager.h" | 28 #include "chrome/browser/background/background_mode_manager.h" |
| (...skipping 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 434 waitable_event_.Signal(); | 435 waitable_event_.Signal(); |
| 435 } | 436 } |
| 436 | 437 |
| 437 bool RundownTaskCounter::TimedWait(const base::TimeDelta& max_time) { | 438 bool RundownTaskCounter::TimedWait(const base::TimeDelta& max_time) { |
| 438 // Decrement the excess count from the constructor. | 439 // Decrement the excess count from the constructor. |
| 439 Decrement(); | 440 Decrement(); |
| 440 | 441 |
| 441 return waitable_event_.TimedWait(max_time); | 442 return waitable_event_.TimedWait(max_time); |
| 442 } | 443 } |
| 443 | 444 |
| 445 bool ExperimentUseBrokenSynchronization() { | |
| 446 const std::string group_name = | |
| 447 base::FieldTrialList::FindFullName("WindowsLogoffRace"); | |
| 448 return group_name == "BrokenSynchronization"; | |
|
gab
2014/07/11 17:13:44
As discussed I think you want a control group and
Sigurður Ásgeirsson
2014/07/14 17:04:14
As-is, this supports a three group split, as the d
| |
| 449 } | |
| 450 | |
| 444 } // namespace | 451 } // namespace |
| 445 | 452 |
| 446 void BrowserProcessImpl::EndSession() { | 453 void BrowserProcessImpl::EndSession() { |
| 454 bool use_broken_synchronization = ExperimentUseBrokenSynchronization(); | |
| 455 | |
| 447 // Mark all the profiles as clean. | 456 // Mark all the profiles as clean. |
| 448 ProfileManager* pm = profile_manager(); | 457 ProfileManager* pm = profile_manager(); |
| 449 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); | 458 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); |
| 450 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter()); | 459 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter()); |
| 451 for (size_t i = 0; i < profiles.size(); ++i) { | 460 for (size_t i = 0; i < profiles.size(); ++i) { |
| 452 Profile* profile = profiles[i]; | 461 Profile* profile = profiles[i]; |
| 453 profile->SetExitType(Profile::EXIT_SESSION_ENDED); | 462 profile->SetExitType(Profile::EXIT_SESSION_ENDED); |
| 454 | 463 |
| 455 rundown_counter->Post(profile->GetIOTaskRunner()); | 464 if (!use_broken_synchronization) |
| 465 rundown_counter->Post(profile->GetIOTaskRunner()); | |
| 456 } | 466 } |
| 457 | 467 |
| 458 // Tell the metrics service it was cleanly shutdown. | 468 // Tell the metrics service it was cleanly shutdown. |
| 459 MetricsService* metrics = g_browser_process->metrics_service(); | 469 MetricsService* metrics = g_browser_process->metrics_service(); |
| 460 if (metrics && local_state()) { | 470 if (metrics && local_state()) { |
| 461 metrics->RecordStartOfSessionEnd(); | 471 metrics->RecordStartOfSessionEnd(); |
| 462 #if !defined(OS_CHROMEOS) | 472 #if !defined(OS_CHROMEOS) |
| 463 // MetricsService lazily writes to prefs, force it to write now. | 473 // MetricsService lazily writes to prefs, force it to write now. |
| 464 // On ChromeOS, chrome gets killed when hangs, so no need to | 474 // On ChromeOS, chrome gets killed when hangs, so no need to |
| 465 // commit metrics::prefs::kStabilitySessionEndCompleted change immediately. | 475 // commit metrics::prefs::kStabilitySessionEndCompleted change immediately. |
| 466 local_state()->CommitPendingWrite(); | 476 local_state()->CommitPendingWrite(); |
| 467 | 477 |
| 468 rundown_counter->Post(local_state_task_runner_); | 478 if (!use_broken_synchronization) |
| 479 rundown_counter->Post(local_state_task_runner_); | |
| 469 #endif | 480 #endif |
| 470 } | 481 } |
| 471 | 482 |
| 472 // http://crbug.com/125207 | 483 // http://crbug.com/125207 |
| 473 base::ThreadRestrictions::ScopedAllowWait allow_wait; | 484 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
| 474 | 485 |
| 475 // We must write that the profile and metrics service shutdown cleanly, | 486 // We must write that the profile and metrics service shutdown cleanly, |
| 476 // otherwise on startup we'll think we crashed. So we block until done and | 487 // otherwise on startup we'll think we crashed. So we block until done and |
| 477 // then proceed with normal shutdown. | 488 // then proceed with normal shutdown. |
| 478 // | 489 // |
| 479 // If you change the condition here, be sure to also change | 490 // If you change the condition here, be sure to also change |
| 480 // ProfileBrowserTests to match. | 491 // ProfileBrowserTests to match. |
| 481 #if defined(USE_X11) || defined(OS_WIN) | 492 #if defined(USE_X11) || defined(OS_WIN) |
| 493 if (use_broken_synchronization) { | |
| 494 rundown_counter->Post( | |
| 495 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); | |
| 496 } | |
| 497 | |
| 482 // Do a best-effort wait on the successful countdown of rundown tasks. Note | 498 // Do a best-effort wait on the successful countdown of rundown tasks. Note |
| 483 // that if we don't complete "quickly enough", Windows will terminate our | 499 // that if we don't complete "quickly enough", Windows will terminate our |
| 484 // process. | 500 // process. |
| 485 // | 501 // |
| 486 // On Windows, we previously posted a message to FILE and then ran a nested | 502 // On Windows, we previously posted a message to FILE and then ran a nested |
| 487 // message loop, waiting for that message to be processed until quitting. | 503 // message loop, waiting for that message to be processed until quitting. |
| 488 // However, doing so means that other messages will also be processed. In | 504 // However, doing so means that other messages will also be processed. In |
| 489 // particular, if the GPU process host notices that the GPU has been killed | 505 // particular, if the GPU process host notices that the GPU has been killed |
| 490 // during shutdown, it races exiting the nested loop with the process host | 506 // during shutdown, it races exiting the nested loop with the process host |
| 491 // blocking the message loop attempting to re-establish a connection to the | 507 // blocking the message loop attempting to re-establish a connection to the |
| (...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1171 } | 1187 } |
| 1172 | 1188 |
| 1173 void BrowserProcessImpl::OnAutoupdateTimer() { | 1189 void BrowserProcessImpl::OnAutoupdateTimer() { |
| 1174 if (CanAutorestartForUpdate()) { | 1190 if (CanAutorestartForUpdate()) { |
| 1175 DLOG(WARNING) << "Detected update. Restarting browser."; | 1191 DLOG(WARNING) << "Detected update. Restarting browser."; |
| 1176 RestartBackgroundInstance(); | 1192 RestartBackgroundInstance(); |
| 1177 } | 1193 } |
| 1178 } | 1194 } |
| 1179 | 1195 |
| 1180 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) | 1196 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) |
| OLD | NEW |