| 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> | 7 #include <math.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <memory> | 10 #include <memory> |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 238 } | 238 } |
| 239 UpdateWaitState(STOPPED_WAITING); | 239 UpdateWaitState(STOPPED_WAITING); |
| 240 return exit_state; | 240 return exit_state; |
| 241 } | 241 } |
| 242 }; | 242 }; |
| 243 | 243 |
| 244 class ThreadWatcherTest : public ::testing::Test { | 244 class ThreadWatcherTest : public ::testing::Test { |
| 245 public: | 245 public: |
| 246 static const TimeDelta kSleepTime; | 246 static const TimeDelta kSleepTime; |
| 247 static const TimeDelta kUnresponsiveTime; | 247 static const TimeDelta kUnresponsiveTime; |
| 248 static const BrowserThread::ID io_thread_id; | 248 static const char kIOThreadName[]; |
| 249 static const std::string io_thread_name; | 249 static const char kDBThreadName[]; |
| 250 static const BrowserThread::ID db_thread_id; | 250 static const char kCrashOnHangThreadNames[]; |
| 251 static const std::string db_thread_name; | 251 static const char kThreadNamesAndLiveThreshold[]; |
| 252 static const std::string crash_on_hang_seconds; | 252 static const char kCrashOnHangThreadData[]; |
| 253 static const std::string crash_on_hang_thread_names; | 253 |
| 254 static const std::string thread_names_and_live_threshold; | |
| 255 static const std::string crash_on_hang_thread_data; | |
| 256 CustomThreadWatcher* io_watcher_; | 254 CustomThreadWatcher* io_watcher_; |
| 257 CustomThreadWatcher* db_watcher_; | 255 CustomThreadWatcher* db_watcher_; |
| 258 ThreadWatcherList* thread_watcher_list_; | 256 ThreadWatcherList* thread_watcher_list_; |
| 259 | 257 |
| 260 ThreadWatcherTest() | 258 ThreadWatcherTest() |
| 261 : setup_complete_(&lock_), | 259 : setup_complete_(&lock_), |
| 262 initialized_(false) { | 260 initialized_(false) { |
| 263 db_thread_.reset(new content::TestBrowserThread(BrowserThread::DB)); | 261 db_thread_.reset(new content::TestBrowserThread(BrowserThread::DB)); |
| 264 io_thread_.reset(new content::TestBrowserThread(BrowserThread::IO)); | 262 io_thread_.reset(new content::TestBrowserThread(BrowserThread::IO)); |
| 265 watchdog_thread_.reset(new WatchDogThread()); | 263 watchdog_thread_.reset(new WatchDogThread()); |
| 266 db_thread_->StartAndWaitForTesting(); | 264 db_thread_->StartAndWaitForTesting(); |
| 267 io_thread_->StartAndWaitForTesting(); | 265 io_thread_->StartAndWaitForTesting(); |
| 268 watchdog_thread_->StartAndWaitForTesting(); | 266 watchdog_thread_->StartAndWaitForTesting(); |
| 269 | 267 |
| 270 WatchDogThread::PostTask( | 268 WatchDogThread::PostTask( |
| 271 FROM_HERE, | 269 FROM_HERE, |
| 272 base::Bind(&ThreadWatcherTest::SetUpObjects, base::Unretained(this))); | 270 base::Bind(&ThreadWatcherTest::SetUpObjects, base::Unretained(this))); |
| 273 | 271 |
| 274 WaitForSetUp(TimeDelta::FromMinutes(1)); | 272 WaitForSetUp(TimeDelta::FromMinutes(1)); |
| 275 } | 273 } |
| 276 | 274 |
| 277 void SetUpObjects() { | 275 void SetUpObjects() { |
| 278 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); | 276 DCHECK(WatchDogThread::CurrentlyOnWatchDogThread()); |
| 279 | 277 |
| 280 // Setup the registry for thread watchers. | 278 // Setup the registry for thread watchers. |
| 281 thread_watcher_list_ = new ThreadWatcherList(); | 279 thread_watcher_list_ = new ThreadWatcherList(); |
| 282 | 280 |
| 283 // Create thread watcher object for the IO thread. | 281 // Create thread watcher object for the IO thread. |
| 284 io_watcher_ = new CustomThreadWatcher(io_thread_id, io_thread_name, | 282 io_watcher_ = new CustomThreadWatcher(BrowserThread::IO, kIOThreadName, |
| 285 kSleepTime, kUnresponsiveTime); | 283 kSleepTime, kUnresponsiveTime); |
| 286 EXPECT_EQ(io_watcher_, thread_watcher_list_->Find(io_thread_id)); | 284 EXPECT_EQ(io_watcher_, thread_watcher_list_->Find(BrowserThread::IO)); |
| 287 | 285 |
| 288 // Create thread watcher object for the DB thread. | 286 // Create thread watcher object for the DB thread. |
| 289 db_watcher_ = new CustomThreadWatcher( | 287 db_watcher_ = new CustomThreadWatcher(BrowserThread::DB, kDBThreadName, |
| 290 db_thread_id, db_thread_name, kSleepTime, kUnresponsiveTime); | 288 kSleepTime, kUnresponsiveTime); |
| 291 EXPECT_EQ(db_watcher_, thread_watcher_list_->Find(db_thread_id)); | 289 EXPECT_EQ(db_watcher_, thread_watcher_list_->Find(BrowserThread::DB)); |
| 292 | 290 |
| 293 { | 291 { |
| 294 base::AutoLock lock(lock_); | 292 base::AutoLock lock(lock_); |
| 295 initialized_ = true; | 293 initialized_ = true; |
| 296 } | 294 } |
| 297 setup_complete_.Signal(); | 295 setup_complete_.Signal(); |
| 298 } | 296 } |
| 299 | 297 |
| 300 void WaitForSetUp(TimeDelta wait_time) { | 298 void WaitForSetUp(TimeDelta wait_time) { |
| 301 DCHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); | 299 DCHECK(!WatchDogThread::CurrentlyOnWatchDogThread()); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 318 } | 316 } |
| 319 | 317 |
| 320 private: | 318 private: |
| 321 base::MessageLoop message_loop_; | 319 base::MessageLoop message_loop_; |
| 322 base::Lock lock_; | 320 base::Lock lock_; |
| 323 base::ConditionVariable setup_complete_; | 321 base::ConditionVariable setup_complete_; |
| 324 bool initialized_; | 322 bool initialized_; |
| 325 std::unique_ptr<content::TestBrowserThread> db_thread_; | 323 std::unique_ptr<content::TestBrowserThread> db_thread_; |
| 326 std::unique_ptr<content::TestBrowserThread> io_thread_; | 324 std::unique_ptr<content::TestBrowserThread> io_thread_; |
| 327 std::unique_ptr<WatchDogThread> watchdog_thread_; | 325 std::unique_ptr<WatchDogThread> watchdog_thread_; |
| 326 |
| 327 DISALLOW_COPY_AND_ASSIGN(ThreadWatcherTest); |
| 328 }; | 328 }; |
| 329 | 329 |
| 330 // Define static constants. | 330 // Define static constants. |
| 331 const TimeDelta ThreadWatcherTest::kSleepTime = | 331 const TimeDelta ThreadWatcherTest::kSleepTime = TimeDelta::FromMilliseconds(50); |
| 332 TimeDelta::FromMilliseconds(50); | |
| 333 const TimeDelta ThreadWatcherTest::kUnresponsiveTime = | 332 const TimeDelta ThreadWatcherTest::kUnresponsiveTime = |
| 334 TimeDelta::FromMilliseconds(500); | 333 TimeDelta::FromMilliseconds(500); |
| 335 const BrowserThread::ID ThreadWatcherTest::io_thread_id = BrowserThread::IO; | 334 const char ThreadWatcherTest::kIOThreadName[] = "IO"; |
| 336 const std::string ThreadWatcherTest::io_thread_name = "IO"; | 335 const char ThreadWatcherTest::kDBThreadName[] = "DB"; |
| 337 const BrowserThread::ID ThreadWatcherTest::db_thread_id = BrowserThread::DB; | 336 const char ThreadWatcherTest::kCrashOnHangThreadNames[] = "UI,IO"; |
| 338 const std::string ThreadWatcherTest::db_thread_name = "DB"; | 337 const char ThreadWatcherTest::kThreadNamesAndLiveThreshold[] = "UI:4,IO:4"; |
| 339 const std::string ThreadWatcherTest::crash_on_hang_thread_names = "UI,IO"; | 338 const char ThreadWatcherTest::kCrashOnHangThreadData[] = |
| 340 const std::string ThreadWatcherTest::thread_names_and_live_threshold = | |
| 341 "UI:4,IO:4"; | |
| 342 const std::string ThreadWatcherTest::crash_on_hang_thread_data = | |
| 343 "UI:5:12,IO:5:12,FILE:5:12"; | 339 "UI:5:12,IO:5:12,FILE:5:12"; |
| 344 | 340 |
| 345 TEST_F(ThreadWatcherTest, ThreadNamesOnlyArgs) { | 341 TEST_F(ThreadWatcherTest, ThreadNamesOnlyArgs) { |
| 346 // Setup command_line arguments. | 342 // Setup command_line arguments. |
| 347 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); | 343 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| 348 command_line.AppendSwitchASCII(switches::kCrashOnHangThreads, | 344 command_line.AppendSwitchASCII(switches::kCrashOnHangThreads, |
| 349 crash_on_hang_thread_names); | 345 kCrashOnHangThreadNames); |
| 350 | 346 |
| 351 // Parse command_line arguments. | 347 // Parse command_line arguments. |
| 352 ThreadWatcherList::CrashOnHangThreadMap crash_on_hang_threads; | 348 ThreadWatcherList::CrashOnHangThreadMap crash_on_hang_threads; |
| 353 uint32_t unresponsive_threshold; | 349 uint32_t unresponsive_threshold; |
| 354 ThreadWatcherList::ParseCommandLine(command_line, | 350 ThreadWatcherList::ParseCommandLine(command_line, |
| 355 &unresponsive_threshold, | 351 &unresponsive_threshold, |
| 356 &crash_on_hang_threads); | 352 &crash_on_hang_threads); |
| 357 | 353 |
| 358 // Verify the data. | 354 // Verify the data. |
| 359 base::StringTokenizer tokens(crash_on_hang_thread_names, ","); | 355 base::CStringTokenizer tokens( |
| 356 kCrashOnHangThreadNames, |
| 357 kCrashOnHangThreadNames + (arraysize(kCrashOnHangThreadNames) - 1), ","); |
| 360 while (tokens.GetNext()) { | 358 while (tokens.GetNext()) { |
| 361 std::vector<base::StringPiece> values = base::SplitStringPiece( | 359 std::vector<base::StringPiece> values = base::SplitStringPiece( |
| 362 tokens.token_piece(), ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 360 tokens.token_piece(), ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 363 std::string thread_name = values[0].as_string(); | 361 std::string thread_name = values[0].as_string(); |
| 364 | 362 |
| 365 ThreadWatcherList::CrashOnHangThreadMap::iterator it = | 363 ThreadWatcherList::CrashOnHangThreadMap::iterator it = |
| 366 crash_on_hang_threads.find(thread_name); | 364 crash_on_hang_threads.find(thread_name); |
| 367 bool crash_on_hang = (it != crash_on_hang_threads.end()); | 365 bool crash_on_hang = (it != crash_on_hang_threads.end()); |
| 368 EXPECT_TRUE(crash_on_hang); | 366 EXPECT_TRUE(crash_on_hang); |
| 369 EXPECT_LT(0u, it->second.live_threads_threshold); | 367 EXPECT_LT(0u, it->second.live_threads_threshold); |
| 370 EXPECT_LT(0u, it->second.unresponsive_threshold); | 368 EXPECT_LT(0u, it->second.unresponsive_threshold); |
| 371 } | 369 } |
| 372 } | 370 } |
| 373 | 371 |
| 374 TEST_F(ThreadWatcherTest, ThreadNamesAndLiveThresholdArgs) { | 372 TEST_F(ThreadWatcherTest, ThreadNamesAndLiveThresholdArgs) { |
| 375 // Setup command_line arguments. | 373 // Setup command_line arguments. |
| 376 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); | 374 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| 377 command_line.AppendSwitchASCII(switches::kCrashOnHangThreads, | 375 command_line.AppendSwitchASCII(switches::kCrashOnHangThreads, |
| 378 thread_names_and_live_threshold); | 376 kThreadNamesAndLiveThreshold); |
| 379 | 377 |
| 380 // Parse command_line arguments. | 378 // Parse command_line arguments. |
| 381 ThreadWatcherList::CrashOnHangThreadMap crash_on_hang_threads; | 379 ThreadWatcherList::CrashOnHangThreadMap crash_on_hang_threads; |
| 382 uint32_t unresponsive_threshold; | 380 uint32_t unresponsive_threshold; |
| 383 ThreadWatcherList::ParseCommandLine(command_line, | 381 ThreadWatcherList::ParseCommandLine(command_line, |
| 384 &unresponsive_threshold, | 382 &unresponsive_threshold, |
| 385 &crash_on_hang_threads); | 383 &crash_on_hang_threads); |
| 386 | 384 |
| 387 // Verify the data. | 385 // Verify the data. |
| 388 base::StringTokenizer tokens(thread_names_and_live_threshold, ","); | 386 base::CStringTokenizer tokens( |
| 387 kThreadNamesAndLiveThreshold, |
| 388 kThreadNamesAndLiveThreshold + |
| 389 (arraysize(kThreadNamesAndLiveThreshold) - 1), |
| 390 ","); |
| 389 while (tokens.GetNext()) { | 391 while (tokens.GetNext()) { |
| 390 std::vector<base::StringPiece> values = base::SplitStringPiece( | 392 std::vector<base::StringPiece> values = base::SplitStringPiece( |
| 391 tokens.token_piece(), ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 393 tokens.token_piece(), ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 392 std::string thread_name = values[0].as_string(); | 394 std::string thread_name = values[0].as_string(); |
| 393 | 395 |
| 394 ThreadWatcherList::CrashOnHangThreadMap::iterator it = | 396 ThreadWatcherList::CrashOnHangThreadMap::iterator it = |
| 395 crash_on_hang_threads.find(thread_name); | 397 crash_on_hang_threads.find(thread_name); |
| 396 bool crash_on_hang = (it != crash_on_hang_threads.end()); | 398 bool crash_on_hang = (it != crash_on_hang_threads.end()); |
| 397 EXPECT_TRUE(crash_on_hang); | 399 EXPECT_TRUE(crash_on_hang); |
| 398 EXPECT_EQ(4u, it->second.live_threads_threshold); | 400 EXPECT_EQ(4u, it->second.live_threads_threshold); |
| 399 EXPECT_LT(0u, it->second.unresponsive_threshold); | 401 EXPECT_LT(0u, it->second.unresponsive_threshold); |
| 400 } | 402 } |
| 401 } | 403 } |
| 402 | 404 |
| 403 TEST_F(ThreadWatcherTest, CrashOnHangThreadsAllArgs) { | 405 TEST_F(ThreadWatcherTest, CrashOnHangThreadsAllArgs) { |
| 404 // Setup command_line arguments. | 406 // Setup command_line arguments. |
| 405 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); | 407 base::CommandLine command_line(base::CommandLine::NO_PROGRAM); |
| 406 command_line.AppendSwitchASCII(switches::kCrashOnHangThreads, | 408 command_line.AppendSwitchASCII(switches::kCrashOnHangThreads, |
| 407 crash_on_hang_thread_data); | 409 kCrashOnHangThreadData); |
| 408 | 410 |
| 409 // Parse command_line arguments. | 411 // Parse command_line arguments. |
| 410 ThreadWatcherList::CrashOnHangThreadMap crash_on_hang_threads; | 412 ThreadWatcherList::CrashOnHangThreadMap crash_on_hang_threads; |
| 411 uint32_t unresponsive_threshold; | 413 uint32_t unresponsive_threshold; |
| 412 ThreadWatcherList::ParseCommandLine(command_line, | 414 ThreadWatcherList::ParseCommandLine(command_line, |
| 413 &unresponsive_threshold, | 415 &unresponsive_threshold, |
| 414 &crash_on_hang_threads); | 416 &crash_on_hang_threads); |
| 415 | 417 |
| 416 // Verify the data. | 418 // Verify the data. |
| 417 base::StringTokenizer tokens(crash_on_hang_thread_data, ","); | 419 base::CStringTokenizer tokens( |
| 420 kCrashOnHangThreadData, |
| 421 kCrashOnHangThreadData + (arraysize(kCrashOnHangThreadData) - 1), ","); |
| 418 while (tokens.GetNext()) { | 422 while (tokens.GetNext()) { |
| 419 std::vector<base::StringPiece> values = base::SplitStringPiece( | 423 std::vector<base::StringPiece> values = base::SplitStringPiece( |
| 420 tokens.token_piece(), ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); | 424 tokens.token_piece(), ":", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL); |
| 421 std::string thread_name = values[0].as_string(); | 425 std::string thread_name = values[0].as_string(); |
| 422 | 426 |
| 423 ThreadWatcherList::CrashOnHangThreadMap::iterator it = | 427 ThreadWatcherList::CrashOnHangThreadMap::iterator it = |
| 424 crash_on_hang_threads.find(thread_name); | 428 crash_on_hang_threads.find(thread_name); |
| 425 | 429 |
| 426 bool crash_on_hang = (it != crash_on_hang_threads.end()); | 430 bool crash_on_hang = (it != crash_on_hang_threads.end()); |
| 427 EXPECT_TRUE(crash_on_hang); | 431 EXPECT_TRUE(crash_on_hang); |
| 428 | 432 |
| 429 uint32_t crash_live_threads_threshold = it->second.live_threads_threshold; | 433 uint32_t crash_live_threads_threshold = it->second.live_threads_threshold; |
| 430 EXPECT_EQ(5u, crash_live_threads_threshold); | 434 EXPECT_EQ(5u, crash_live_threads_threshold); |
| 431 | 435 |
| 432 uint32_t crash_unresponsive_threshold = it->second.unresponsive_threshold; | 436 uint32_t crash_unresponsive_threshold = it->second.unresponsive_threshold; |
| 433 uint32_t crash_on_unresponsive_seconds = | 437 uint32_t crash_on_unresponsive_seconds = |
| 434 ThreadWatcherList::kUnresponsiveSeconds * crash_unresponsive_threshold; | 438 ThreadWatcherList::kUnresponsiveSeconds * crash_unresponsive_threshold; |
| 435 EXPECT_EQ(12u, crash_on_unresponsive_seconds); | 439 EXPECT_EQ(12u, crash_on_unresponsive_seconds); |
| 436 } | 440 } |
| 437 } | 441 } |
| 438 | 442 |
| 439 // Test registration. When thread_watcher_list_ goes out of scope after | 443 // Test registration. When thread_watcher_list_ goes out of scope after |
| 440 // TearDown, all thread watcher objects will be deleted. | 444 // TearDown, all thread watcher objects will be deleted. |
| 441 TEST_F(ThreadWatcherTest, Registration) { | 445 TEST_F(ThreadWatcherTest, Registration) { |
| 442 // Check ThreadWatcher object has all correct parameters. | 446 // Check ThreadWatcher object has all correct parameters. |
| 443 EXPECT_EQ(io_thread_id, io_watcher_->thread_id()); | 447 EXPECT_EQ(BrowserThread::IO, io_watcher_->thread_id()); |
| 444 EXPECT_EQ(io_thread_name, io_watcher_->thread_name()); | 448 EXPECT_EQ(kIOThreadName, io_watcher_->thread_name()); |
| 445 EXPECT_EQ(kSleepTime, io_watcher_->sleep_time()); | 449 EXPECT_EQ(kSleepTime, io_watcher_->sleep_time()); |
| 446 EXPECT_EQ(kUnresponsiveTime, io_watcher_->unresponsive_time()); | 450 EXPECT_EQ(kUnresponsiveTime, io_watcher_->unresponsive_time()); |
| 447 EXPECT_FALSE(io_watcher_->active()); | 451 EXPECT_FALSE(io_watcher_->active()); |
| 448 | 452 |
| 449 // Check ThreadWatcher object of watched DB thread has correct data. | 453 // Check ThreadWatcher object of watched DB thread has correct data. |
| 450 EXPECT_EQ(db_thread_id, db_watcher_->thread_id()); | 454 EXPECT_EQ(BrowserThread::DB, db_watcher_->thread_id()); |
| 451 EXPECT_EQ(db_thread_name, db_watcher_->thread_name()); | 455 EXPECT_EQ(kDBThreadName, db_watcher_->thread_name()); |
| 452 EXPECT_EQ(kSleepTime, db_watcher_->sleep_time()); | 456 EXPECT_EQ(kSleepTime, db_watcher_->sleep_time()); |
| 453 EXPECT_EQ(kUnresponsiveTime, db_watcher_->unresponsive_time()); | 457 EXPECT_EQ(kUnresponsiveTime, db_watcher_->unresponsive_time()); |
| 454 EXPECT_FALSE(db_watcher_->active()); | 458 EXPECT_FALSE(db_watcher_->active()); |
| 455 } | 459 } |
| 456 | 460 |
| 457 // Test ActivateThreadWatching and DeActivateThreadWatching of IO thread. This | 461 // Test ActivateThreadWatching and DeActivateThreadWatching of IO thread. This |
| 458 // method also checks that pong message was sent by the watched thread and pong | 462 // method also checks that pong message was sent by the watched thread and pong |
| 459 // message was received by the WatchDogThread. It also checks that | 463 // message was received by the WatchDogThread. It also checks that |
| 460 // OnCheckResponsiveness has verified the ping-pong mechanism and the watched | 464 // OnCheckResponsiveness has verified the ping-pong mechanism and the watched |
| 461 // thread is not hung. | 465 // thread is not hung. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 // This test posts a task on watched thread that takes very long time (this is | 499 // This test posts a task on watched thread that takes very long time (this is |
| 496 // to simulate hanging of watched thread). It then checks for | 500 // to simulate hanging of watched thread). It then checks for |
| 497 // OnCheckResponsiveness raising an alert (OnCheckResponsiveness returns false | 501 // OnCheckResponsiveness raising an alert (OnCheckResponsiveness returns false |
| 498 // if the watched thread is not responding). | 502 // if the watched thread is not responding). |
| 499 TEST_F(ThreadWatcherTest, ThreadNotResponding) { | 503 TEST_F(ThreadWatcherTest, ThreadNotResponding) { |
| 500 // Simulate hanging of watched thread by making the watched thread wait for a | 504 // Simulate hanging of watched thread by making the watched thread wait for a |
| 501 // very long time by posting a task on watched thread that keeps it busy. | 505 // very long time by posting a task on watched thread that keeps it busy. |
| 502 // It is safe to use base::Unretained because test is waiting for the method | 506 // It is safe to use base::Unretained because test is waiting for the method |
| 503 // to finish. | 507 // to finish. |
| 504 BrowserThread::PostTask( | 508 BrowserThread::PostTask( |
| 505 io_thread_id, | 509 BrowserThread::IO, FROM_HERE, |
| 506 FROM_HERE, | |
| 507 base::Bind(&CustomThreadWatcher::VeryLongMethod, | 510 base::Bind(&CustomThreadWatcher::VeryLongMethod, |
| 508 base::Unretained(io_watcher_), | 511 base::Unretained(io_watcher_), kUnresponsiveTime * 10)); |
| 509 kUnresponsiveTime * 10)); | |
| 510 | 512 |
| 511 // Activate thread watching. | 513 // Activate thread watching. |
| 512 WatchDogThread::PostTask( | 514 WatchDogThread::PostTask( |
| 513 FROM_HERE, | 515 FROM_HERE, |
| 514 base::Bind(&ThreadWatcher::ActivateThreadWatching, | 516 base::Bind(&ThreadWatcher::ActivateThreadWatching, |
| 515 base::Unretained(io_watcher_))); | 517 base::Unretained(io_watcher_))); |
| 516 | 518 |
| 517 // Verify watched thread is not responding for ping messages. | 519 // Verify watched thread is not responding for ping messages. |
| 518 io_watcher_->WaitForCheckResponse( | 520 io_watcher_->WaitForCheckResponse( |
| 519 kUnresponsiveTime + TimeDelta::FromMinutes(1), FAILED); | 521 kUnresponsiveTime + TimeDelta::FromMinutes(1), FAILED); |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 580 base::Unretained(db_watcher_))); | 582 base::Unretained(db_watcher_))); |
| 581 } | 583 } |
| 582 | 584 |
| 583 // Test watching of multiple threads with one of the threads not responding. | 585 // Test watching of multiple threads with one of the threads not responding. |
| 584 TEST_F(ThreadWatcherTest, MultipleThreadsNotResponding) { | 586 TEST_F(ThreadWatcherTest, MultipleThreadsNotResponding) { |
| 585 // Simulate hanging of watched thread by making the watched thread wait for a | 587 // Simulate hanging of watched thread by making the watched thread wait for a |
| 586 // very long time by posting a task on watched thread that keeps it busy. | 588 // very long time by posting a task on watched thread that keeps it busy. |
| 587 // It is safe ot use base::Unretained because test is waiting for the method | 589 // It is safe ot use base::Unretained because test is waiting for the method |
| 588 // to finish. | 590 // to finish. |
| 589 BrowserThread::PostTask( | 591 BrowserThread::PostTask( |
| 590 io_thread_id, | 592 BrowserThread::IO, FROM_HERE, |
| 591 FROM_HERE, | |
| 592 base::Bind(&CustomThreadWatcher::VeryLongMethod, | 593 base::Bind(&CustomThreadWatcher::VeryLongMethod, |
| 593 base::Unretained(io_watcher_), | 594 base::Unretained(io_watcher_), kUnresponsiveTime * 10)); |
| 594 kUnresponsiveTime * 10)); | |
| 595 | 595 |
| 596 // Activate watching of DB thread. | 596 // Activate watching of DB thread. |
| 597 WatchDogThread::PostTask( | 597 WatchDogThread::PostTask( |
| 598 FROM_HERE, | 598 FROM_HERE, |
| 599 base::Bind(&ThreadWatcher::ActivateThreadWatching, | 599 base::Bind(&ThreadWatcher::ActivateThreadWatching, |
| 600 base::Unretained(db_watcher_))); | 600 base::Unretained(db_watcher_))); |
| 601 | 601 |
| 602 // Activate watching of IO thread. | 602 // Activate watching of IO thread. |
| 603 WatchDogThread::PostTask( | 603 WatchDogThread::PostTask( |
| 604 FROM_HERE, | 604 FROM_HERE, |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(1), | 771 SPIN_FOR_TIMEDELTA_OR_UNTIL_TRUE(TimeDelta::FromMinutes(1), |
| 772 watchdog_thread_->Started()); | 772 watchdog_thread_->Started()); |
| 773 WaitForWatchDogThreadPostTask(); | 773 WaitForWatchDogThreadPostTask(); |
| 774 } | 774 } |
| 775 | 775 |
| 776 ~JankTimeBombTest() override { | 776 ~JankTimeBombTest() override { |
| 777 watchdog_thread_.reset(); | 777 watchdog_thread_.reset(); |
| 778 } | 778 } |
| 779 | 779 |
| 780 static void WaitForWatchDogThreadPostTask() { | 780 static void WaitForWatchDogThreadPostTask() { |
| 781 base::WaitableEvent watchdog_thread_event(false, false); | 781 base::WaitableEvent watchdog_thread_event( |
| 782 base::WaitableEvent::ResetPolicy::AUTOMATIC, |
| 783 base::WaitableEvent::InitialState::NOT_SIGNALED); |
| 782 PostAndWaitForWatchdogThread(&watchdog_thread_event); | 784 PostAndWaitForWatchdogThread(&watchdog_thread_event); |
| 783 } | 785 } |
| 784 | 786 |
| 785 private: | 787 private: |
| 786 static void OnJankTimeBombTask(base::WaitableEvent* event) { | 788 static void OnJankTimeBombTask(base::WaitableEvent* event) { |
| 787 event->Signal(); | 789 event->Signal(); |
| 788 } | 790 } |
| 789 | 791 |
| 790 static void PostAndWaitForWatchdogThread(base::WaitableEvent* event) { | 792 static void PostAndWaitForWatchdogThread(base::WaitableEvent* event) { |
| 791 WatchDogThread::PostDelayedTask( | 793 WatchDogThread::PostDelayedTask( |
| (...skipping 20 matching lines...) Expand all Loading... |
| 812 } | 814 } |
| 813 | 815 |
| 814 TEST_F(JankTimeBombTest, ArmTest) { | 816 TEST_F(JankTimeBombTest, ArmTest) { |
| 815 // Test firing of Alarm by passing empty delay. | 817 // Test firing of Alarm by passing empty delay. |
| 816 TestingJankTimeBomb timebomb((base::TimeDelta())); | 818 TestingJankTimeBomb timebomb((base::TimeDelta())); |
| 817 if (!timebomb.IsEnabled()) | 819 if (!timebomb.IsEnabled()) |
| 818 return; | 820 return; |
| 819 WaitForWatchDogThreadPostTask(); | 821 WaitForWatchDogThreadPostTask(); |
| 820 EXPECT_TRUE(timebomb.alarm_invoked()); | 822 EXPECT_TRUE(timebomb.alarm_invoked()); |
| 821 } | 823 } |
| OLD | NEW |