Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/threading/thread_restrictions.h" | 5 #include "base/threading/thread_restrictions.h" |
| 6 #include "build/build_config.h" | 6 #include "build/build_config.h" |
| 7 #include "chrome/browser/metrics/metrics_service.h" | 7 #include "chrome/browser/metrics/metrics_service.h" |
| 8 #include "chrome/browser/metrics/thread_watcher.h" | 8 #include "chrome/browser/metrics/thread_watcher.h" |
| 9 #include "content/common/notification_service.h" | 9 #include "content/common/notification_service.h" |
| 10 | 10 |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 25 sleep_time_(sleep_time), | 25 sleep_time_(sleep_time), |
| 26 unresponsive_time_(unresponsive_time), | 26 unresponsive_time_(unresponsive_time), |
| 27 ping_time_(base::TimeTicks::Now()), | 27 ping_time_(base::TimeTicks::Now()), |
| 28 pong_time_(ping_time_), | 28 pong_time_(ping_time_), |
| 29 ping_sequence_number_(0), | 29 ping_sequence_number_(0), |
| 30 active_(false), | 30 active_(false), |
| 31 ping_count_(kPingCount), | 31 ping_count_(kPingCount), |
| 32 response_time_histogram_(NULL), | 32 response_time_histogram_(NULL), |
| 33 unresponsive_time_histogram_(NULL), | 33 unresponsive_time_histogram_(NULL), |
| 34 unresponsive_count_(0), | 34 unresponsive_count_(0), |
| 35 hung_processing_complete_(false), | |
| 35 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { | 36 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| 36 Initialize(); | 37 Initialize(); |
| 37 } | 38 } |
| 38 | 39 |
| 39 ThreadWatcher::~ThreadWatcher() {} | 40 ThreadWatcher::~ThreadWatcher() {} |
| 40 | 41 |
| 41 // static | 42 // static |
| 42 void ThreadWatcher::StartWatching(const BrowserThread::ID& thread_id, | 43 void ThreadWatcher::StartWatching(const BrowserThread::ID& thread_id, |
| 43 const std::string& thread_name, | 44 const std::string& thread_name, |
| 44 const base::TimeDelta& sleep_time, | 45 const base::TimeDelta& sleep_time, |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 void ThreadWatcher::OnPingMessage(const BrowserThread::ID& thread_id, | 226 void ThreadWatcher::OnPingMessage(const BrowserThread::ID& thread_id, |
| 226 Task* callback_task) { | 227 Task* callback_task) { |
| 227 // This method is called on watched thread. | 228 // This method is called on watched thread. |
| 228 DCHECK(BrowserThread::CurrentlyOn(thread_id)); | 229 DCHECK(BrowserThread::CurrentlyOn(thread_id)); |
| 229 WatchDogThread::PostTask(FROM_HERE, callback_task); | 230 WatchDogThread::PostTask(FROM_HERE, callback_task); |
| 230 } | 231 } |
| 231 | 232 |
| 232 void ThreadWatcher::GotGoodResponse() { | 233 void ThreadWatcher::GotGoodResponse() { |
| 233 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 234 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 234 unresponsive_count_ = 0; | 235 unresponsive_count_ = 0; |
| 236 hung_processing_complete_ = false; | |
| 235 } | 237 } |
| 236 | 238 |
| 237 void ThreadWatcher::GotNoResponse() { | 239 void ThreadWatcher::GotNoResponse() { |
| 238 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 240 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 239 | 241 |
| 240 // Record how other threads are responding when we don't get a response for | 242 // Record how other threads are responding when we don't get a response for |
| 241 // ping message atleast three times. | 243 // ping message atleast three times. |
| 242 if (++unresponsive_count_ < 3) | 244 if (++unresponsive_count_ < 3) |
| 243 return; | 245 return; |
| 244 | 246 |
| 245 // Record total unresponsive_time since last pong message. | 247 // Record total unresponsive_time since last pong message. |
| 246 base::TimeDelta unresponse_time = base::TimeTicks::Now() - pong_time_; | 248 base::TimeDelta unresponse_time = base::TimeTicks::Now() - pong_time_; |
| 247 unresponsive_time_histogram_->AddTime(unresponse_time); | 249 unresponsive_time_histogram_->AddTime(unresponse_time); |
| 248 | 250 |
| 251 // We have already collected stats for the non-responding watched thread. | |
| 252 if (hung_processing_complete_) | |
| 253 return; | |
| 254 | |
| 249 int no_of_responding_threads = 0; | 255 int no_of_responding_threads = 0; |
| 250 int no_of_unresponding_threads = 0; | 256 int no_of_unresponding_threads = 0; |
| 251 ThreadWatcherList::GetStatusOfThreads(&no_of_responding_threads, | 257 ThreadWatcherList::GetStatusOfThreads(&no_of_responding_threads, |
| 252 &no_of_unresponding_threads); | 258 &no_of_unresponding_threads); |
| 253 | 259 |
| 254 // Record how many watched threads are responding. | 260 // Record how many watched threads are responding. |
| 255 responsive_count_histogram_->Add(no_of_responding_threads); | 261 responsive_count_histogram_->Add(no_of_responding_threads); |
| 256 | 262 |
| 257 // Record how many watched threads are not responding. | 263 // Record how many watched threads are not responding. |
| 258 unresponsive_count_histogram_->Add(no_of_unresponding_threads); | 264 unresponsive_count_histogram_->Add(no_of_unresponding_threads); |
| 265 | |
| 266 // Crash the browser if IO thread hasn't responded atleast 3 times and if the | |
| 267 // number of other threads is equal to 1. We picked 1 to reduce the number of | |
| 268 // crashes and to get some sample data. | |
| 269 if (thread_id_ == BrowserThread::IO && no_of_responding_threads == 1) { | |
| 270 int* crash = NULL; | |
| 271 CHECK(crash++); | |
|
Peter Kasting
2011/05/17 00:41:05
Why is this better than simply NOTREACHED();?
| |
| 272 } | |
| 273 | |
| 274 hung_processing_complete_ = true; | |
| 259 } | 275 } |
| 260 | 276 |
| 261 // ThreadWatcherList methods and members. | 277 // ThreadWatcherList methods and members. |
| 262 // | 278 // |
| 263 // static | 279 // static |
| 264 ThreadWatcherList* ThreadWatcherList::global_ = NULL; | 280 ThreadWatcherList* ThreadWatcherList::global_ = NULL; |
| 265 // static | 281 // static |
| 266 const int ThreadWatcherList::kSleepSeconds = 2; | 282 const int ThreadWatcherList::kSleepSeconds = 2; |
| 267 // static | 283 // static |
| 268 const int ThreadWatcherList::kUnresponsiveSeconds = 4; | 284 const int ThreadWatcherList::kUnresponsiveSeconds = 4; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 520 watchdog_thread_ = NULL; | 536 watchdog_thread_ = NULL; |
| 521 } | 537 } |
| 522 | 538 |
| 523 void WatchDogThread::CleanUpAfterMessageLoopDestruction() { | 539 void WatchDogThread::CleanUpAfterMessageLoopDestruction() { |
| 524 #if defined(OS_WIN) | 540 #if defined(OS_WIN) |
| 525 // Closes the COM library on the current thread. CoInitialize must | 541 // Closes the COM library on the current thread. CoInitialize must |
| 526 // be balanced by a corresponding call to CoUninitialize. | 542 // be balanced by a corresponding call to CoUninitialize. |
| 527 CoUninitialize(); | 543 CoUninitialize(); |
| 528 #endif | 544 #endif |
| 529 } | 545 } |
| OLD | NEW |