Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(342)

Side by Side Diff: chrome/browser/metrics/thread_watcher.cc

Issue 1550593002: Switch to standard integer types in chrome/browser/, part 2 of 4. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/metrics/thread_watcher.h ('k') | chrome/browser/metrics/thread_watcher_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698