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

Side by Side Diff: chrome/browser/browser_process_impl.cc

Issue 385123004: Implement the WindowsLogoffRace finch experiment. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Revert chrome_browser_field_trials change. Created 6 years, 5 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/lifetime/application_lifetime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 // The logoff behavior used to have a race, whereby it would perform profile
447 // IO writes on the blocking thread pool, but would sycnhronize to the FILE
448 // thread. Windows feels free to terminate any process that's hidden or
449 // destroyed all it's windows, and sometimes Chrome would be terminated
450 // with pending profile IO due to this mis-synchronization.
451 // Under the "WindowsLogoffRace" experiment group, the broken behavior is
452 // emulated, in order to allow measuring what fraction of unclean shutdowns
453 // are due to this bug.
454 const std::string group_name =
455 base::FieldTrialList::FindFullName("WindowsLogoffRace");
456 return group_name == "BrokenSynchronization";
457 }
458
444 } // namespace 459 } // namespace
445 460
446 void BrowserProcessImpl::EndSession() { 461 void BrowserProcessImpl::EndSession() {
462 bool use_broken_synchronization = ExperimentUseBrokenSynchronization();
463
447 // Mark all the profiles as clean. 464 // Mark all the profiles as clean.
448 ProfileManager* pm = profile_manager(); 465 ProfileManager* pm = profile_manager();
449 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); 466 std::vector<Profile*> profiles(pm->GetLoadedProfiles());
450 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter()); 467 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter());
451 for (size_t i = 0; i < profiles.size(); ++i) { 468 for (size_t i = 0; i < profiles.size(); ++i) {
452 Profile* profile = profiles[i]; 469 Profile* profile = profiles[i];
453 profile->SetExitType(Profile::EXIT_SESSION_ENDED); 470 profile->SetExitType(Profile::EXIT_SESSION_ENDED);
454 471
455 rundown_counter->Post(profile->GetIOTaskRunner()); 472 if (!use_broken_synchronization)
473 rundown_counter->Post(profile->GetIOTaskRunner());
456 } 474 }
457 475
458 // Tell the metrics service it was cleanly shutdown. 476 // Tell the metrics service it was cleanly shutdown.
459 MetricsService* metrics = g_browser_process->metrics_service(); 477 MetricsService* metrics = g_browser_process->metrics_service();
460 if (metrics && local_state()) { 478 if (metrics && local_state()) {
461 metrics->RecordStartOfSessionEnd(); 479 metrics->RecordStartOfSessionEnd();
462 #if !defined(OS_CHROMEOS) 480 #if !defined(OS_CHROMEOS)
463 // MetricsService lazily writes to prefs, force it to write now. 481 // MetricsService lazily writes to prefs, force it to write now.
464 // On ChromeOS, chrome gets killed when hangs, so no need to 482 // On ChromeOS, chrome gets killed when hangs, so no need to
465 // commit metrics::prefs::kStabilitySessionEndCompleted change immediately. 483 // commit metrics::prefs::kStabilitySessionEndCompleted change immediately.
466 local_state()->CommitPendingWrite(); 484 local_state()->CommitPendingWrite();
467 485
468 rundown_counter->Post(local_state_task_runner_); 486 if (!use_broken_synchronization)
487 rundown_counter->Post(local_state_task_runner_);
469 #endif 488 #endif
470 } 489 }
471 490
472 // http://crbug.com/125207 491 // http://crbug.com/125207
473 base::ThreadRestrictions::ScopedAllowWait allow_wait; 492 base::ThreadRestrictions::ScopedAllowWait allow_wait;
474 493
475 // We must write that the profile and metrics service shutdown cleanly, 494 // 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 495 // otherwise on startup we'll think we crashed. So we block until done and
477 // then proceed with normal shutdown. 496 // then proceed with normal shutdown.
478 // 497 //
479 // If you change the condition here, be sure to also change 498 // If you change the condition here, be sure to also change
480 // ProfileBrowserTests to match. 499 // ProfileBrowserTests to match.
481 #if defined(USE_X11) || defined(OS_WIN) 500 #if defined(USE_X11) || defined(OS_WIN)
501 if (use_broken_synchronization) {
502 rundown_counter->Post(
503 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
504 }
505
482 // Do a best-effort wait on the successful countdown of rundown tasks. Note 506 // 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 507 // that if we don't complete "quickly enough", Windows will terminate our
484 // process. 508 // process.
485 // 509 //
486 // On Windows, we previously posted a message to FILE and then ran a nested 510 // 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. 511 // message loop, waiting for that message to be processed until quitting.
488 // However, doing so means that other messages will also be processed. In 512 // 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 513 // 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 514 // 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 515 // blocking the message loop attempting to re-establish a connection to the
(...skipping 679 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 } 1195 }
1172 1196
1173 void BrowserProcessImpl::OnAutoupdateTimer() { 1197 void BrowserProcessImpl::OnAutoupdateTimer() {
1174 if (CanAutorestartForUpdate()) { 1198 if (CanAutorestartForUpdate()) {
1175 DLOG(WARNING) << "Detected update. Restarting browser."; 1199 DLOG(WARNING) << "Detected update. Restarting browser.";
1176 RestartBackgroundInstance(); 1200 RestartBackgroundInstance();
1177 } 1201 }
1178 } 1202 }
1179 1203
1180 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) 1204 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS)
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/lifetime/application_lifetime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698