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 |