Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "mojo/message_pump/handle_watcher.h" | 5 #include "mojo/message_pump/handle_watcher.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/at_exit.h" | 9 #include "base/at_exit.h" |
| 10 #include "base/auto_reset.h" | 10 #include "base/auto_reset.h" |
| 11 #include "base/bind.h" | 11 #include "base/bind.h" |
| 12 #include "base/memory/scoped_vector.h" | |
| 13 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 14 #include "base/test/simple_test_tick_clock.h" | 13 #include "base/test/simple_test_tick_clock.h" |
| 15 #include "base/threading/thread.h" | |
| 16 #include "mojo/message_pump/message_pump_mojo.h" | 14 #include "mojo/message_pump/message_pump_mojo.h" |
| 17 #include "mojo/message_pump/time_helper.h" | 15 #include "mojo/message_pump/time_helper.h" |
| 18 #include "mojo/public/cpp/system/core.h" | 16 #include "mojo/public/cpp/system/core.h" |
| 19 #include "mojo/public/cpp/test_support/test_utils.h" | 17 #include "mojo/public/cpp/test_support/test_utils.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
| 21 | 19 |
| 22 namespace mojo { | 20 namespace mojo { |
| 23 namespace common { | 21 namespace common { |
| 24 namespace test { | 22 namespace test { |
| 25 | 23 |
| (...skipping 340 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 366 MOJO_DEADLINE_INDEFINITE, | 364 MOJO_DEADLINE_INDEFINITE, |
| 367 base::Bind(&ObserveCallback, &was_signaled, &result)); | 365 base::Bind(&ObserveCallback, &was_signaled, &result)); |
| 368 | 366 |
| 369 // Now, let the MessageLoop get torn down. We expect our callback to run. | 367 // Now, let the MessageLoop get torn down. We expect our callback to run. |
| 370 TearDownMessageLoop(); | 368 TearDownMessageLoop(); |
| 371 | 369 |
| 372 EXPECT_TRUE(was_signaled); | 370 EXPECT_TRUE(was_signaled); |
| 373 EXPECT_EQ(MOJO_RESULT_ABORTED, result); | 371 EXPECT_EQ(MOJO_RESULT_ABORTED, result); |
| 374 } | 372 } |
| 375 | 373 |
| 376 void NeverReached(MojoResult result) { | |
| 377 FAIL() << "Callback should never be invoked " << result; | |
| 378 } | |
| 379 | |
| 380 // Called on the main thread when a thread is done. Decrements |active_count| | |
| 381 // and if |active_count| is zero quits |run_loop|. | |
| 382 void StressThreadDone(base::RunLoop* run_loop, int* active_count) { | |
| 383 (*active_count)--; | |
| 384 EXPECT_GE(*active_count, 0); | |
| 385 if (*active_count == 0) | |
| 386 run_loop->Quit(); | |
| 387 } | |
| 388 | |
| 389 // See description of StressTest. This is called on the background thread. | |
| 390 // |count| is the number of HandleWatchers to create. |active_count| is the | |
| 391 // number of outstanding threads, |task_runner| the task runner for the main | |
| 392 // thread and |run_loop| the run loop that should be quit when there are no more | |
| 393 // threads running. When done StressThreadDone() is invoked on the main thread. | |
| 394 // |active_count| and |run_loop| should only be used on the main thread. | |
| 395 void RunStressTest(int count, | |
| 396 scoped_refptr<base::TaskRunner> task_runner, | |
| 397 base::RunLoop* run_loop, | |
| 398 int* active_count) { | |
| 399 struct TestData { | |
| 400 MessagePipe pipe; | |
| 401 HandleWatcher watcher; | |
| 402 }; | |
| 403 ScopedVector<TestData> data_vector; | |
| 404 for (int i = 0; i < count; ++i) { | |
| 405 if (i % 20 == 0) { | |
| 406 // Every so often we wait. This results in some level of thread balancing | |
| 407 // as well as making sure HandleWatcher has time to actually start some | |
| 408 // watches. | |
| 409 MessagePipe test_pipe; | |
| 410 ASSERT_TRUE(test_pipe.handle0.is_valid()); | |
| 411 CallbackHelper callback_helper; | |
| 412 HandleWatcher watcher; | |
| 413 callback_helper.Start(&watcher, test_pipe.handle0.get()); | |
| 414 RunUntilIdle(); | |
| 415 EXPECT_FALSE(callback_helper.got_callback()); | |
| 416 EXPECT_TRUE(mojo::test::WriteTextMessage(test_pipe.handle1.get(), | |
| 417 std::string())); | |
| 418 base::MessageLoop::ScopedNestableTaskAllower scoper( | |
| 419 base::MessageLoop::current()); | |
| 420 callback_helper.RunUntilGotCallback(); | |
| 421 EXPECT_TRUE(callback_helper.got_callback()); | |
| 422 } else { | |
| 423 scoped_ptr<TestData> test_data(new TestData); | |
| 424 ASSERT_TRUE(test_data->pipe.handle0.is_valid()); | |
| 425 test_data->watcher.Start(test_data->pipe.handle0.get(), | |
| 426 MOJO_HANDLE_SIGNAL_READABLE, | |
| 427 MOJO_DEADLINE_INDEFINITE, | |
| 428 base::Bind(&NeverReached)); | |
| 429 data_vector.push_back(test_data.release()); | |
| 430 } | |
| 431 if (i % 15 == 0) | |
| 432 data_vector.clear(); | |
| 433 } | |
| 434 task_runner->PostTask(FROM_HERE, | |
| 435 base::Bind(&StressThreadDone, run_loop, | |
| 436 active_count)); | |
| 437 } | |
| 438 | |
| 439 // This test is meant to stress HandleWatcher. It uses from various threads | |
| 440 // repeatedly starting and stopping watches. It spins up kThreadCount | |
| 441 // threads. Each thread creates kWatchCount watches. Every so often each thread | |
| 442 // writes to a pipe and waits for the response. | |
| 443 TEST(HandleWatcherCleanEnvironmentTest, StressTest) { | |
|
Anand Mistry (off Chromium)
2015/11/26 02:49:04
Can you keep this test? If HandleWatcher is functi
jam
2015/11/26 03:32:01
ah good point thanks. I had blindly reverted it. B
| |
| 444 #if defined(NDEBUG) | |
| 445 const int kThreadCount = 15; | |
| 446 const int kWatchCount = 400; | |
| 447 #else | |
| 448 const int kThreadCount = 10; | |
| 449 const int kWatchCount = 250; | |
| 450 #endif | |
| 451 | |
| 452 base::ShadowingAtExitManager at_exit; | |
| 453 base::MessageLoop message_loop; | |
| 454 base::RunLoop run_loop; | |
| 455 ScopedVector<base::Thread> threads; | |
| 456 int threads_active_counter = kThreadCount; | |
| 457 // Starts the threads first and then post the task in hopes of having more | |
| 458 // threads running at once. | |
| 459 for (int i = 0; i < kThreadCount; ++i) { | |
| 460 scoped_ptr<base::Thread> thread(new base::Thread("test thread")); | |
| 461 if (i % 2) { | |
| 462 base::Thread::Options thread_options; | |
| 463 thread_options.message_pump_factory = | |
| 464 base::Bind(&MessagePumpMojo::Create); | |
| 465 thread->StartWithOptions(thread_options); | |
| 466 } else { | |
| 467 thread->Start(); | |
| 468 } | |
| 469 threads.push_back(thread.release()); | |
| 470 } | |
| 471 for (int i = 0; i < kThreadCount; ++i) { | |
| 472 threads[i]->task_runner()->PostTask( | |
| 473 FROM_HERE, base::Bind(&RunStressTest, kWatchCount, | |
| 474 message_loop.task_runner(), | |
| 475 &run_loop, &threads_active_counter)); | |
| 476 } | |
| 477 run_loop.Run(); | |
| 478 ASSERT_EQ(0, threads_active_counter); | |
| 479 } | |
| 480 | |
| 481 } // namespace test | 374 } // namespace test |
| 482 } // namespace common | 375 } // namespace common |
| 483 } // namespace mojo | 376 } // namespace mojo |
| OLD | NEW |