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 const static int kWaitTimeout = 1000; |
| 539 GuardedAsyncInvokeTest() |
| 540 : int_value_(0), |
| 541 invoke_started_(true, false), |
| 542 expected_thread_(nullptr) {} |
| 543 |
| 544 int int_value_; |
| 545 Event invoke_started_; |
| 546 Thread* expected_thread_; |
| 547 }; |
| 548 |
| 549 // Functor for creating an invoker. |
| 550 struct CreateInvoker { |
| 551 CreateInvoker(scoped_ptr<GuardedAsyncInvoker>* invoker) : invoker_(invoker) {} |
| 552 void operator()() { invoker_->reset(new GuardedAsyncInvoker()); } |
| 553 scoped_ptr<GuardedAsyncInvoker>* invoker_; |
| 554 }; |
| 555 |
| 556 // Test that we can call AsyncInvoke<void>() after the thread died. |
| 557 TEST_F(GuardedAsyncInvokeTest, KillThreadFireAndForget) { |
| 558 // Create and start the thread. |
| 559 scoped_ptr<Thread> thread(new Thread()); |
| 560 thread->Start(); |
| 561 scoped_ptr<GuardedAsyncInvoker> invoker; |
| 562 // Create the invoker on |thread|. |
| 563 thread->Invoke<void>(CreateInvoker(&invoker)); |
| 564 // Kill |thread|. |
| 565 thread = nullptr; |
| 566 // Try calling functor. |
| 567 bool called = false; |
| 568 EXPECT_FALSE(invoker->AsyncInvoke<void>(FunctorB(&called))); |
| 569 // With thread gone, nothing should happen. |
| 570 WAIT(called, kWaitTimeout); |
| 571 EXPECT_FALSE(called); |
| 572 } |
| 573 |
| 574 // Test that we can call AsyncInvoke with callback after the thread died. |
| 575 TEST_F(GuardedAsyncInvokeTest, KillThreadWithCallback) { |
| 576 // Create and start the thread. |
| 577 scoped_ptr<Thread> thread(new Thread()); |
| 578 thread->Start(); |
| 579 scoped_ptr<GuardedAsyncInvoker> invoker; |
| 580 // Create the invoker on |thread|. |
| 581 thread->Invoke<void>(CreateInvoker(&invoker)); |
| 582 // Kill |thread|. |
| 583 thread = nullptr; |
| 584 // Try calling functor. |
| 585 EXPECT_FALSE( |
| 586 invoker->AsyncInvoke(FunctorC(), &GuardedAsyncInvokeTest::IntCallback, |
| 587 static_cast<GuardedAsyncInvokeTest*>(this))); |
| 588 // With thread gone, callback should be cancelled. |
| 589 Thread::Current()->ProcessMessages(kWaitTimeout); |
| 590 EXPECT_EQ(0, int_value_); |
| 591 } |
| 592 |
| 593 // The remaining tests check that GuardedAsyncInvoker behaves as AsyncInvoker |
| 594 // when Thread is still alive. |
| 595 TEST_F(GuardedAsyncInvokeTest, FireAndForget) { |
| 596 GuardedAsyncInvoker invoker; |
| 597 // Try calling functor. |
| 598 bool called = false; |
| 599 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&called))); |
| 600 EXPECT_TRUE_WAIT(called, kWaitTimeout); |
| 601 } |
| 602 |
| 603 TEST_F(GuardedAsyncInvokeTest, WithCallback) { |
| 604 GuardedAsyncInvoker invoker; |
| 605 // Try calling functor. |
| 606 SetExpectedThreadForIntCallback(Thread::Current()); |
| 607 EXPECT_TRUE(invoker.AsyncInvoke(FunctorA(), |
| 608 &GuardedAsyncInvokeTest::IntCallback, |
| 609 static_cast<GuardedAsyncInvokeTest*>(this))); |
| 610 EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout); |
| 611 } |
| 612 |
| 613 TEST_F(GuardedAsyncInvokeTest, CancelInvoker) { |
| 614 // Try destroying invoker during call. |
| 615 { |
| 616 GuardedAsyncInvoker invoker; |
| 617 EXPECT_TRUE( |
| 618 invoker.AsyncInvoke(FunctorC(), &GuardedAsyncInvokeTest::IntCallback, |
| 619 static_cast<GuardedAsyncInvokeTest*>(this))); |
| 620 } |
| 621 // With invoker gone, callback should be cancelled. |
| 622 Thread::Current()->ProcessMessages(kWaitTimeout); |
| 623 EXPECT_EQ(0, int_value_); |
| 624 } |
| 625 |
| 626 TEST_F(GuardedAsyncInvokeTest, CancelCallingThread) { |
| 627 GuardedAsyncInvoker invoker; |
| 628 // Try destroying calling thread during call. |
| 629 { |
| 630 Thread thread; |
| 631 thread.Start(); |
| 632 // Try calling functor. |
| 633 thread.Invoke<void>(Bind(&GuardedAsyncInvokeTest::AsyncInvokeIntCallback, |
| 634 static_cast<GuardedAsyncInvokeTest*>(this), |
| 635 &invoker, Thread::Current())); |
| 636 // Wait for the call to begin. |
| 637 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); |
| 638 } |
| 639 // Calling thread is gone. Return message shouldn't happen. |
| 640 Thread::Current()->ProcessMessages(kWaitTimeout); |
| 641 EXPECT_EQ(0, int_value_); |
| 642 } |
| 643 |
| 644 TEST_F(GuardedAsyncInvokeTest, KillInvokerBeforeExecute) { |
| 645 Thread thread; |
| 646 thread.Start(); |
| 647 { |
| 648 GuardedAsyncInvoker invoker; |
| 649 // Try calling functor. |
| 650 thread.Invoke<void>(Bind(&GuardedAsyncInvokeTest::AsyncInvokeIntCallback, |
| 651 static_cast<GuardedAsyncInvokeTest*>(this), |
| 652 &invoker, Thread::Current())); |
| 653 // Wait for the call to begin. |
| 654 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); |
| 655 } |
| 656 // Invoker is destroyed. Function should not execute. |
| 657 Thread::Current()->ProcessMessages(kWaitTimeout); |
| 658 EXPECT_EQ(0, int_value_); |
| 659 } |
| 660 |
| 661 TEST_F(GuardedAsyncInvokeTest, Flush) { |
| 662 GuardedAsyncInvoker invoker; |
| 663 bool flag1 = false; |
| 664 bool flag2 = false; |
| 665 // Queue two async calls to the current thread. |
| 666 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag1))); |
| 667 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag2))); |
| 668 // Because we haven't pumped messages, these should not have run yet. |
| 669 EXPECT_FALSE(flag1); |
| 670 EXPECT_FALSE(flag2); |
| 671 // Force them to run now. |
| 672 EXPECT_TRUE(invoker.Flush()); |
| 673 EXPECT_TRUE(flag1); |
| 674 EXPECT_TRUE(flag2); |
| 675 } |
| 676 |
| 677 TEST_F(GuardedAsyncInvokeTest, FlushWithIds) { |
| 678 GuardedAsyncInvoker invoker; |
| 679 bool flag1 = false; |
| 680 bool flag2 = false; |
| 681 // Queue two async calls to the current thread, one with a message id. |
| 682 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag1), 5)); |
| 683 EXPECT_TRUE(invoker.AsyncInvoke<void>(FunctorB(&flag2))); |
| 684 // Because we haven't pumped messages, these should not have run yet. |
| 685 EXPECT_FALSE(flag1); |
| 686 EXPECT_FALSE(flag2); |
| 687 // Execute pending calls with id == 5. |
| 688 EXPECT_TRUE(invoker.Flush(5)); |
| 689 EXPECT_TRUE(flag1); |
| 690 EXPECT_FALSE(flag2); |
| 691 flag1 = false; |
| 692 // Execute all pending calls. The id == 5 call should not execute again. |
| 693 EXPECT_TRUE(invoker.Flush()); |
| 694 EXPECT_FALSE(flag1); |
| 695 EXPECT_TRUE(flag2); |
| 696 } |
521 | 697 |
522 #if defined(WEBRTC_WIN) | 698 #if defined(WEBRTC_WIN) |
523 class ComThreadTest : public testing::Test, public MessageHandler { | 699 class ComThreadTest : public testing::Test, public MessageHandler { |
524 public: | 700 public: |
525 ComThreadTest() : done_(false) {} | 701 ComThreadTest() : done_(false) {} |
526 protected: | 702 protected: |
527 virtual void OnMessage(Message* message) { | 703 virtual void OnMessage(Message* message) { |
528 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); | 704 HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); |
529 // S_FALSE means the thread was already inited for a multithread apartment. | 705 // S_FALSE means the thread was already inited for a multithread apartment. |
530 EXPECT_EQ(S_FALSE, hr); | 706 EXPECT_EQ(S_FALSE, hr); |
531 if (SUCCEEDED(hr)) { | 707 if (SUCCEEDED(hr)) { |
532 CoUninitialize(); | 708 CoUninitialize(); |
533 } | 709 } |
534 done_ = true; | 710 done_ = true; |
535 } | 711 } |
536 bool done_; | 712 bool done_; |
537 }; | 713 }; |
538 | 714 |
539 TEST_F(ComThreadTest, ComInited) { | 715 TEST_F(ComThreadTest, ComInited) { |
540 Thread* thread = new ComThread(); | 716 Thread* thread = new ComThread(); |
541 EXPECT_TRUE(thread->Start()); | 717 EXPECT_TRUE(thread->Start()); |
542 thread->Post(this, 0); | 718 thread->Post(this, 0); |
543 EXPECT_TRUE_WAIT(done_, 1000); | 719 EXPECT_TRUE_WAIT(done_, 1000); |
544 delete thread; | 720 delete thread; |
545 } | 721 } |
546 #endif | 722 #endif |
OLD | NEW |