Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. | 2 * Copyright 2004 The WebRTC Project Authors. All rights reserved. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license |
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source |
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found |
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
| 9 */ | 9 */ |
| 10 | 10 |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 511 invoker.Flush(Thread::Current(), 5); | 511 invoker.Flush(Thread::Current(), 5); |
| 512 EXPECT_TRUE(flag1); | 512 EXPECT_TRUE(flag1); |
| 513 EXPECT_FALSE(flag2); | 513 EXPECT_FALSE(flag2); |
| 514 flag1 = false; | 514 flag1 = false; |
| 515 // Execute all pending calls. The id == 5 call should not execute again. | 515 // Execute all pending calls. The id == 5 call should not execute again. |
| 516 invoker.Flush(Thread::Current()); | 516 invoker.Flush(Thread::Current()); |
| 517 EXPECT_FALSE(flag1); | 517 EXPECT_FALSE(flag1); |
| 518 EXPECT_TRUE(flag2); | 518 EXPECT_TRUE(flag2); |
| 519 } | 519 } |
| 520 | 520 |
| 521 class GuardedAsyncInvokeTest : public testing::Test { | |
| 522 public: | |
| 523 void IntCallback(int value) { | |
| 524 EXPECT_EQ(expected_thread_, Thread::Current()); | |
| 525 int_value_ = value; | |
| 526 } | |
| 527 void AsyncInvokeIntCallback(GuardedAsyncInvoker* invoker, Thread* thread) { | |
| 528 expected_thread_ = thread; | |
| 529 invoker->AsyncInvoke(FunctorC(), &GuardedAsyncInvokeTest::IntCallback, | |
| 530 static_cast<GuardedAsyncInvokeTest*>(this)); | |
| 531 invoke_started_.Set(); | |
| 532 } | |
| 533 void SetExpectedThreadForIntCallback(Thread* thread) { | |
| 534 expected_thread_ = thread; | |
| 535 } | |
| 536 | |
| 537 protected: | |
| 538 enum { kWaitTimeout = 1000 }; | |
|
tommi (sloooow) - chröme
2015/08/19 20:01:54
const static int
I think using enums this way is
magjed_webrtc
2015/08/20 10:28:33
Done.
| |
| 539 GuardedAsyncInvokeTest() | |
| 540 : int_value_(0), invoke_started_(true, false), expected_thread_(NULL) {} | |
|
tommi (sloooow) - chröme
2015/08/19 20:01:54
nit: nullptr
magjed_webrtc
2015/08/20 10:28:33
Done.
| |
| 541 | |
| 542 int int_value_; | |
| 543 Event invoke_started_; | |
| 544 Thread* expected_thread_; | |
| 545 }; | |
| 546 | |
| 547 struct CreateInvoker { | |
| 548 CreateInvoker(scoped_ptr<GuardedAsyncInvoker>* invoker) : invoker_(invoker) {} | |
| 549 void operator()() { invoker_->reset(new GuardedAsyncInvoker()); } | |
| 550 scoped_ptr<GuardedAsyncInvoker>* invoker_; | |
| 551 }; | |
| 552 | |
| 553 // Test that we can call AsyncInvoke<void>() after the thread died. | |
| 554 TEST_F(GuardedAsyncInvokeTest, KillThreadFireAndForget) { | |
| 555 // Create and start the thread. | |
| 556 scoped_ptr<Thread> thread(new Thread()); | |
| 557 thread->Start(); | |
| 558 scoped_ptr<GuardedAsyncInvoker> invoker; | |
| 559 // Create the invoker on |thread|. | |
| 560 thread->Invoke<void>(CreateInvoker(&invoker)); | |
| 561 // Kill |thread|. | |
| 562 thread = nullptr; | |
| 563 // Try calling functor. | |
| 564 bool called = false; | |
| 565 invoker->AsyncInvoke<void>(FunctorB(&called)); | |
| 566 // With thread gone, nothing should happen. | |
| 567 WAIT(called, kWaitTimeout); | |
| 568 EXPECT_FALSE(called); | |
| 569 } | |
| 570 | |
| 571 // Test that we can call AsyncInvoke with callback after the thread died. | |
| 572 TEST_F(GuardedAsyncInvokeTest, KillThreadWithCallback) { | |
| 573 // Create and start the thread. | |
| 574 scoped_ptr<Thread> thread(new Thread()); | |
| 575 thread->Start(); | |
| 576 scoped_ptr<GuardedAsyncInvoker> invoker; | |
| 577 // Create the invoker on |thread|. | |
| 578 thread->Invoke<void>(CreateInvoker(&invoker)); | |
| 579 // Kill |thread|. | |
| 580 thread = nullptr; | |
| 581 // Try calling functor. | |
| 582 invoker->AsyncInvoke(FunctorC(), &GuardedAsyncInvokeTest::IntCallback, | |
| 583 static_cast<GuardedAsyncInvokeTest*>(this)); | |
| 584 // With thread gone, callback should be cancelled. | |
| 585 Thread::Current()->ProcessMessages(kWaitTimeout); | |
| 586 EXPECT_EQ(0, int_value_); | |
| 587 } | |
| 588 | |
| 589 // The remaining tests check that GuardedAsyncInvoker behaves as AsyncInvoker | |
| 590 // when Thread is still alive. | |
| 591 TEST_F(GuardedAsyncInvokeTest, FireAndForget) { | |
| 592 GuardedAsyncInvoker invoker; | |
| 593 // Try calling functor. | |
| 594 bool called = false; | |
| 595 invoker.AsyncInvoke<void>(FunctorB(&called)); | |
| 596 EXPECT_TRUE_WAIT(called, kWaitTimeout); | |
| 597 } | |
| 598 | |
| 599 TEST_F(GuardedAsyncInvokeTest, WithCallback) { | |
| 600 GuardedAsyncInvoker invoker; | |
| 601 // Try calling functor. | |
| 602 SetExpectedThreadForIntCallback(Thread::Current()); | |
| 603 invoker.AsyncInvoke(FunctorA(), &GuardedAsyncInvokeTest::IntCallback, | |
| 604 static_cast<GuardedAsyncInvokeTest*>(this)); | |
| 605 EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout); | |
| 606 } | |
| 607 | |
| 608 TEST_F(GuardedAsyncInvokeTest, CancelInvoker) { | |
| 609 // Try destroying invoker during call. | |
| 610 { | |
| 611 GuardedAsyncInvoker invoker; | |
| 612 invoker.AsyncInvoke(FunctorC(), &GuardedAsyncInvokeTest::IntCallback, | |
| 613 static_cast<GuardedAsyncInvokeTest*>(this)); | |
| 614 } | |
| 615 // With invoker gone, callback should be cancelled. | |
| 616 Thread::Current()->ProcessMessages(kWaitTimeout); | |
| 617 EXPECT_EQ(0, int_value_); | |
| 618 } | |
| 619 | |
| 620 TEST_F(GuardedAsyncInvokeTest, CancelCallingThread) { | |
| 621 GuardedAsyncInvoker invoker; | |
| 622 // Try destroying calling thread during call. | |
| 623 { | |
| 624 Thread thread; | |
| 625 thread.Start(); | |
| 626 // Try calling functor. | |
| 627 thread.Invoke<void>(Bind(&GuardedAsyncInvokeTest::AsyncInvokeIntCallback, | |
| 628 static_cast<GuardedAsyncInvokeTest*>(this), | |
| 629 &invoker, Thread::Current())); | |
| 630 // Wait for the call to begin. | |
| 631 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); | |
| 632 } | |
| 633 // Calling thread is gone. Return message shouldn't happen. | |
| 634 Thread::Current()->ProcessMessages(kWaitTimeout); | |
| 635 EXPECT_EQ(0, int_value_); | |
| 636 } | |
| 637 | |
| 638 TEST_F(GuardedAsyncInvokeTest, KillInvokerBeforeExecute) { | |
| 639 Thread thread; | |
| 640 thread.Start(); | |
| 641 { | |
| 642 GuardedAsyncInvoker invoker; | |
| 643 // Try calling functor. | |
| 644 thread.Invoke<void>(Bind(&GuardedAsyncInvokeTest::AsyncInvokeIntCallback, | |
| 645 static_cast<GuardedAsyncInvokeTest*>(this), | |
| 646 &invoker, Thread::Current())); | |
| 647 // Wait for the call to begin. | |
| 648 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); | |
| 649 } | |
| 650 // Invoker is destroyed. Function should not execute. | |
| 651 Thread::Current()->ProcessMessages(kWaitTimeout); | |
| 652 EXPECT_EQ(0, int_value_); | |
| 653 } | |
| 654 | |
| 655 TEST_F(GuardedAsyncInvokeTest, Flush) { | |
| 656 GuardedAsyncInvoker invoker; | |
| 657 bool flag1 = false; | |
| 658 bool flag2 = false; | |
| 659 // Queue two async calls to the current thread. | |
| 660 invoker.AsyncInvoke<void>(FunctorB(&flag1)); | |
| 661 invoker.AsyncInvoke<void>(FunctorB(&flag2)); | |
| 662 // Because we haven't pumped messages, these should not have run yet. | |
| 663 EXPECT_FALSE(flag1); | |
| 664 EXPECT_FALSE(flag2); | |
| 665 // Force them to run now. | |
| 666 invoker.Flush(); | |
| 667 EXPECT_TRUE(flag1); | |
| 668 EXPECT_TRUE(flag2); | |
| 669 } | |
| 670 | |
| 671 TEST_F(GuardedAsyncInvokeTest, FlushWithIds) { | |
| 672 GuardedAsyncInvoker invoker; | |
| 673 bool flag1 = false; | |
| 674 bool flag2 = false; | |
| 675 // Queue two async calls to the current thread, one with a message id. | |
| 676 invoker.AsyncInvoke<void>(FunctorB(&flag1), 5); | |
| 677 invoker.AsyncInvoke<void>(FunctorB(&flag2)); | |
| 678 // Because we haven't pumped messages, these should not have run yet. | |
| 679 EXPECT_FALSE(flag1); | |
| 680 EXPECT_FALSE(flag2); | |
| 681 // Execute pending calls with id == 5. | |
| 682 invoker.Flush(5); | |
| 683 EXPECT_TRUE(flag1); | |
| 684 EXPECT_FALSE(flag2); | |
| 685 flag1 = false; | |
| 686 // Execute all pending calls. The id == 5 call should not execute again. | |
| 687 invoker.Flush(); | |
| 688 EXPECT_FALSE(flag1); | |
| 689 EXPECT_TRUE(flag2); | |
| 690 } | |
| 521 | 691 |
| 522 #if defined(WEBRTC_WIN) | 692 #if defined(WEBRTC_WIN) |
| 523 class ComThreadTest : public testing::Test, public MessageHandler { | 693 class ComThreadTest : public testing::Test, public MessageHandler { |
| 524 public: | 694 public: |
| 525 ComThreadTest() : done_(false) {} | 695 ComThreadTest() : done_(false) {} |
| 526 protected: | 696 protected: |
| 527 virtual void OnMessage(Message* message) { | 697 virtual void OnMessage(Message* message) { |
| 528 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); | 698 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); |
| 529 // S_FALSE means the thread was already inited for a multithread apartment. | 699 // S_FALSE means the thread was already inited for a multithread apartment. |
| 530 EXPECT_EQ(S_FALSE, hr); | 700 EXPECT_EQ(S_FALSE, hr); |
| 531 if (SUCCEEDED(hr)) { | 701 if (SUCCEEDED(hr)) { |
| 532 CoUninitialize(); | 702 CoUninitialize(); |
| 533 } | 703 } |
| 534 done_ = true; | 704 done_ = true; |
| 535 } | 705 } |
| 536 bool done_; | 706 bool done_; |
| 537 }; | 707 }; |
| 538 | 708 |
| 539 TEST_F(ComThreadTest, ComInited) { | 709 TEST_F(ComThreadTest, ComInited) { |
| 540 Thread* thread = new ComThread(); | 710 Thread* thread = new ComThread(); |
| 541 EXPECT_TRUE(thread->Start()); | 711 EXPECT_TRUE(thread->Start()); |
| 542 thread->Post(this, 0); | 712 thread->Post(this, 0); |
| 543 EXPECT_TRUE_WAIT(done_, 1000); | 713 EXPECT_TRUE_WAIT(done_, 1000); |
| 544 delete thread; | 714 delete thread; |
| 545 } | 715 } |
| 546 #endif | 716 #endif |
| OLD | NEW |