| 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/metrics/thread_watcher.h" | 5 #include "chrome/browser/metrics/thread_watcher.h" |
| 6 | 6 |
| 7 #include <math.h> // ceil | 7 #include <math.h> // ceil |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 bool ThreadWatcher::IsVeryUnresponsive() { | 402 bool ThreadWatcher::IsVeryUnresponsive() { |
| 403 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 403 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 404 return unresponsive_count_ >= unresponsive_threshold_; | 404 return unresponsive_count_ >= unresponsive_threshold_; |
| 405 } | 405 } |
| 406 | 406 |
| 407 // ThreadWatcherList methods and members. | 407 // ThreadWatcherList methods and members. |
| 408 // | 408 // |
| 409 // static | 409 // static |
| 410 ThreadWatcherList* ThreadWatcherList::g_thread_watcher_list_ = NULL; | 410 ThreadWatcherList* ThreadWatcherList::g_thread_watcher_list_ = NULL; |
| 411 // static | 411 // static |
| 412 bool ThreadWatcherList::g_stopped_ = false; | |
| 413 // static | |
| 414 const int ThreadWatcherList::kSleepSeconds = 1; | 412 const int ThreadWatcherList::kSleepSeconds = 1; |
| 415 // static | 413 // static |
| 416 const int ThreadWatcherList::kUnresponsiveSeconds = 2; | 414 const int ThreadWatcherList::kUnresponsiveSeconds = 2; |
| 417 // static | 415 // static |
| 418 const int ThreadWatcherList::kUnresponsiveCount = 9; | 416 const int ThreadWatcherList::kUnresponsiveCount = 9; |
| 419 // static | 417 // static |
| 420 const int ThreadWatcherList::kLiveThreadsThreshold = 2; | 418 const int ThreadWatcherList::kLiveThreadsThreshold = 2; |
| 421 // static, non-const for tests. | 419 // static, non-const for tests. |
| 422 int ThreadWatcherList::g_initialize_delay_seconds = 120; | 420 int ThreadWatcherList::g_initialize_delay_seconds = 120; |
| 423 | 421 |
| (...skipping 14 matching lines...) Expand all Loading... |
| 438 // TODO(rtenneti): Enable ThreadWatcher. | 436 // TODO(rtenneti): Enable ThreadWatcher. |
| 439 uint32 unresponsive_threshold; | 437 uint32 unresponsive_threshold; |
| 440 CrashOnHangThreadMap crash_on_hang_threads; | 438 CrashOnHangThreadMap crash_on_hang_threads; |
| 441 ParseCommandLine(command_line, | 439 ParseCommandLine(command_line, |
| 442 &unresponsive_threshold, | 440 &unresponsive_threshold, |
| 443 &crash_on_hang_threads); | 441 &crash_on_hang_threads); |
| 444 | 442 |
| 445 ThreadWatcherObserver::SetupNotifications( | 443 ThreadWatcherObserver::SetupNotifications( |
| 446 base::TimeDelta::FromSeconds(kSleepSeconds * unresponsive_threshold)); | 444 base::TimeDelta::FromSeconds(kSleepSeconds * unresponsive_threshold)); |
| 447 | 445 |
| 448 WatchDogThread::PostTask( | |
| 449 FROM_HERE, | |
| 450 base::Bind(&ThreadWatcherList::SetStopped, false)); | |
| 451 | |
| 452 WatchDogThread::PostDelayedTask( | 446 WatchDogThread::PostDelayedTask( |
| 453 FROM_HERE, | 447 FROM_HERE, |
| 454 base::Bind(&ThreadWatcherList::InitializeAndStartWatching, | 448 base::Bind(&ThreadWatcherList::InitializeAndStartWatching, |
| 455 unresponsive_threshold, | 449 unresponsive_threshold, |
| 456 crash_on_hang_threads), | 450 crash_on_hang_threads), |
| 457 base::TimeDelta::FromSeconds(g_initialize_delay_seconds)); | 451 base::TimeDelta::FromSeconds(g_initialize_delay_seconds)); |
| 458 } | 452 } |
| 459 | 453 |
| 460 // static | 454 // static |
| 461 void ThreadWatcherList::StopWatchingAll() { | 455 void ThreadWatcherList::StopWatchingAll() { |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 634 (*crash_on_hang_threads)[thread_name] = crash_data; | 628 (*crash_on_hang_threads)[thread_name] = crash_data; |
| 635 } | 629 } |
| 636 } | 630 } |
| 637 | 631 |
| 638 // static | 632 // static |
| 639 void ThreadWatcherList::InitializeAndStartWatching( | 633 void ThreadWatcherList::InitializeAndStartWatching( |
| 640 uint32 unresponsive_threshold, | 634 uint32 unresponsive_threshold, |
| 641 const CrashOnHangThreadMap& crash_on_hang_threads) { | 635 const CrashOnHangThreadMap& crash_on_hang_threads) { |
| 642 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 636 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 643 | 637 |
| 644 // This method is deferred in relationship to its StopWatchingAll() | |
| 645 // counterpart. If a previous initialization has already happened, or if | |
| 646 // stop has been called, there's nothing left to do here. | |
| 647 if (g_thread_watcher_list_ || g_stopped_) | |
| 648 return; | |
| 649 | |
| 650 ThreadWatcherList* thread_watcher_list = new ThreadWatcherList(); | 638 ThreadWatcherList* thread_watcher_list = new ThreadWatcherList(); |
| 651 CHECK(thread_watcher_list); | 639 CHECK(thread_watcher_list); |
| 652 | 640 |
| 653 BrowserThread::PostTask( | 641 BrowserThread::PostTask( |
| 654 BrowserThread::UI, | 642 BrowserThread::UI, |
| 655 FROM_HERE, | 643 FROM_HERE, |
| 656 base::Bind(&StartupTimeBomb::DisarmStartupTimeBomb)); | 644 base::Bind(&StartupTimeBomb::DisarmStartupTimeBomb)); |
| 657 | 645 |
| 658 const base::TimeDelta kSleepTime = | 646 const base::TimeDelta kSleepTime = |
| 659 base::TimeDelta::FromSeconds(kSleepSeconds); | 647 base::TimeDelta::FromSeconds(kSleepSeconds); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 705 // static | 693 // static |
| 706 void ThreadWatcherList::DeleteAll() { | 694 void ThreadWatcherList::DeleteAll() { |
| 707 if (!WatchDogThread::CurrentlyOnWatchDogThread()) { | 695 if (!WatchDogThread::CurrentlyOnWatchDogThread()) { |
| 708 WatchDogThread::PostTask( | 696 WatchDogThread::PostTask( |
| 709 FROM_HERE, | 697 FROM_HERE, |
| 710 base::Bind(&ThreadWatcherList::DeleteAll)); | 698 base::Bind(&ThreadWatcherList::DeleteAll)); |
| 711 return; | 699 return; |
| 712 } | 700 } |
| 713 | 701 |
| 714 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 702 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 715 | |
| 716 SetStopped(true); | |
| 717 | |
| 718 if (!g_thread_watcher_list_) | 703 if (!g_thread_watcher_list_) |
| 719 return; | 704 return; |
| 720 | 705 |
| 721 // Delete all thread watcher objects. | 706 // Delete all thread watcher objects. |
| 722 while (!g_thread_watcher_list_->registered_.empty()) { | 707 while (!g_thread_watcher_list_->registered_.empty()) { |
| 723 RegistrationList::iterator it = g_thread_watcher_list_->registered_.begin(); | 708 RegistrationList::iterator it = g_thread_watcher_list_->registered_.begin(); |
| 724 delete it->second; | 709 delete it->second; |
| 725 g_thread_watcher_list_->registered_.erase(it); | 710 g_thread_watcher_list_->registered_.erase(it); |
| 726 } | 711 } |
| 727 | 712 |
| 728 delete g_thread_watcher_list_; | 713 delete g_thread_watcher_list_; |
| 729 } | 714 } |
| 730 | 715 |
| 731 // static | 716 // static |
| 732 ThreadWatcher* ThreadWatcherList::Find(const BrowserThread::ID& thread_id) { | 717 ThreadWatcher* ThreadWatcherList::Find(const BrowserThread::ID& thread_id) { |
| 733 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 718 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 734 if (!g_thread_watcher_list_) | 719 if (!g_thread_watcher_list_) |
| 735 return NULL; | 720 return NULL; |
| 736 RegistrationList::iterator it = | 721 RegistrationList::iterator it = |
| 737 g_thread_watcher_list_->registered_.find(thread_id); | 722 g_thread_watcher_list_->registered_.find(thread_id); |
| 738 if (g_thread_watcher_list_->registered_.end() == it) | 723 if (g_thread_watcher_list_->registered_.end() == it) |
| 739 return NULL; | 724 return NULL; |
| 740 return it->second; | 725 return it->second; |
| 741 } | 726 } |
| 742 | 727 |
| 743 // static | |
| 744 void ThreadWatcherList::SetStopped(bool stopped) { | |
| 745 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | |
| 746 g_stopped_ = stopped; | |
| 747 } | |
| 748 | |
| 749 // ThreadWatcherObserver methods and members. | 728 // ThreadWatcherObserver methods and members. |
| 750 // | 729 // |
| 751 // static | 730 // static |
| 752 ThreadWatcherObserver* ThreadWatcherObserver::g_thread_watcher_observer_ = NULL; | 731 ThreadWatcherObserver* ThreadWatcherObserver::g_thread_watcher_observer_ = NULL; |
| 753 | 732 |
| 754 ThreadWatcherObserver::ThreadWatcherObserver( | 733 ThreadWatcherObserver::ThreadWatcherObserver( |
| 755 const base::TimeDelta& wakeup_interval) | 734 const base::TimeDelta& wakeup_interval) |
| 756 : last_wakeup_time_(base::TimeTicks::Now()), | 735 : last_wakeup_time_(base::TimeTicks::Now()), |
| 757 wakeup_interval_(wakeup_interval) { | 736 wakeup_interval_(wakeup_interval) { |
| 758 CHECK(!g_thread_watcher_observer_); | 737 CHECK(!g_thread_watcher_observer_); |
| (...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1006 | 985 |
| 1007 #if defined(OS_WIN) | 986 #if defined(OS_WIN) |
| 1008 // On Windows XP, give twice the time for shutdown. | 987 // On Windows XP, give twice the time for shutdown. |
| 1009 if (base::win::GetVersion() <= base::win::VERSION_XP) | 988 if (base::win::GetVersion() <= base::win::VERSION_XP) |
| 1010 actual_duration *= 2; | 989 actual_duration *= 2; |
| 1011 #endif | 990 #endif |
| 1012 | 991 |
| 1013 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); | 992 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); |
| 1014 shutdown_watchdog_->Arm(); | 993 shutdown_watchdog_->Arm(); |
| 1015 } | 994 } |
| OLD | NEW |