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 <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <map> | 10 #include <map> |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
69 #include "chrome/browser/printing/print_preview_dialog_controller.h" | 69 #include "chrome/browser/printing/print_preview_dialog_controller.h" |
70 #include "chrome/browser/profiles/profile_manager.h" | 70 #include "chrome/browser/profiles/profile_manager.h" |
71 #include "chrome/browser/safe_browsing/safe_browsing_service.h" | 71 #include "chrome/browser/safe_browsing/safe_browsing_service.h" |
72 #include "chrome/browser/shell_integration.h" | 72 #include "chrome/browser/shell_integration.h" |
73 #include "chrome/browser/status_icons/status_tray.h" | 73 #include "chrome/browser/status_icons/status_tray.h" |
74 #include "chrome/browser/ui/browser_dialogs.h" | 74 #include "chrome/browser/ui/browser_dialogs.h" |
75 #include "chrome/browser/ui/browser_finder.h" | 75 #include "chrome/browser/ui/browser_finder.h" |
76 #include "chrome/browser/update_client/chrome_update_query_params_delegate.h" | 76 #include "chrome/browser/update_client/chrome_update_query_params_delegate.h" |
77 #include "chrome/common/channel_info.h" | 77 #include "chrome/common/channel_info.h" |
78 #include "chrome/common/chrome_constants.h" | 78 #include "chrome/common/chrome_constants.h" |
| 79 #include "chrome/common/chrome_features.h" |
79 #include "chrome/common/chrome_paths.h" | 80 #include "chrome/common/chrome_paths.h" |
80 #include "chrome/common/chrome_switches.h" | 81 #include "chrome/common/chrome_switches.h" |
81 #include "chrome/common/crash_keys.h" | 82 #include "chrome/common/crash_keys.h" |
82 #include "chrome/common/extensions/chrome_extensions_client.h" | 83 #include "chrome/common/extensions/chrome_extensions_client.h" |
83 #include "chrome/common/extensions/extension_process_policy.h" | 84 #include "chrome/common/extensions/extension_process_policy.h" |
84 #include "chrome/common/features.h" | 85 #include "chrome/common/features.h" |
85 #include "chrome/common/pref_names.h" | 86 #include "chrome/common/pref_names.h" |
86 #include "chrome/common/switch_utils.h" | 87 #include "chrome/common/switch_utils.h" |
87 #include "chrome/common/url_constants.h" | 88 #include "chrome/common/url_constants.h" |
88 #include "chrome/installer/util/google_update_settings.h" | 89 #include "chrome/installer/util/google_update_settings.h" |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 // How often to check if the persistent instance of Chrome needs to restart | 187 // How often to check if the persistent instance of Chrome needs to restart |
187 // to install an update. | 188 // to install an update. |
188 static const int kUpdateCheckIntervalHours = 6; | 189 static const int kUpdateCheckIntervalHours = 6; |
189 #endif | 190 #endif |
190 | 191 |
191 #if defined(USE_X11) || defined(OS_WIN) || defined(USE_OZONE) | 192 #if defined(USE_X11) || defined(OS_WIN) || defined(USE_OZONE) |
192 // How long to wait for the File thread to complete during EndSession, on Linux | 193 // How long to wait for the File thread to complete during EndSession, on Linux |
193 // and Windows. We have a timeout here because we're unable to run the UI | 194 // and Windows. We have a timeout here because we're unable to run the UI |
194 // messageloop and there's some deadlock risk. Our only option is to exit | 195 // messageloop and there's some deadlock risk. Our only option is to exit |
195 // anyway. | 196 // anyway. |
196 static const int kEndSessionTimeoutSeconds = 10; | 197 static constexpr base::TimeDelta kEndSessionTimeout = |
| 198 base::TimeDelta::FromSeconds(10); |
197 #endif | 199 #endif |
198 | 200 |
199 using content::BrowserThread; | 201 using content::BrowserThread; |
200 using content::ChildProcessSecurityPolicy; | 202 using content::ChildProcessSecurityPolicy; |
201 using content::PluginService; | 203 using content::PluginService; |
202 using content::ResourceDispatcherHost; | 204 using content::ResourceDispatcherHost; |
203 | 205 |
204 rappor::RapporService* GetBrowserRapporService() { | 206 rappor::RapporService* GetBrowserRapporService() { |
205 if (g_browser_process != nullptr) | 207 if (g_browser_process != nullptr) |
206 return g_browser_process->rappor_service(); | 208 return g_browser_process->rappor_service(); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 // continuing. | 404 // continuing. |
403 class RundownTaskCounter : | 405 class RundownTaskCounter : |
404 public base::RefCountedThreadSafe<RundownTaskCounter> { | 406 public base::RefCountedThreadSafe<RundownTaskCounter> { |
405 public: | 407 public: |
406 RundownTaskCounter(); | 408 RundownTaskCounter(); |
407 | 409 |
408 // Posts a rundown task to |task_runner|, can be invoked an arbitrary number | 410 // Posts a rundown task to |task_runner|, can be invoked an arbitrary number |
409 // of times before calling TimedWait. | 411 // of times before calling TimedWait. |
410 void Post(base::SequencedTaskRunner* task_runner); | 412 void Post(base::SequencedTaskRunner* task_runner); |
411 | 413 |
412 // Waits until the count is zero or |max_time| has passed. | 414 // Waits until the count is zero or |end_time| is reached. |
413 // This can only be called once per instance. | 415 // This can only be called once per instance. Returns true if a count of zero |
414 bool TimedWait(const base::TimeDelta& max_time); | 416 // is reached or false if the |end_time| is reached. It is valid to pass an |
| 417 // |end_time| in the past. |
| 418 bool TimedWaitUntil(const base::TimeTicks& end_time); |
415 | 419 |
416 private: | 420 private: |
417 friend class base::RefCountedThreadSafe<RundownTaskCounter>; | 421 friend class base::RefCountedThreadSafe<RundownTaskCounter>; |
418 ~RundownTaskCounter() {} | 422 ~RundownTaskCounter() {} |
419 | 423 |
420 // Decrements the counter and releases the waitable event on transition to | 424 // Decrements the counter and releases the waitable event on transition to |
421 // zero. | 425 // zero. |
422 void Decrement(); | 426 void Decrement(); |
423 | 427 |
424 // The count starts at one to defer the possibility of one->zero transitions | 428 // The count starts at one to defer the possibility of one->zero transitions |
(...skipping 20 matching lines...) Expand all Loading... |
445 // currently scheduled on |task_runner| have completed. | 449 // currently scheduled on |task_runner| have completed. |
446 task_runner->PostNonNestableTask(FROM_HERE, | 450 task_runner->PostNonNestableTask(FROM_HERE, |
447 base::Bind(&RundownTaskCounter::Decrement, this)); | 451 base::Bind(&RundownTaskCounter::Decrement, this)); |
448 } | 452 } |
449 | 453 |
450 void RundownTaskCounter::Decrement() { | 454 void RundownTaskCounter::Decrement() { |
451 if (!base::AtomicRefCountDec(&count_)) | 455 if (!base::AtomicRefCountDec(&count_)) |
452 waitable_event_.Signal(); | 456 waitable_event_.Signal(); |
453 } | 457 } |
454 | 458 |
455 bool RundownTaskCounter::TimedWait(const base::TimeDelta& max_time) { | 459 bool RundownTaskCounter::TimedWaitUntil(const base::TimeTicks& end_time) { |
456 // Decrement the excess count from the constructor. | 460 // Decrement the excess count from the constructor. |
457 Decrement(); | 461 Decrement(); |
458 | 462 |
459 return waitable_event_.TimedWait(max_time); | 463 return waitable_event_.TimedWaitUntil(end_time); |
460 } | 464 } |
461 | 465 |
462 } // namespace | 466 } // namespace |
463 | 467 |
464 void BrowserProcessImpl::EndSession() { | 468 void BrowserProcessImpl::EndSession() { |
465 // Mark all the profiles as clean. | 469 // Mark all the profiles as clean. |
466 ProfileManager* pm = profile_manager(); | 470 ProfileManager* pm = profile_manager(); |
467 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); | 471 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); |
468 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter()); | 472 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter()); |
| 473 const bool pref_service_enabled = |
| 474 base::FeatureList::IsEnabled(features::kPrefService); |
| 475 std::vector<scoped_refptr<base::SequencedTaskRunner>> profile_writer_runners; |
469 for (size_t i = 0; i < profiles.size(); ++i) { | 476 for (size_t i = 0; i < profiles.size(); ++i) { |
470 Profile* profile = profiles[i]; | 477 Profile* profile = profiles[i]; |
471 profile->SetExitType(Profile::EXIT_SESSION_ENDED); | 478 profile->SetExitType(Profile::EXIT_SESSION_ENDED); |
472 if (profile->GetPrefs()) { | 479 if (profile->GetPrefs()) { |
473 profile->GetPrefs()->CommitPendingWrite(); | 480 profile->GetPrefs()->CommitPendingWrite(); |
474 rundown_counter->Post(profile->GetIOTaskRunner().get()); | 481 if (pref_service_enabled) { |
| 482 rundown_counter->Post(content::BrowserThread::GetTaskRunnerForThread( |
| 483 content::BrowserThread::IO) |
| 484 .get()); |
| 485 profile_writer_runners.push_back(profile->GetIOTaskRunner()); |
| 486 } else { |
| 487 rundown_counter->Post(profile->GetIOTaskRunner().get()); |
| 488 } |
475 } | 489 } |
476 } | 490 } |
477 | 491 |
478 // Tell the metrics service it was cleanly shutdown. | 492 // Tell the metrics service it was cleanly shutdown. |
479 metrics::MetricsService* metrics = g_browser_process->metrics_service(); | 493 metrics::MetricsService* metrics = g_browser_process->metrics_service(); |
480 if (metrics && local_state()) { | 494 if (metrics && local_state()) { |
481 metrics->RecordStartOfSessionEnd(); | 495 metrics->RecordStartOfSessionEnd(); |
482 #if !defined(OS_CHROMEOS) | 496 #if !defined(OS_CHROMEOS) |
483 // MetricsService lazily writes to prefs, force it to write now. | 497 // MetricsService lazily writes to prefs, force it to write now. |
484 // On ChromeOS, chrome gets killed when hangs, so no need to | 498 // On ChromeOS, chrome gets killed when hangs, so no need to |
(...skipping 20 matching lines...) Expand all Loading... |
505 // | 519 // |
506 // On Windows, we previously posted a message to FILE and then ran a nested | 520 // On Windows, we previously posted a message to FILE and then ran a nested |
507 // message loop, waiting for that message to be processed until quitting. | 521 // message loop, waiting for that message to be processed until quitting. |
508 // However, doing so means that other messages will also be processed. In | 522 // However, doing so means that other messages will also be processed. In |
509 // particular, if the GPU process host notices that the GPU has been killed | 523 // particular, if the GPU process host notices that the GPU has been killed |
510 // during shutdown, it races exiting the nested loop with the process host | 524 // during shutdown, it races exiting the nested loop with the process host |
511 // blocking the message loop attempting to re-establish a connection to the | 525 // blocking the message loop attempting to re-establish a connection to the |
512 // GPU process synchronously. Because the system may not be allowing | 526 // GPU process synchronously. Because the system may not be allowing |
513 // processes to launch, this can result in a hang. See | 527 // processes to launch, this can result in a hang. See |
514 // http://crbug.com/318527. | 528 // http://crbug.com/318527. |
515 rundown_counter->TimedWait( | 529 const base::TimeTicks end_time = base::TimeTicks::Now() + kEndSessionTimeout; |
516 base::TimeDelta::FromSeconds(kEndSessionTimeoutSeconds)); | 530 const bool timed_out = !rundown_counter->TimedWaitUntil(end_time); |
| 531 if (timed_out || !pref_service_enabled) |
| 532 return; |
| 533 |
| 534 scoped_refptr<RundownTaskCounter> profile_write_rundown_counter( |
| 535 new RundownTaskCounter()); |
| 536 for (auto& profile_writer_runner : profile_writer_runners) |
| 537 profile_write_rundown_counter->Post(profile_writer_runner.get()); |
| 538 profile_write_rundown_counter->TimedWaitUntil(end_time); |
517 #else | 539 #else |
518 NOTIMPLEMENTED(); | 540 NOTIMPLEMENTED(); |
519 #endif | 541 #endif |
520 } | 542 } |
521 | 543 |
522 metrics_services_manager::MetricsServicesManager* | 544 metrics_services_manager::MetricsServicesManager* |
523 BrowserProcessImpl::GetMetricsServicesManager() { | 545 BrowserProcessImpl::GetMetricsServicesManager() { |
524 DCHECK(CalledOnValidThread()); | 546 DCHECK(CalledOnValidThread()); |
525 if (!metrics_services_manager_) { | 547 if (!metrics_services_manager_) { |
526 metrics_services_manager_.reset( | 548 metrics_services_manager_.reset( |
(...skipping 886 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1413 } | 1435 } |
1414 | 1436 |
1415 void BrowserProcessImpl::OnAutoupdateTimer() { | 1437 void BrowserProcessImpl::OnAutoupdateTimer() { |
1416 if (CanAutorestartForUpdate()) { | 1438 if (CanAutorestartForUpdate()) { |
1417 DLOG(WARNING) << "Detected update. Restarting browser."; | 1439 DLOG(WARNING) << "Detected update. Restarting browser."; |
1418 RestartBackgroundInstance(); | 1440 RestartBackgroundInstance(); |
1419 } | 1441 } |
1420 } | 1442 } |
1421 | 1443 |
1422 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) | 1444 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) |
OLD | NEW |