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

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

Issue 2788813002: Try to flush DOMStorage too when ending the browsing session.
Patch Set: compile (doh!) Created 3 years, 8 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
« no previous file with comments | « no previous file | chrome/browser/browsing_data/browsing_data_remover_impl_unittest.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 <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
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
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)
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/browsing_data/browsing_data_remover_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698