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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <iterator> | |
| 10 #include <map> | 11 #include <map> |
| 11 #include <utility> | 12 #include <utility> |
| 12 #include <vector> | 13 #include <vector> |
| 13 | 14 |
| 14 #include "base/atomic_ref_count.h" | 15 #include "base/atomic_ref_count.h" |
| 15 #include "base/bind.h" | 16 #include "base/bind.h" |
| 16 #include "base/bind_helpers.h" | 17 #include "base/bind_helpers.h" |
| 17 #include "base/command_line.h" | 18 #include "base/command_line.h" |
| 18 #include "base/debug/crash_logging.h" | 19 #include "base/debug/crash_logging.h" |
| 19 #include "base/debug/leak_annotations.h" | 20 #include "base/debug/leak_annotations.h" |
| (...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 391 // | 392 // |
| 392 // This is important also because in various places, the | 393 // This is important also because in various places, the |
| 393 // IOThread object being NULL is considered synonymous with the | 394 // IOThread object being NULL is considered synonymous with the |
| 394 // IO thread having stopped. | 395 // IO thread having stopped. |
| 395 io_thread_.reset(); | 396 io_thread_.reset(); |
| 396 } | 397 } |
| 397 #endif // !defined(OS_ANDROID) | 398 #endif // !defined(OS_ANDROID) |
| 398 | 399 |
| 399 namespace { | 400 namespace { |
| 400 | 401 |
| 402 using TaskRunnerVector = std::vector<scoped_refptr<base::SequencedTaskRunner>>; | |
| 403 | |
| 401 // Used at the end of session to block the UI thread for completion of sentinel | 404 // Used at the end of session to block the UI thread for completion of sentinel |
| 402 // tasks on the set of threads used to persist profile data and local state. | 405 // tasks on the set of threads used to persist profile data and local state. |
| 403 // This is done to ensure that the data has been persisted to disk before | 406 // This is done to ensure that the data has been persisted to disk before |
| 404 // continuing. | 407 // continuing. |
| 405 class RundownTaskCounter : | 408 class RundownTaskCounter : |
| 406 public base::RefCountedThreadSafe<RundownTaskCounter> { | 409 public base::RefCountedThreadSafe<RundownTaskCounter> { |
| 407 public: | 410 public: |
| 408 RundownTaskCounter(); | 411 RundownTaskCounter(); |
| 409 | 412 |
| 410 // Posts a rundown task to |task_runner|, can be invoked an arbitrary number | 413 // Posts a rundown task to |task_runner|, can be invoked an arbitrary number |
| 411 // of times before calling TimedWait. | 414 // of times before calling TimedWait. |
| 412 void Post(base::SequencedTaskRunner* task_runner); | 415 void Post(base::SequencedTaskRunner* task_runner); |
| 413 | 416 |
| 417 // Posts a rundown task to each runner in |runners|, where the rundown task | |
| 418 // for runner[n+1] is posted during rundown task execution for runner[n]. | |
| 419 void PostSerially(TaskRunnerVector runners); | |
| 420 | |
| 414 // Waits until the count is zero or |end_time| is reached. | 421 // Waits until the count is zero or |end_time| is reached. |
| 415 // This can only be called once per instance. Returns true if a count of zero | 422 // This can only be called once per instance. Returns true if a count of zero |
| 416 // is reached or false if the |end_time| is reached. It is valid to pass an | 423 // is reached or false if the |end_time| is reached. It is valid to pass an |
| 417 // |end_time| in the past. | 424 // |end_time| in the past. |
| 418 bool TimedWaitUntil(const base::TimeTicks& end_time); | 425 bool TimedWaitUntil(const base::TimeTicks& end_time); |
| 419 | 426 |
| 420 private: | 427 private: |
| 421 friend class base::RefCountedThreadSafe<RundownTaskCounter>; | 428 friend class base::RefCountedThreadSafe<RundownTaskCounter>; |
| 422 ~RundownTaskCounter() {} | 429 ~RundownTaskCounter() {} |
| 423 | 430 |
| 424 // Decrements the counter and releases the waitable event on transition to | 431 // Decrements the counter and releases the waitable event on transition to |
| 425 // zero. | 432 // zero. |
| 426 void Decrement(); | 433 void Decrement(); |
| 427 | 434 |
| 435 void RundownSerially(TaskRunnerVector::const_iterator it, | |
| 436 TaskRunnerVector runner); | |
| 437 | |
| 428 // The count starts at one to defer the possibility of one->zero transitions | 438 // The count starts at one to defer the possibility of one->zero transitions |
| 429 // until TimedWait is called. | 439 // until TimedWait is called. |
| 430 base::AtomicRefCount count_; | 440 base::AtomicRefCount count_; |
| 431 base::WaitableEvent waitable_event_; | 441 base::WaitableEvent waitable_event_; |
| 432 | 442 |
| 433 DISALLOW_COPY_AND_ASSIGN(RundownTaskCounter); | 443 DISALLOW_COPY_AND_ASSIGN(RundownTaskCounter); |
| 434 }; | 444 }; |
| 435 | 445 |
| 436 RundownTaskCounter::RundownTaskCounter() | 446 RundownTaskCounter::RundownTaskCounter() |
| 437 : count_(1), | 447 : count_(1), |
| 438 waitable_event_(base::WaitableEvent::ResetPolicy::MANUAL, | 448 waitable_event_(base::WaitableEvent::ResetPolicy::MANUAL, |
| 439 base::WaitableEvent::InitialState::NOT_SIGNALED) {} | 449 base::WaitableEvent::InitialState::NOT_SIGNALED) {} |
| 440 | 450 |
| 441 void RundownTaskCounter::Post(base::SequencedTaskRunner* task_runner) { | 451 void RundownTaskCounter::Post(base::SequencedTaskRunner* task_runner) { |
| 442 // As the count starts off at one, it should never get to zero unless | 452 // As the count starts off at one, it should never get to zero unless |
| 443 // TimedWait has been called. | 453 // TimedWait has been called. |
| 444 DCHECK(!base::AtomicRefCountIsZero(&count_)); | 454 DCHECK(!base::AtomicRefCountIsZero(&count_)); |
| 445 | 455 |
| 446 base::AtomicRefCountInc(&count_); | 456 base::AtomicRefCountInc(&count_); |
| 447 | 457 |
| 448 // The task must be non-nestable to guarantee that it runs after all tasks | 458 // The task must be non-nestable to guarantee that it runs after all tasks |
| 449 // currently scheduled on |task_runner| have completed. | 459 // currently scheduled on |task_runner| have completed. |
| 450 task_runner->PostNonNestableTask(FROM_HERE, | 460 task_runner->PostNonNestableTask(FROM_HERE, |
| 451 base::Bind(&RundownTaskCounter::Decrement, this)); | 461 base::Bind(&RundownTaskCounter::Decrement, this)); |
| 452 } | 462 } |
| 453 | 463 |
| 464 void RundownTaskCounter::PostSerially(TaskRunnerVector runners) { | |
| 465 if (runners.empty()) | |
| 466 return; | |
| 467 base::AtomicRefCountInc(&count_); | |
| 468 TaskRunnerVector::const_iterator it = runners.begin(); | |
| 469 (*it)->PostNonNestableTask( | |
| 470 FROM_HERE, base::Bind(&RundownTaskCounter::RundownSerially, this, it + 1, | |
| 471 base::Passed(&runners))); | |
| 472 } | |
| 473 | |
| 454 void RundownTaskCounter::Decrement() { | 474 void RundownTaskCounter::Decrement() { |
| 455 if (!base::AtomicRefCountDec(&count_)) | 475 if (!base::AtomicRefCountDec(&count_)) |
| 456 waitable_event_.Signal(); | 476 waitable_event_.Signal(); |
| 457 } | 477 } |
| 458 | 478 |
| 459 bool RundownTaskCounter::TimedWaitUntil(const base::TimeTicks& end_time) { | 479 bool RundownTaskCounter::TimedWaitUntil(const base::TimeTicks& end_time) { |
| 460 // Decrement the excess count from the constructor. | 480 // Decrement the excess count from the constructor. |
| 461 Decrement(); | 481 Decrement(); |
| 462 | 482 |
| 463 return waitable_event_.TimedWaitUntil(end_time); | 483 return waitable_event_.TimedWaitUntil(end_time); |
| 464 } | 484 } |
| 465 | 485 |
| 486 void RundownTaskCounter::RundownSerially(TaskRunnerVector::const_iterator it, | |
| 487 TaskRunnerVector runners) { | |
| 488 if (it == runners.end()) { | |
| 489 Decrement(); | |
| 490 return; | |
| 491 } | |
| 492 (*it)->PostNonNestableTask( | |
| 493 FROM_HERE, base::Bind(&RundownTaskCounter::RundownSerially, this, it + 1, | |
| 494 base::Passed(&runners))); | |
| 495 } | |
| 496 | |
| 497 void FlushStoragePartition(scoped_refptr<RundownTaskCounter> rundown_counter, | |
| 498 content::StoragePartition* partition) { | |
| 499 rundown_counter->PostSerially(partition->Flush()); | |
| 500 } | |
| 501 | |
| 466 } // namespace | 502 } // namespace |
| 467 | 503 |
| 468 void BrowserProcessImpl::EndSession() { | 504 void BrowserProcessImpl::EndSession() { |
| 469 // Mark all the profiles as clean. | 505 // Mark all the profiles as clean. |
| 470 ProfileManager* pm = profile_manager(); | 506 ProfileManager* pm = profile_manager(); |
| 471 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); | 507 std::vector<Profile*> profiles(pm->GetLoadedProfiles()); |
| 472 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter()); | 508 scoped_refptr<RundownTaskCounter> rundown_counter(new RundownTaskCounter()); |
| 473 const bool pref_service_enabled = | 509 const bool pref_service_enabled = |
| 474 base::FeatureList::IsEnabled(features::kPrefService); | 510 base::FeatureList::IsEnabled(features::kPrefService); |
| 475 std::vector<scoped_refptr<base::SequencedTaskRunner>> profile_writer_runners; | 511 std::vector<scoped_refptr<base::SequencedTaskRunner>> profile_writer_runners; |
| 476 for (size_t i = 0; i < profiles.size(); ++i) { | 512 for (Profile* profile : profiles) { |
| 477 Profile* profile = profiles[i]; | |
| 478 profile->SetExitType(Profile::EXIT_SESSION_ENDED); | 513 profile->SetExitType(Profile::EXIT_SESSION_ENDED); |
| 479 if (profile->GetPrefs()) { | 514 if (profile->GetPrefs()) { |
| 480 profile->GetPrefs()->CommitPendingWrite(); | 515 profile->GetPrefs()->CommitPendingWrite(); |
| 481 if (pref_service_enabled) { | 516 if (pref_service_enabled) { |
| 482 rundown_counter->Post(content::BrowserThread::GetTaskRunnerForThread( | 517 rundown_counter->Post(content::BrowserThread::GetTaskRunnerForThread( |
| 483 content::BrowserThread::IO) | 518 content::BrowserThread::IO) |
| 484 .get()); | 519 .get()); |
| 485 profile_writer_runners.push_back(profile->GetIOTaskRunner()); | 520 profile_writer_runners.push_back(profile->GetIOTaskRunner()); |
| 486 } else { | 521 } else { |
| 487 rundown_counter->Post(profile->GetIOTaskRunner().get()); | 522 rundown_counter->Post(profile->GetIOTaskRunner().get()); |
| 488 } | 523 } |
| 489 } | 524 } |
| 525 content::BrowserContext::ForEachStoragePartition( | |
| 526 profile, base::Bind(&FlushStoragePartition, rundown_counter)); | |
|
hashimoto
2017/04/04 09:23:24
This shouldn't be put before Local State.
Local St
| |
| 490 } | 527 } |
| 491 | 528 |
| 492 // Tell the metrics service it was cleanly shutdown. | 529 // Tell the metrics service it was cleanly shutdown. |
| 493 metrics::MetricsService* metrics = g_browser_process->metrics_service(); | 530 metrics::MetricsService* metrics = g_browser_process->metrics_service(); |
| 494 if (metrics && local_state()) { | 531 if (metrics && local_state()) { |
| 495 metrics->RecordStartOfSessionEnd(); | 532 metrics->RecordStartOfSessionEnd(); |
| 496 #if !defined(OS_CHROMEOS) | 533 #if !defined(OS_CHROMEOS) |
| 497 // MetricsService lazily writes to prefs, force it to write now. | 534 // MetricsService lazily writes to prefs, force it to write now. |
| 498 // On ChromeOS, chrome gets killed when hangs, so no need to | 535 // On ChromeOS, chrome gets killed when hangs, so no need to |
| 499 // commit metrics::prefs::kStabilitySessionEndCompleted change immediately. | 536 // commit metrics::prefs::kStabilitySessionEndCompleted change immediately. |
| (...skipping 935 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1435 } | 1472 } |
| 1436 | 1473 |
| 1437 void BrowserProcessImpl::OnAutoupdateTimer() { | 1474 void BrowserProcessImpl::OnAutoupdateTimer() { |
| 1438 if (CanAutorestartForUpdate()) { | 1475 if (CanAutorestartForUpdate()) { |
| 1439 DLOG(WARNING) << "Detected update. Restarting browser."; | 1476 DLOG(WARNING) << "Detected update. Restarting browser."; |
| 1440 RestartBackgroundInstance(); | 1477 RestartBackgroundInstance(); |
| 1441 } | 1478 } |
| 1442 } | 1479 } |
| 1443 | 1480 |
| 1444 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) | 1481 #endif // (defined(OS_WIN) || defined(OS_LINUX)) && !defined(OS_CHROMEOS) |
| OLD | NEW |