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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 return; | 177 return; |
178 watcher->ActivateThreadWatching(); | 178 watcher->ActivateThreadWatching(); |
179 } | 179 } |
180 | 180 |
181 void ThreadWatcher::ActivateThreadWatching() { | 181 void ThreadWatcher::ActivateThreadWatching() { |
182 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 182 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
183 if (active_) return; | 183 if (active_) return; |
184 active_ = true; | 184 active_ = true; |
185 ping_count_ = unresponsive_threshold_; | 185 ping_count_ = unresponsive_threshold_; |
186 ResetHangCounters(); | 186 ResetHangCounters(); |
187 MessageLoop::current()->PostTask( | 187 base::MessageLoop::current()->PostTask( |
188 FROM_HERE, | 188 FROM_HERE, |
189 base::Bind(&ThreadWatcher::PostPingMessage, | 189 base::Bind(&ThreadWatcher::PostPingMessage, |
190 weak_ptr_factory_.GetWeakPtr())); | 190 weak_ptr_factory_.GetWeakPtr())); |
191 } | 191 } |
192 | 192 |
193 void ThreadWatcher::DeActivateThreadWatching() { | 193 void ThreadWatcher::DeActivateThreadWatching() { |
194 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 194 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
195 active_ = false; | 195 active_ = false; |
196 ping_count_ = 0; | 196 ping_count_ = 0; |
197 weak_ptr_factory_.InvalidateWeakPtrs(); | 197 weak_ptr_factory_.InvalidateWeakPtrs(); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 // Send a ping message to the watched thread. Callback will be called on | 233 // Send a ping message to the watched thread. Callback will be called on |
234 // the WatchDogThread. | 234 // the WatchDogThread. |
235 base::Closure callback( | 235 base::Closure callback( |
236 base::Bind(&ThreadWatcher::OnPongMessage, weak_ptr_factory_.GetWeakPtr(), | 236 base::Bind(&ThreadWatcher::OnPongMessage, weak_ptr_factory_.GetWeakPtr(), |
237 ping_sequence_number_)); | 237 ping_sequence_number_)); |
238 if (watched_loop_->PostTask( | 238 if (watched_loop_->PostTask( |
239 FROM_HERE, | 239 FROM_HERE, |
240 base::Bind(&ThreadWatcher::OnPingMessage, thread_id_, | 240 base::Bind(&ThreadWatcher::OnPingMessage, thread_id_, |
241 callback))) { | 241 callback))) { |
242 // Post a task to check the responsiveness of watched thread. | 242 // Post a task to check the responsiveness of watched thread. |
243 MessageLoop::current()->PostDelayedTask( | 243 base::MessageLoop::current()->PostDelayedTask( |
244 FROM_HERE, | 244 FROM_HERE, |
245 base::Bind(&ThreadWatcher::OnCheckResponsiveness, | 245 base::Bind(&ThreadWatcher::OnCheckResponsiveness, |
246 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), | 246 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), |
247 unresponsive_time_); | 247 unresponsive_time_); |
248 } else { | 248 } else { |
249 // Watched thread might have gone away, stop watching it. | 249 // Watched thread might have gone away, stop watching it. |
250 DeActivateThreadWatching(); | 250 DeActivateThreadWatching(); |
251 } | 251 } |
252 } | 252 } |
253 | 253 |
(...skipping 15 matching lines...) Expand all Loading... |
269 | 269 |
270 // Increment sequence number for the next ping message to indicate watched | 270 // Increment sequence number for the next ping message to indicate watched |
271 // thread is responsive. | 271 // thread is responsive. |
272 ++ping_sequence_number_; | 272 ++ping_sequence_number_; |
273 | 273 |
274 // If we have stopped watching or if the user is idle, then stop sending | 274 // If we have stopped watching or if the user is idle, then stop sending |
275 // ping messages. | 275 // ping messages. |
276 if (!active_ || --ping_count_ <= 0) | 276 if (!active_ || --ping_count_ <= 0) |
277 return; | 277 return; |
278 | 278 |
279 MessageLoop::current()->PostDelayedTask( | 279 base::MessageLoop::current()->PostDelayedTask( |
280 FROM_HERE, | 280 FROM_HERE, |
281 base::Bind(&ThreadWatcher::PostPingMessage, | 281 base::Bind(&ThreadWatcher::PostPingMessage, |
282 weak_ptr_factory_.GetWeakPtr()), | 282 weak_ptr_factory_.GetWeakPtr()), |
283 sleep_time_); | 283 sleep_time_); |
284 } | 284 } |
285 | 285 |
286 void ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) { | 286 void ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) { |
287 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 287 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
288 // If we have stopped watching then consider thread as responding. | 288 // If we have stopped watching then consider thread as responding. |
289 if (!active_) { | 289 if (!active_) { |
290 responsive_ = true; | 290 responsive_ = true; |
291 return; | 291 return; |
292 } | 292 } |
293 // If the latest ping_sequence_number_ is not same as the ping_sequence_number | 293 // If the latest ping_sequence_number_ is not same as the ping_sequence_number |
294 // that is passed in, then we can assume OnPongMessage was called. | 294 // that is passed in, then we can assume OnPongMessage was called. |
295 // OnPongMessage increments ping_sequence_number_. | 295 // OnPongMessage increments ping_sequence_number_. |
296 if (ping_sequence_number_ != ping_sequence_number) { | 296 if (ping_sequence_number_ != ping_sequence_number) { |
297 // Reset unresponsive_count_ to zero because we got a response from the | 297 // Reset unresponsive_count_ to zero because we got a response from the |
298 // watched thread. | 298 // watched thread. |
299 ResetHangCounters(); | 299 ResetHangCounters(); |
300 | 300 |
301 responsive_ = true; | 301 responsive_ = true; |
302 return; | 302 return; |
303 } | 303 } |
304 // Record that we got no response from watched thread. | 304 // Record that we got no response from watched thread. |
305 GotNoResponse(); | 305 GotNoResponse(); |
306 | 306 |
307 // Post a task to check the responsiveness of watched thread. | 307 // Post a task to check the responsiveness of watched thread. |
308 MessageLoop::current()->PostDelayedTask( | 308 base::MessageLoop::current()->PostDelayedTask( |
309 FROM_HERE, | 309 FROM_HERE, |
310 base::Bind(&ThreadWatcher::OnCheckResponsiveness, | 310 base::Bind(&ThreadWatcher::OnCheckResponsiveness, |
311 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), | 311 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), |
312 unresponsive_time_); | 312 unresponsive_time_); |
313 responsive_ = false; | 313 responsive_ = false; |
314 } | 314 } |
315 | 315 |
316 void ThreadWatcher::Initialize() { | 316 void ThreadWatcher::Initialize() { |
317 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 317 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
318 ThreadWatcherList::Register(this); | 318 ThreadWatcherList::Register(this); |
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
780 } | 780 } |
781 | 781 |
782 WatchDogThread::~WatchDogThread() { | 782 WatchDogThread::~WatchDogThread() { |
783 Stop(); | 783 Stop(); |
784 } | 784 } |
785 | 785 |
786 // static | 786 // static |
787 bool WatchDogThread::CurrentlyOnWatchDogThread() { | 787 bool WatchDogThread::CurrentlyOnWatchDogThread() { |
788 base::AutoLock lock(g_watchdog_lock.Get()); | 788 base::AutoLock lock(g_watchdog_lock.Get()); |
789 return g_watchdog_thread && | 789 return g_watchdog_thread && |
790 g_watchdog_thread->message_loop() == MessageLoop::current(); | 790 g_watchdog_thread->message_loop() == base::MessageLoop::current(); |
791 } | 791 } |
792 | 792 |
793 // static | 793 // static |
794 bool WatchDogThread::PostTask(const tracked_objects::Location& from_here, | 794 bool WatchDogThread::PostTask(const tracked_objects::Location& from_here, |
795 const base::Closure& task) { | 795 const base::Closure& task) { |
796 return PostTaskHelper(from_here, task, base::TimeDelta()); | 796 return PostTaskHelper(from_here, task, base::TimeDelta()); |
797 } | 797 } |
798 | 798 |
799 // static | 799 // static |
800 bool WatchDogThread::PostDelayedTask(const tracked_objects::Location& from_here, | 800 bool WatchDogThread::PostDelayedTask(const tracked_objects::Location& from_here, |
801 const base::Closure& task, | 801 const base::Closure& task, |
802 base::TimeDelta delay) { | 802 base::TimeDelta delay) { |
803 return PostTaskHelper(from_here, task, delay); | 803 return PostTaskHelper(from_here, task, delay); |
804 } | 804 } |
805 | 805 |
806 // static | 806 // static |
807 bool WatchDogThread::PostTaskHelper( | 807 bool WatchDogThread::PostTaskHelper( |
808 const tracked_objects::Location& from_here, | 808 const tracked_objects::Location& from_here, |
809 const base::Closure& task, | 809 const base::Closure& task, |
810 base::TimeDelta delay) { | 810 base::TimeDelta delay) { |
811 { | 811 { |
812 base::AutoLock lock(g_watchdog_lock.Get()); | 812 base::AutoLock lock(g_watchdog_lock.Get()); |
813 | 813 |
814 MessageLoop* message_loop = g_watchdog_thread ? | 814 base::MessageLoop* message_loop = g_watchdog_thread ? |
815 g_watchdog_thread->message_loop() : NULL; | 815 g_watchdog_thread->message_loop() : NULL; |
816 if (message_loop) { | 816 if (message_loop) { |
817 message_loop->PostDelayedTask(from_here, task, delay); | 817 message_loop->PostDelayedTask(from_here, task, delay); |
818 return true; | 818 return true; |
819 } | 819 } |
820 } | 820 } |
821 | 821 |
822 return false; | 822 return false; |
823 } | 823 } |
824 | 824 |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
926 void StartupTimeBomb::DeleteStartupWatchdog() { | 926 void StartupTimeBomb::DeleteStartupWatchdog() { |
927 DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); | 927 DCHECK_EQ(thread_id_, base::PlatformThread::CurrentId()); |
928 if (startup_watchdog_->IsJoinable()) { | 928 if (startup_watchdog_->IsJoinable()) { |
929 // Allow the watchdog thread to shutdown on UI. Watchdog thread shutdowns | 929 // Allow the watchdog thread to shutdown on UI. Watchdog thread shutdowns |
930 // very fast. | 930 // very fast. |
931 base::ThreadRestrictions::SetIOAllowed(true); | 931 base::ThreadRestrictions::SetIOAllowed(true); |
932 delete startup_watchdog_; | 932 delete startup_watchdog_; |
933 startup_watchdog_ = NULL; | 933 startup_watchdog_ = NULL; |
934 return; | 934 return; |
935 } | 935 } |
936 MessageLoop::current()->PostDelayedTask( | 936 base::MessageLoop::current()->PostDelayedTask( |
937 FROM_HERE, | 937 FROM_HERE, |
938 base::Bind(&StartupTimeBomb::DeleteStartupWatchdog, | 938 base::Bind(&StartupTimeBomb::DeleteStartupWatchdog, |
939 base::Unretained(this)), | 939 base::Unretained(this)), |
940 base::TimeDelta::FromSeconds(10)); | 940 base::TimeDelta::FromSeconds(10)); |
941 } | 941 } |
942 | 942 |
943 // static | 943 // static |
944 void StartupTimeBomb::DisarmStartupTimeBomb() { | 944 void StartupTimeBomb::DisarmStartupTimeBomb() { |
945 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 945 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
946 if (g_startup_timebomb_) | 946 if (g_startup_timebomb_) |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
980 | 980 |
981 #if defined(OS_WIN) | 981 #if defined(OS_WIN) |
982 // On Windows XP, give twice the time for shutdown. | 982 // On Windows XP, give twice the time for shutdown. |
983 if (base::win::GetVersion() <= base::win::VERSION_XP) | 983 if (base::win::GetVersion() <= base::win::VERSION_XP) |
984 actual_duration *= 2; | 984 actual_duration *= 2; |
985 #endif | 985 #endif |
986 | 986 |
987 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); | 987 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); |
988 shutdown_watchdog_->Arm(); | 988 shutdown_watchdog_->Arm(); |
989 } | 989 } |
OLD | NEW |