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" |
11 #include "base/debug/dump_without_crashing.h" | 11 #include "base/debug/dump_without_crashing.h" |
12 #include "base/lazy_instance.h" | 12 #include "base/lazy_instance.h" |
| 13 #include "base/location.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/strings/stringprintf.h" | 17 #include "base/strings/stringprintf.h" |
| 18 #include "base/thread_task_runner_handle.h" |
17 #include "base/threading/thread_restrictions.h" | 19 #include "base/threading/thread_restrictions.h" |
18 #include "build/build_config.h" | 20 #include "build/build_config.h" |
19 #include "chrome/browser/chrome_notification_types.h" | 21 #include "chrome/browser/chrome_notification_types.h" |
20 #include "chrome/browser/metrics/thread_watcher_report_hang.h" | 22 #include "chrome/browser/metrics/thread_watcher_report_hang.h" |
21 #include "chrome/common/chrome_switches.h" | 23 #include "chrome/common/chrome_switches.h" |
22 #include "chrome/common/chrome_version_info.h" | 24 #include "chrome/common/chrome_version_info.h" |
23 #include "chrome/common/logging_chrome.h" | 25 #include "chrome/common/logging_chrome.h" |
24 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
25 | 27 |
26 #if defined(OS_WIN) | 28 #if defined(OS_WIN) |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 return; | 85 return; |
84 watcher->ActivateThreadWatching(); | 86 watcher->ActivateThreadWatching(); |
85 } | 87 } |
86 | 88 |
87 void ThreadWatcher::ActivateThreadWatching() { | 89 void ThreadWatcher::ActivateThreadWatching() { |
88 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 90 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
89 if (active_) return; | 91 if (active_) return; |
90 active_ = true; | 92 active_ = true; |
91 ping_count_ = unresponsive_threshold_; | 93 ping_count_ = unresponsive_threshold_; |
92 ResetHangCounters(); | 94 ResetHangCounters(); |
93 base::MessageLoop::current()->PostTask( | 95 base::ThreadTaskRunnerHandle::Get()->PostTask( |
94 FROM_HERE, | 96 FROM_HERE, base::Bind(&ThreadWatcher::PostPingMessage, |
95 base::Bind(&ThreadWatcher::PostPingMessage, | 97 weak_ptr_factory_.GetWeakPtr())); |
96 weak_ptr_factory_.GetWeakPtr())); | |
97 } | 98 } |
98 | 99 |
99 void ThreadWatcher::DeActivateThreadWatching() { | 100 void ThreadWatcher::DeActivateThreadWatching() { |
100 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 101 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
101 active_ = false; | 102 active_ = false; |
102 ping_count_ = 0; | 103 ping_count_ = 0; |
103 weak_ptr_factory_.InvalidateWeakPtrs(); | 104 weak_ptr_factory_.InvalidateWeakPtrs(); |
104 } | 105 } |
105 | 106 |
106 void ThreadWatcher::WakeUp() { | 107 void ThreadWatcher::WakeUp() { |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
175 | 176 |
176 // Increment sequence number for the next ping message to indicate watched | 177 // Increment sequence number for the next ping message to indicate watched |
177 // thread is responsive. | 178 // thread is responsive. |
178 ++ping_sequence_number_; | 179 ++ping_sequence_number_; |
179 | 180 |
180 // If we have stopped watching or if the user is idle, then stop sending | 181 // If we have stopped watching or if the user is idle, then stop sending |
181 // ping messages. | 182 // ping messages. |
182 if (!active_ || --ping_count_ <= 0) | 183 if (!active_ || --ping_count_ <= 0) |
183 return; | 184 return; |
184 | 185 |
185 base::MessageLoop::current()->PostDelayedTask( | 186 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
186 FROM_HERE, | 187 FROM_HERE, base::Bind(&ThreadWatcher::PostPingMessage, |
187 base::Bind(&ThreadWatcher::PostPingMessage, | 188 weak_ptr_factory_.GetWeakPtr()), |
188 weak_ptr_factory_.GetWeakPtr()), | |
189 sleep_time_); | 189 sleep_time_); |
190 } | 190 } |
191 | 191 |
192 void ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) { | 192 void ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) { |
193 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 193 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
194 // If we have stopped watching then consider thread as responding. | 194 // If we have stopped watching then consider thread as responding. |
195 if (!active_) { | 195 if (!active_) { |
196 responsive_ = true; | 196 responsive_ = true; |
197 return; | 197 return; |
198 } | 198 } |
199 // If the latest ping_sequence_number_ is not same as the ping_sequence_number | 199 // If the latest ping_sequence_number_ is not same as the ping_sequence_number |
200 // that is passed in, then we can assume OnPongMessage was called. | 200 // that is passed in, then we can assume OnPongMessage was called. |
201 // OnPongMessage increments ping_sequence_number_. | 201 // OnPongMessage increments ping_sequence_number_. |
202 if (ping_sequence_number_ != ping_sequence_number) { | 202 if (ping_sequence_number_ != ping_sequence_number) { |
203 // Reset unresponsive_count_ to zero because we got a response from the | 203 // Reset unresponsive_count_ to zero because we got a response from the |
204 // watched thread. | 204 // watched thread. |
205 ResetHangCounters(); | 205 ResetHangCounters(); |
206 | 206 |
207 responsive_ = true; | 207 responsive_ = true; |
208 return; | 208 return; |
209 } | 209 } |
210 // Record that we got no response from watched thread. | 210 // Record that we got no response from watched thread. |
211 GotNoResponse(); | 211 GotNoResponse(); |
212 | 212 |
213 // Post a task to check the responsiveness of watched thread. | 213 // Post a task to check the responsiveness of watched thread. |
214 base::MessageLoop::current()->PostDelayedTask( | 214 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
215 FROM_HERE, | 215 FROM_HERE, |
216 base::Bind(&ThreadWatcher::OnCheckResponsiveness, | 216 base::Bind(&ThreadWatcher::OnCheckResponsiveness, |
217 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), | 217 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), |
218 unresponsive_time_); | 218 unresponsive_time_); |
219 responsive_ = false; | 219 responsive_ = false; |
220 } | 220 } |
221 | 221 |
222 void ThreadWatcher::Initialize() { | 222 void ThreadWatcher::Initialize() { |
223 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 223 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
224 ThreadWatcherList::Register(this); | 224 ThreadWatcherList::Register(this); |
(...skipping 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
756 bool WatchDogThread::PostTaskHelper( | 756 bool WatchDogThread::PostTaskHelper( |
757 const tracked_objects::Location& from_here, | 757 const tracked_objects::Location& from_here, |
758 const base::Closure& task, | 758 const base::Closure& task, |
759 base::TimeDelta delay) { | 759 base::TimeDelta delay) { |
760 { | 760 { |
761 base::AutoLock lock(g_watchdog_lock.Get()); | 761 base::AutoLock lock(g_watchdog_lock.Get()); |
762 | 762 |
763 base::MessageLoop* message_loop = g_watchdog_thread ? | 763 base::MessageLoop* message_loop = g_watchdog_thread ? |
764 g_watchdog_thread->message_loop() : NULL; | 764 g_watchdog_thread->message_loop() : NULL; |
765 if (message_loop) { | 765 if (message_loop) { |
766 message_loop->PostDelayedTask(from_here, task, delay); | 766 message_loop->task_runner()->PostDelayedTask(from_here, task, delay); |
767 return true; | 767 return true; |
768 } | 768 } |
769 } | 769 } |
770 | 770 |
771 return false; | 771 return false; |
772 } | 772 } |
773 | 773 |
774 void WatchDogThread::Init() { | 774 void WatchDogThread::Init() { |
775 // This thread shouldn't be allowed to perform any blocking disk I/O. | 775 // This thread shouldn't be allowed to perform any blocking disk I/O. |
776 base::ThreadRestrictions::SetIOAllowed(false); | 776 base::ThreadRestrictions::SetIOAllowed(false); |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 void StartupTimeBomb::DeleteStartupWatchdog() { | 877 void StartupTimeBomb::DeleteStartupWatchdog() { |
878 DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); | 878 DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); |
879 if (startup_watchdog_->IsJoinable()) { | 879 if (startup_watchdog_->IsJoinable()) { |
880 // Allow the watchdog thread to shutdown on UI. Watchdog thread shutdowns | 880 // Allow the watchdog thread to shutdown on UI. Watchdog thread shutdowns |
881 // very fast. | 881 // very fast. |
882 base::ThreadRestrictions::SetIOAllowed(true); | 882 base::ThreadRestrictions::SetIOAllowed(true); |
883 delete startup_watchdog_; | 883 delete startup_watchdog_; |
884 startup_watchdog_ = NULL; | 884 startup_watchdog_ = NULL; |
885 return; | 885 return; |
886 } | 886 } |
887 base::MessageLoop::current()->PostDelayedTask( | 887 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
888 FROM_HERE, | 888 FROM_HERE, base::Bind(&StartupTimeBomb::DeleteStartupWatchdog, |
889 base::Bind(&StartupTimeBomb::DeleteStartupWatchdog, | 889 base::Unretained(this)), |
890 base::Unretained(this)), | |
891 base::TimeDelta::FromSeconds(10)); | 890 base::TimeDelta::FromSeconds(10)); |
892 } | 891 } |
893 | 892 |
894 // static | 893 // static |
895 void StartupTimeBomb::DisarmStartupTimeBomb() { | 894 void StartupTimeBomb::DisarmStartupTimeBomb() { |
896 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 895 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
897 if (g_startup_timebomb_) | 896 if (g_startup_timebomb_) |
898 g_startup_timebomb_->Disarm(); | 897 g_startup_timebomb_->Disarm(); |
899 } | 898 } |
900 | 899 |
(...skipping 30 matching lines...) Expand all Loading... |
931 | 930 |
932 #if defined(OS_WIN) | 931 #if defined(OS_WIN) |
933 // On Windows XP, give twice the time for shutdown. | 932 // On Windows XP, give twice the time for shutdown. |
934 if (base::win::GetVersion() <= base::win::VERSION_XP) | 933 if (base::win::GetVersion() <= base::win::VERSION_XP) |
935 actual_duration *= 2; | 934 actual_duration *= 2; |
936 #endif | 935 #endif |
937 | 936 |
938 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); | 937 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); |
939 shutdown_watchdog_->Arm(); | 938 shutdown_watchdog_->Arm(); |
940 } | 939 } |
OLD | NEW |