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 <math.h> | 5 #include <math.h> |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
8 #include "base/bind.h" | 8 #include "base/bind.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
12 #include "base/message_loop/message_loop_proxy.h" | 12 #include "base/message_loop/message_loop_proxy.h" |
| 13 #include "base/run_loop.h" |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_split.h" | 15 #include "base/strings/string_split.h" |
15 #include "base/strings/string_tokenizer.h" | 16 #include "base/strings/string_tokenizer.h" |
16 #include "base/synchronization/condition_variable.h" | 17 #include "base/synchronization/condition_variable.h" |
17 #include "base/synchronization/lock.h" | 18 #include "base/synchronization/lock.h" |
18 #include "base/threading/platform_thread.h" | 19 #include "base/threading/platform_thread.h" |
19 #include "base/time/time.h" | 20 #include "base/time/time.h" |
20 #include "build/build_config.h" | 21 #include "build/build_config.h" |
21 #include "chrome/browser/metrics/thread_watcher.h" | 22 #include "chrome/browser/metrics/thread_watcher.h" |
22 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
622 base::Bind(&ThreadWatcher::DeActivateThreadWatching, | 623 base::Bind(&ThreadWatcher::DeActivateThreadWatching, |
623 base::Unretained(io_watcher_))); | 624 base::Unretained(io_watcher_))); |
624 WatchDogThread::PostTask( | 625 WatchDogThread::PostTask( |
625 FROM_HERE, | 626 FROM_HERE, |
626 base::Bind(&ThreadWatcher::DeActivateThreadWatching, | 627 base::Bind(&ThreadWatcher::DeActivateThreadWatching, |
627 base::Unretained(db_watcher_))); | 628 base::Unretained(db_watcher_))); |
628 | 629 |
629 // Wait for the io_watcher_'s VeryLongMethod to finish. | 630 // Wait for the io_watcher_'s VeryLongMethod to finish. |
630 io_watcher_->WaitForWaitStateChange(kUnresponsiveTime * 10, ALL_DONE); | 631 io_watcher_->WaitForWaitStateChange(kUnresponsiveTime * 10, ALL_DONE); |
631 } | 632 } |
| 633 |
| 634 class ThreadWatcherListTest : public ::testing::Test { |
| 635 protected: |
| 636 ThreadWatcherListTest() |
| 637 : done_(&lock_), |
| 638 state_available_(false), |
| 639 has_thread_watcher_list_(false), |
| 640 stopped_(false) { |
| 641 } |
| 642 |
| 643 void ReadStateOnWatchDogThread() { |
| 644 CHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 645 { |
| 646 base::AutoLock auto_lock(lock_); |
| 647 has_thread_watcher_list_ = |
| 648 ThreadWatcherList::g_thread_watcher_list_ != NULL; |
| 649 stopped_ = ThreadWatcherList::g_stopped_; |
| 650 state_available_ = true; |
| 651 } |
| 652 done_.Signal(); |
| 653 } |
| 654 |
| 655 void CheckState(bool has_thread_watcher_list, |
| 656 bool stopped, |
| 657 const char* const msg) { |
| 658 CHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); |
| 659 { |
| 660 base::AutoLock auto_lock(lock_); |
| 661 state_available_ = false; |
| 662 } |
| 663 |
| 664 WatchDogThread::PostTask( |
| 665 FROM_HERE, |
| 666 base::Bind(&ThreadWatcherListTest::ReadStateOnWatchDogThread, |
| 667 base::Unretained(this))); |
| 668 { |
| 669 base::AutoLock auto_lock(lock_); |
| 670 while (!state_available_) |
| 671 done_.Wait(); |
| 672 |
| 673 EXPECT_EQ(has_thread_watcher_list, has_thread_watcher_list_) << msg; |
| 674 EXPECT_EQ(stopped, stopped_) << msg; |
| 675 } |
| 676 } |
| 677 |
| 678 base::Lock lock_; |
| 679 base::ConditionVariable done_; |
| 680 |
| 681 bool state_available_; |
| 682 bool has_thread_watcher_list_; |
| 683 bool stopped_; |
| 684 }; |
| 685 |
| 686 TEST_F(ThreadWatcherListTest, Restart) { |
| 687 ThreadWatcherList::g_initialize_delay_seconds = 1; |
| 688 |
| 689 base::MessageLoopForUI message_loop_for_ui; |
| 690 content::TestBrowserThread ui_thread(BrowserThread::UI, &message_loop_for_ui); |
| 691 |
| 692 scoped_ptr<WatchDogThread> watchdog_thread_(new WatchDogThread()); |
| 693 watchdog_thread_->Start(); |
| 694 |
| 695 // See http://crbug.com/347887. |
| 696 // StartWatchingAll() will PostDelayedTask to create g_thread_watcher_list_, |
| 697 // whilst StopWatchingAll() will just PostTask to destroy it. |
| 698 // Ensure that when Stop is called, Start will NOT create |
| 699 // g_thread_watcher_list_ later on. |
| 700 ThreadWatcherList::StartWatchingAll(*CommandLine::ForCurrentProcess()); |
| 701 ThreadWatcherList::StopWatchingAll(); |
| 702 message_loop_for_ui.PostDelayedTask( |
| 703 FROM_HERE, |
| 704 message_loop_for_ui.QuitClosure(), |
| 705 base::TimeDelta::FromSeconds( |
| 706 ThreadWatcherList::g_initialize_delay_seconds)); |
| 707 message_loop_for_ui.Run(); |
| 708 |
| 709 CheckState(false /* has_thread_watcher_list */, |
| 710 true /* stopped */, |
| 711 "Start / Stopped"); |
| 712 |
| 713 // Proceed with just |StartWatchingAll| and ensure it'll be started. |
| 714 ThreadWatcherList::StartWatchingAll(*CommandLine::ForCurrentProcess()); |
| 715 message_loop_for_ui.PostDelayedTask( |
| 716 FROM_HERE, |
| 717 message_loop_for_ui.QuitClosure(), |
| 718 base::TimeDelta::FromSeconds( |
| 719 ThreadWatcherList::g_initialize_delay_seconds + 1)); |
| 720 message_loop_for_ui.Run(); |
| 721 |
| 722 CheckState(true /* has_thread_watcher_list */, |
| 723 false /* stopped */, |
| 724 "Started"); |
| 725 |
| 726 // Finally, StopWatchingAll() must stop. |
| 727 ThreadWatcherList::StopWatchingAll(); |
| 728 message_loop_for_ui.PostDelayedTask( |
| 729 FROM_HERE, |
| 730 message_loop_for_ui.QuitClosure(), |
| 731 base::TimeDelta::FromSeconds( |
| 732 ThreadWatcherList::g_initialize_delay_seconds)); |
| 733 message_loop_for_ui.Run(); |
| 734 |
| 735 CheckState(false /* has_thread_watcher_list */, |
| 736 true /* stopped */, |
| 737 "Stopped"); |
| 738 } |
OLD | NEW |