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 |