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 |