| 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/location.h" |
| 14 #include "base/macros.h" |
| 14 #include "base/strings/string_number_conversions.h" | 15 #include "base/strings/string_number_conversions.h" |
| 15 #include "base/strings/string_split.h" | 16 #include "base/strings/string_split.h" |
| 16 #include "base/strings/string_tokenizer.h" | 17 #include "base/strings/string_tokenizer.h" |
| 17 #include "base/strings/stringprintf.h" | 18 #include "base/strings/stringprintf.h" |
| 18 #include "base/thread_task_runner_handle.h" | 19 #include "base/thread_task_runner_handle.h" |
| 19 #include "base/threading/platform_thread.h" | 20 #include "base/threading/platform_thread.h" |
| 20 #include "base/threading/thread_restrictions.h" | 21 #include "base/threading/thread_restrictions.h" |
| 21 #include "build/build_config.h" | 22 #include "build/build_config.h" |
| 22 #include "chrome/browser/chrome_notification_types.h" | 23 #include "chrome/browser/chrome_notification_types.h" |
| 23 #include "chrome/browser/metrics/thread_watcher_report_hang.h" | 24 #include "chrome/browser/metrics/thread_watcher_report_hang.h" |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 FROM_HERE, | 155 FROM_HERE, |
| 155 base::Bind(&ThreadWatcher::OnCheckResponsiveness, | 156 base::Bind(&ThreadWatcher::OnCheckResponsiveness, |
| 156 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), | 157 weak_ptr_factory_.GetWeakPtr(), ping_sequence_number_), |
| 157 unresponsive_time_); | 158 unresponsive_time_); |
| 158 } else { | 159 } else { |
| 159 // Watched thread might have gone away, stop watching it. | 160 // Watched thread might have gone away, stop watching it. |
| 160 DeActivateThreadWatching(); | 161 DeActivateThreadWatching(); |
| 161 } | 162 } |
| 162 } | 163 } |
| 163 | 164 |
| 164 void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) { | 165 void ThreadWatcher::OnPongMessage(uint64_t ping_sequence_number) { |
| 165 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 166 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 166 | 167 |
| 167 // Record watched thread's response time. | 168 // Record watched thread's response time. |
| 168 base::TimeTicks now = base::TimeTicks::Now(); | 169 base::TimeTicks now = base::TimeTicks::Now(); |
| 169 base::TimeDelta response_time = now - ping_time_; | 170 base::TimeDelta response_time = now - ping_time_; |
| 170 response_time_histogram_->AddTime(response_time); | 171 response_time_histogram_->AddTime(response_time); |
| 171 | 172 |
| 172 // Save the current time when we have got pong message. | 173 // Save the current time when we have got pong message. |
| 173 pong_time_ = now; | 174 pong_time_ = now; |
| 174 | 175 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 185 // ping messages. | 186 // ping messages. |
| 186 if (!active_ || --ping_count_ <= 0) | 187 if (!active_ || --ping_count_ <= 0) |
| 187 return; | 188 return; |
| 188 | 189 |
| 189 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | 190 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
| 190 FROM_HERE, base::Bind(&ThreadWatcher::PostPingMessage, | 191 FROM_HERE, base::Bind(&ThreadWatcher::PostPingMessage, |
| 191 weak_ptr_factory_.GetWeakPtr()), | 192 weak_ptr_factory_.GetWeakPtr()), |
| 192 sleep_time_); | 193 sleep_time_); |
| 193 } | 194 } |
| 194 | 195 |
| 195 void ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) { | 196 void ThreadWatcher::OnCheckResponsiveness(uint64_t ping_sequence_number) { |
| 196 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 197 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 197 // If we have stopped watching then consider thread as responding. | 198 // If we have stopped watching then consider thread as responding. |
| 198 if (!active_) { | 199 if (!active_) { |
| 199 responsive_ = true; | 200 responsive_ = true; |
| 200 return; | 201 return; |
| 201 } | 202 } |
| 202 // If the latest ping_sequence_number_ is not same as the ping_sequence_number | 203 // If the latest ping_sequence_number_ is not same as the ping_sequence_number |
| 203 // that is passed in, then we can assume OnPongMessage was called. | 204 // that is passed in, then we can assume OnPongMessage was called. |
| 204 // OnPongMessage increments ping_sequence_number_. | 205 // OnPongMessage increments ping_sequence_number_. |
| 205 if (ping_sequence_number_ != ping_sequence_number) { | 206 if (ping_sequence_number_ != ping_sequence_number) { |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 278 | 279 |
| 279 // Record total unresponsive_time since last pong message. | 280 // Record total unresponsive_time since last pong message. |
| 280 base::TimeDelta unresponse_time = base::TimeTicks::Now() - pong_time_; | 281 base::TimeDelta unresponse_time = base::TimeTicks::Now() - pong_time_; |
| 281 unresponsive_time_histogram_->AddTime(unresponse_time); | 282 unresponsive_time_histogram_->AddTime(unresponse_time); |
| 282 | 283 |
| 283 // We have already collected stats for the non-responding watched thread. | 284 // We have already collected stats for the non-responding watched thread. |
| 284 if (hung_processing_complete_) | 285 if (hung_processing_complete_) |
| 285 return; | 286 return; |
| 286 | 287 |
| 287 // Record how other threads are responding. | 288 // Record how other threads are responding. |
| 288 uint32 responding_thread_count = 0; | 289 uint32_t responding_thread_count = 0; |
| 289 uint32 unresponding_thread_count = 0; | 290 uint32_t unresponding_thread_count = 0; |
| 290 ThreadWatcherList::GetStatusOfThreads(&responding_thread_count, | 291 ThreadWatcherList::GetStatusOfThreads(&responding_thread_count, |
| 291 &unresponding_thread_count); | 292 &unresponding_thread_count); |
| 292 | 293 |
| 293 // Record how many watched threads are responding. | 294 // Record how many watched threads are responding. |
| 294 responsive_count_histogram_->Add(responding_thread_count); | 295 responsive_count_histogram_->Add(responding_thread_count); |
| 295 | 296 |
| 296 // Record how many watched threads are not responding. | 297 // Record how many watched threads are not responding. |
| 297 unresponsive_count_histogram_->Add(unresponding_thread_count); | 298 unresponsive_count_histogram_->Add(unresponding_thread_count); |
| 298 | 299 |
| 299 // Crash the browser if the watched thread is to be crashed on hang and if the | 300 // Crash the browser if the watched thread is to be crashed on hang and if the |
| (...skipping 28 matching lines...) Expand all Loading... |
| 328 // static | 329 // static |
| 329 const int ThreadWatcherList::kUnresponsiveSeconds = 2; | 330 const int ThreadWatcherList::kUnresponsiveSeconds = 2; |
| 330 // static | 331 // static |
| 331 const int ThreadWatcherList::kUnresponsiveCount = 9; | 332 const int ThreadWatcherList::kUnresponsiveCount = 9; |
| 332 // static | 333 // static |
| 333 const int ThreadWatcherList::kLiveThreadsThreshold = 2; | 334 const int ThreadWatcherList::kLiveThreadsThreshold = 2; |
| 334 // static, non-const for tests. | 335 // static, non-const for tests. |
| 335 int ThreadWatcherList::g_initialize_delay_seconds = 120; | 336 int ThreadWatcherList::g_initialize_delay_seconds = 120; |
| 336 | 337 |
| 337 ThreadWatcherList::CrashDataThresholds::CrashDataThresholds( | 338 ThreadWatcherList::CrashDataThresholds::CrashDataThresholds( |
| 338 uint32 live_threads_threshold, | 339 uint32_t live_threads_threshold, |
| 339 uint32 unresponsive_threshold) | 340 uint32_t unresponsive_threshold) |
| 340 : live_threads_threshold(live_threads_threshold), | 341 : live_threads_threshold(live_threads_threshold), |
| 341 unresponsive_threshold(unresponsive_threshold) { | 342 unresponsive_threshold(unresponsive_threshold) {} |
| 342 } | |
| 343 | 343 |
| 344 ThreadWatcherList::CrashDataThresholds::CrashDataThresholds() | 344 ThreadWatcherList::CrashDataThresholds::CrashDataThresholds() |
| 345 : live_threads_threshold(kLiveThreadsThreshold), | 345 : live_threads_threshold(kLiveThreadsThreshold), |
| 346 unresponsive_threshold(kUnresponsiveCount) { | 346 unresponsive_threshold(kUnresponsiveCount) { |
| 347 } | 347 } |
| 348 | 348 |
| 349 // static | 349 // static |
| 350 void ThreadWatcherList::StartWatchingAll( | 350 void ThreadWatcherList::StartWatchingAll( |
| 351 const base::CommandLine& command_line) { | 351 const base::CommandLine& command_line) { |
| 352 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 352 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
| 353 uint32 unresponsive_threshold; | 353 uint32_t unresponsive_threshold; |
| 354 CrashOnHangThreadMap crash_on_hang_threads; | 354 CrashOnHangThreadMap crash_on_hang_threads; |
| 355 ParseCommandLine(command_line, | 355 ParseCommandLine(command_line, |
| 356 &unresponsive_threshold, | 356 &unresponsive_threshold, |
| 357 &crash_on_hang_threads); | 357 &crash_on_hang_threads); |
| 358 | 358 |
| 359 ThreadWatcherObserver::SetupNotifications( | 359 ThreadWatcherObserver::SetupNotifications( |
| 360 base::TimeDelta::FromSeconds(kSleepSeconds * unresponsive_threshold)); | 360 base::TimeDelta::FromSeconds(kSleepSeconds * unresponsive_threshold)); |
| 361 | 361 |
| 362 WatchDogThread::PostTask( | 362 WatchDogThread::PostTask( |
| 363 FROM_HERE, | 363 FROM_HERE, |
| (...skipping 27 matching lines...) Expand all Loading... |
| 391 g_thread_watcher_list_->registered_[watcher->thread_id()] = watcher; | 391 g_thread_watcher_list_->registered_[watcher->thread_id()] = watcher; |
| 392 } | 392 } |
| 393 | 393 |
| 394 // static | 394 // static |
| 395 bool ThreadWatcherList::IsRegistered(const BrowserThread::ID thread_id) { | 395 bool ThreadWatcherList::IsRegistered(const BrowserThread::ID thread_id) { |
| 396 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 396 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 397 return nullptr != ThreadWatcherList::Find(thread_id); | 397 return nullptr != ThreadWatcherList::Find(thread_id); |
| 398 } | 398 } |
| 399 | 399 |
| 400 // static | 400 // static |
| 401 void ThreadWatcherList::GetStatusOfThreads(uint32* responding_thread_count, | 401 void ThreadWatcherList::GetStatusOfThreads( |
| 402 uint32* unresponding_thread_count) { | 402 uint32_t* responding_thread_count, |
| 403 uint32_t* unresponding_thread_count) { |
| 403 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 404 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 404 *responding_thread_count = 0; | 405 *responding_thread_count = 0; |
| 405 *unresponding_thread_count = 0; | 406 *unresponding_thread_count = 0; |
| 406 if (!g_thread_watcher_list_) | 407 if (!g_thread_watcher_list_) |
| 407 return; | 408 return; |
| 408 | 409 |
| 409 for (RegistrationList::iterator it = | 410 for (RegistrationList::iterator it = |
| 410 g_thread_watcher_list_->registered_.begin(); | 411 g_thread_watcher_list_->registered_.begin(); |
| 411 g_thread_watcher_list_->registered_.end() != it; | 412 g_thread_watcher_list_->registered_.end() != it; |
| 412 ++it) { | 413 ++it) { |
| (...skipping 25 matching lines...) Expand all Loading... |
| 438 | 439 |
| 439 ThreadWatcherList::~ThreadWatcherList() { | 440 ThreadWatcherList::~ThreadWatcherList() { |
| 440 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 441 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 441 DCHECK(this == g_thread_watcher_list_); | 442 DCHECK(this == g_thread_watcher_list_); |
| 442 g_thread_watcher_list_ = nullptr; | 443 g_thread_watcher_list_ = nullptr; |
| 443 } | 444 } |
| 444 | 445 |
| 445 // static | 446 // static |
| 446 void ThreadWatcherList::ParseCommandLine( | 447 void ThreadWatcherList::ParseCommandLine( |
| 447 const base::CommandLine& command_line, | 448 const base::CommandLine& command_line, |
| 448 uint32* unresponsive_threshold, | 449 uint32_t* unresponsive_threshold, |
| 449 CrashOnHangThreadMap* crash_on_hang_threads) { | 450 CrashOnHangThreadMap* crash_on_hang_threads) { |
| 450 // Initialize |unresponsive_threshold| to a default value. | 451 // Initialize |unresponsive_threshold| to a default value. |
| 451 *unresponsive_threshold = kUnresponsiveCount; | 452 *unresponsive_threshold = kUnresponsiveCount; |
| 452 | 453 |
| 453 // Increase the unresponsive_threshold on the Stable and Beta channels to | 454 // Increase the unresponsive_threshold on the Stable and Beta channels to |
| 454 // reduce the number of crashes due to ThreadWatcher. | 455 // reduce the number of crashes due to ThreadWatcher. |
| 455 version_info::Channel channel = chrome::GetChannel(); | 456 version_info::Channel channel = chrome::GetChannel(); |
| 456 if (channel == version_info::Channel::STABLE) { | 457 if (channel == version_info::Channel::STABLE) { |
| 457 *unresponsive_threshold *= 4; | 458 *unresponsive_threshold *= 4; |
| 458 } else if (channel == version_info::Channel::BETA) { | 459 } else if (channel == version_info::Channel::BETA) { |
| 459 *unresponsive_threshold *= 2; | 460 *unresponsive_threshold *= 2; |
| 460 } | 461 } |
| 461 | 462 |
| 462 #if defined(OS_WIN) | 463 #if defined(OS_WIN) |
| 463 // For Windows XP (old systems), double the unresponsive_threshold to give | 464 // For Windows XP (old systems), double the unresponsive_threshold to give |
| 464 // the OS a chance to schedule UI/IO threads a time slice to respond with a | 465 // the OS a chance to schedule UI/IO threads a time slice to respond with a |
| 465 // pong message (to get around limitations with the OS). | 466 // pong message (to get around limitations with the OS). |
| 466 if (base::win::GetVersion() <= base::win::VERSION_XP) | 467 if (base::win::GetVersion() <= base::win::VERSION_XP) |
| 467 *unresponsive_threshold *= 2; | 468 *unresponsive_threshold *= 2; |
| 468 #endif | 469 #endif |
| 469 | 470 |
| 470 uint32 crash_seconds = *unresponsive_threshold * kUnresponsiveSeconds; | 471 uint32_t crash_seconds = *unresponsive_threshold * kUnresponsiveSeconds; |
| 471 std::string crash_on_hang_thread_names; | 472 std::string crash_on_hang_thread_names; |
| 472 if (command_line.HasSwitch(switches::kCrashOnHangThreads)) { | 473 if (command_line.HasSwitch(switches::kCrashOnHangThreads)) { |
| 473 crash_on_hang_thread_names = | 474 crash_on_hang_thread_names = |
| 474 command_line.GetSwitchValueASCII(switches::kCrashOnHangThreads); | 475 command_line.GetSwitchValueASCII(switches::kCrashOnHangThreads); |
| 475 } else if (channel != version_info::Channel::STABLE) { | 476 } else if (channel != version_info::Channel::STABLE) { |
| 476 // Default to crashing the browser if UI or IO or FILE threads are not | 477 // Default to crashing the browser if UI or IO or FILE threads are not |
| 477 // responsive except in stable channel. | 478 // responsive except in stable channel. |
| 478 crash_on_hang_thread_names = base::StringPrintf( | 479 crash_on_hang_thread_names = base::StringPrintf( |
| 479 "UI:%d:%d,IO:%d:%d,FILE:%d:%d", | 480 "UI:%d:%d,IO:%d:%d,FILE:%d:%d", |
| 480 kLiveThreadsThreshold, crash_seconds, | 481 kLiveThreadsThreshold, crash_seconds, |
| 481 kLiveThreadsThreshold, crash_seconds, | 482 kLiveThreadsThreshold, crash_seconds, |
| 482 kLiveThreadsThreshold, crash_seconds * 5); | 483 kLiveThreadsThreshold, crash_seconds * 5); |
| 483 } | 484 } |
| 484 | 485 |
| 485 ParseCommandLineCrashOnHangThreads(crash_on_hang_thread_names, | 486 ParseCommandLineCrashOnHangThreads(crash_on_hang_thread_names, |
| 486 kLiveThreadsThreshold, | 487 kLiveThreadsThreshold, |
| 487 crash_seconds, | 488 crash_seconds, |
| 488 crash_on_hang_threads); | 489 crash_on_hang_threads); |
| 489 } | 490 } |
| 490 | 491 |
| 491 // static | 492 // static |
| 492 void ThreadWatcherList::ParseCommandLineCrashOnHangThreads( | 493 void ThreadWatcherList::ParseCommandLineCrashOnHangThreads( |
| 493 const std::string& crash_on_hang_thread_names, | 494 const std::string& crash_on_hang_thread_names, |
| 494 uint32 default_live_threads_threshold, | 495 uint32_t default_live_threads_threshold, |
| 495 uint32 default_crash_seconds, | 496 uint32_t default_crash_seconds, |
| 496 CrashOnHangThreadMap* crash_on_hang_threads) { | 497 CrashOnHangThreadMap* crash_on_hang_threads) { |
| 497 base::StringTokenizer tokens(crash_on_hang_thread_names, ","); | 498 base::StringTokenizer tokens(crash_on_hang_thread_names, ","); |
| 498 while (tokens.GetNext()) { | 499 while (tokens.GetNext()) { |
| 499 std::vector<base::StringPiece> values = base::SplitStringPiece( | 500 std::vector<base::StringPiece> values = base::SplitStringPiece( |
| 500 tokens.token_piece(), ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 501 tokens.token_piece(), ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 501 std::string thread_name = values[0].as_string(); | 502 std::string thread_name = values[0].as_string(); |
| 502 | 503 |
| 503 uint32 live_threads_threshold = default_live_threads_threshold; | 504 uint32_t live_threads_threshold = default_live_threads_threshold; |
| 504 uint32 crash_seconds = default_crash_seconds; | 505 uint32_t crash_seconds = default_crash_seconds; |
| 505 if (values.size() >= 2 && | 506 if (values.size() >= 2 && |
| 506 (!base::StringToUint(values[1], &live_threads_threshold))) { | 507 (!base::StringToUint(values[1], &live_threads_threshold))) { |
| 507 continue; | 508 continue; |
| 508 } | 509 } |
| 509 if (values.size() >= 3 && | 510 if (values.size() >= 3 && |
| 510 (!base::StringToUint(values[2], &crash_seconds))) { | 511 (!base::StringToUint(values[2], &crash_seconds))) { |
| 511 continue; | 512 continue; |
| 512 } | 513 } |
| 513 uint32 unresponsive_threshold = static_cast<uint32>( | 514 uint32_t unresponsive_threshold = static_cast<uint32_t>( |
| 514 ceil(static_cast<float>(crash_seconds) / kUnresponsiveSeconds)); | 515 ceil(static_cast<float>(crash_seconds) / kUnresponsiveSeconds)); |
| 515 | 516 |
| 516 CrashDataThresholds crash_data(live_threads_threshold, | 517 CrashDataThresholds crash_data(live_threads_threshold, |
| 517 unresponsive_threshold); | 518 unresponsive_threshold); |
| 518 // Use the last specifier. | 519 // Use the last specifier. |
| 519 (*crash_on_hang_threads)[thread_name] = crash_data; | 520 (*crash_on_hang_threads)[thread_name] = crash_data; |
| 520 } | 521 } |
| 521 } | 522 } |
| 522 | 523 |
| 523 // static | 524 // static |
| 524 void ThreadWatcherList::InitializeAndStartWatching( | 525 void ThreadWatcherList::InitializeAndStartWatching( |
| 525 uint32 unresponsive_threshold, | 526 uint32_t unresponsive_threshold, |
| 526 const CrashOnHangThreadMap& crash_on_hang_threads) { | 527 const CrashOnHangThreadMap& crash_on_hang_threads) { |
| 527 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 528 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 528 | 529 |
| 529 // Disarm the startup timebomb, even if stop has been called. | 530 // Disarm the startup timebomb, even if stop has been called. |
| 530 BrowserThread::PostTask( | 531 BrowserThread::PostTask( |
| 531 BrowserThread::UI, | 532 BrowserThread::UI, |
| 532 FROM_HERE, | 533 FROM_HERE, |
| 533 base::Bind(&StartupTimeBomb::DisarmStartupTimeBomb)); | 534 base::Bind(&StartupTimeBomb::DisarmStartupTimeBomb)); |
| 534 | 535 |
| 535 // This method is deferred in relationship to its StopWatchingAll() | 536 // This method is deferred in relationship to its StopWatchingAll() |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 567 StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime, kUnresponsiveTime, | 568 StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime, kUnresponsiveTime, |
| 568 unresponsive_threshold, crash_on_hang_threads); | 569 unresponsive_threshold, crash_on_hang_threads); |
| 569 } | 570 } |
| 570 | 571 |
| 571 // static | 572 // static |
| 572 void ThreadWatcherList::StartWatching( | 573 void ThreadWatcherList::StartWatching( |
| 573 const BrowserThread::ID& thread_id, | 574 const BrowserThread::ID& thread_id, |
| 574 const std::string& thread_name, | 575 const std::string& thread_name, |
| 575 const base::TimeDelta& sleep_time, | 576 const base::TimeDelta& sleep_time, |
| 576 const base::TimeDelta& unresponsive_time, | 577 const base::TimeDelta& unresponsive_time, |
| 577 uint32 unresponsive_threshold, | 578 uint32_t unresponsive_threshold, |
| 578 const CrashOnHangThreadMap& crash_on_hang_threads) { | 579 const CrashOnHangThreadMap& crash_on_hang_threads) { |
| 579 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 580 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 580 | 581 |
| 581 CrashOnHangThreadMap::const_iterator it = | 582 CrashOnHangThreadMap::const_iterator it = |
| 582 crash_on_hang_threads.find(thread_name); | 583 crash_on_hang_threads.find(thread_name); |
| 583 bool crash_on_hang = false; | 584 bool crash_on_hang = false; |
| 584 uint32 live_threads_threshold = 0; | 585 uint32_t live_threads_threshold = 0; |
| 585 if (it != crash_on_hang_threads.end()) { | 586 if (it != crash_on_hang_threads.end()) { |
| 586 crash_on_hang = true; | 587 crash_on_hang = true; |
| 587 live_threads_threshold = it->second.live_threads_threshold; | 588 live_threads_threshold = it->second.live_threads_threshold; |
| 588 unresponsive_threshold = it->second.unresponsive_threshold; | 589 unresponsive_threshold = it->second.unresponsive_threshold; |
| 589 } | 590 } |
| 590 | 591 |
| 591 ThreadWatcher::StartWatching( | 592 ThreadWatcher::StartWatching( |
| 592 ThreadWatcher::WatchingParams(thread_id, | 593 ThreadWatcher::WatchingParams(thread_id, |
| 593 thread_name, | 594 thread_name, |
| 594 sleep_time, | 595 sleep_time, |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 999 | 1000 |
| 1000 #if defined(OS_WIN) | 1001 #if defined(OS_WIN) |
| 1001 // On Windows XP, give twice the time for shutdown. | 1002 // On Windows XP, give twice the time for shutdown. |
| 1002 if (base::win::GetVersion() <= base::win::VERSION_XP) | 1003 if (base::win::GetVersion() <= base::win::VERSION_XP) |
| 1003 actual_duration *= 2; | 1004 actual_duration *= 2; |
| 1004 #endif | 1005 #endif |
| 1005 | 1006 |
| 1006 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); | 1007 shutdown_watchdog_ = new ShutdownWatchDogThread(actual_duration); |
| 1007 shutdown_watchdog_->Arm(); | 1008 shutdown_watchdog_->Arm(); |
| 1008 } | 1009 } |
| OLD | NEW |