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 403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
414 SetNameOnSignalQueueDestroyedTester tester2(thread2); | 414 SetNameOnSignalQueueDestroyedTester tester2(thread2); |
415 delete thread2; | 415 delete thread2; |
416 } | 416 } |
417 | 417 |
418 class AsyncInvokeTest : public testing::Test { | 418 class AsyncInvokeTest : public testing::Test { |
419 public: | 419 public: |
420 void IntCallback(int value) { | 420 void IntCallback(int value) { |
421 EXPECT_EQ(expected_thread_, Thread::Current()); | 421 EXPECT_EQ(expected_thread_, Thread::Current()); |
422 int_value_ = value; | 422 int_value_ = value; |
423 } | 423 } |
424 void AsyncInvokeIntCallback(AsyncInvoker* invoker, Thread* thread) { | |
425 expected_thread_ = thread; | |
426 invoker->AsyncInvoke(RTC_FROM_HERE, RTC_FROM_HERE, thread, FunctorC(), | |
427 &AsyncInvokeTest::IntCallback, | |
428 static_cast<AsyncInvokeTest*>(this)); | |
429 invoke_started_.Set(); | |
430 } | |
431 void SetExpectedThreadForIntCallback(Thread* thread) { | 424 void SetExpectedThreadForIntCallback(Thread* thread) { |
432 expected_thread_ = thread; | 425 expected_thread_ = thread; |
433 } | 426 } |
434 | 427 |
435 protected: | 428 protected: |
436 enum { kWaitTimeout = 1000 }; | 429 enum { kWaitTimeout = 1000 }; |
437 AsyncInvokeTest() | 430 AsyncInvokeTest() |
438 : int_value_(0), | 431 : int_value_(0), |
439 invoke_started_(true, false), | |
440 expected_thread_(nullptr) {} | 432 expected_thread_(nullptr) {} |
441 | 433 |
442 int int_value_; | 434 int int_value_; |
443 Event invoke_started_; | |
444 Thread* expected_thread_; | 435 Thread* expected_thread_; |
445 }; | 436 }; |
446 | 437 |
447 TEST_F(AsyncInvokeTest, FireAndForget) { | 438 TEST_F(AsyncInvokeTest, FireAndForget) { |
448 AsyncInvoker invoker; | 439 AsyncInvoker invoker; |
449 // Create and start the thread. | 440 // Create and start the thread. |
450 Thread thread; | 441 Thread thread; |
451 thread.Start(); | 442 thread.Start(); |
452 // Try calling functor. | 443 // Try calling functor. |
453 AtomicBool called; | 444 AtomicBool called; |
454 invoker.AsyncInvoke<void>(RTC_FROM_HERE, &thread, FunctorB(&called)); | 445 invoker.AsyncInvoke<void>(RTC_FROM_HERE, &thread, FunctorB(&called)); |
455 EXPECT_TRUE_WAIT(called.get(), kWaitTimeout); | 446 EXPECT_TRUE_WAIT(called.get(), kWaitTimeout); |
456 } | 447 } |
457 | 448 |
458 TEST_F(AsyncInvokeTest, WithCallback) { | |
459 AsyncInvoker invoker; | |
460 // Create and start the thread. | |
461 Thread thread; | |
462 thread.Start(); | |
463 // Try calling functor. | |
464 SetExpectedThreadForIntCallback(Thread::Current()); | |
465 invoker.AsyncInvoke(RTC_FROM_HERE, RTC_FROM_HERE, &thread, FunctorA(), | |
466 &AsyncInvokeTest::IntCallback, | |
467 static_cast<AsyncInvokeTest*>(this)); | |
468 EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout); | |
469 } | |
470 | |
471 TEST_F(AsyncInvokeTest, CancelInvoker) { | |
472 // Create and start the thread. | |
473 Thread thread; | |
474 thread.Start(); | |
475 // Try destroying invoker during call. | |
476 { | |
477 AsyncInvoker invoker; | |
478 invoker.AsyncInvoke(RTC_FROM_HERE, RTC_FROM_HERE, &thread, FunctorC(), | |
479 &AsyncInvokeTest::IntCallback, | |
480 static_cast<AsyncInvokeTest*>(this)); | |
481 } | |
482 // With invoker gone, callback should be cancelled. | |
483 Thread::Current()->ProcessMessages(kWaitTimeout); | |
484 EXPECT_EQ(0, int_value_); | |
485 } | |
486 | |
487 TEST_F(AsyncInvokeTest, CancelCallingThread) { | |
488 AsyncInvoker invoker; | |
489 { // Create and start the thread. | |
490 Thread thread; | |
491 thread.Start(); | |
492 // Try calling functor. | |
493 thread.Invoke<void>( | |
494 RTC_FROM_HERE, | |
495 Bind(&AsyncInvokeTest::AsyncInvokeIntCallback, | |
496 static_cast<AsyncInvokeTest*>(this), &invoker, Thread::Current())); | |
497 // Wait for the call to begin. | |
498 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); | |
499 } | |
500 // Calling thread is gone. Return message shouldn't happen. | |
501 Thread::Current()->ProcessMessages(kWaitTimeout); | |
502 EXPECT_EQ(0, int_value_); | |
503 } | |
504 | |
505 TEST_F(AsyncInvokeTest, KillInvokerBeforeExecute) { | |
506 Thread thread; | |
507 thread.Start(); | |
508 { | |
509 AsyncInvoker invoker; | |
510 // Try calling functor. | |
511 thread.Invoke<void>( | |
512 RTC_FROM_HERE, | |
513 Bind(&AsyncInvokeTest::AsyncInvokeIntCallback, | |
514 static_cast<AsyncInvokeTest*>(this), &invoker, Thread::Current())); | |
515 // Wait for the call to begin. | |
516 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); | |
517 } | |
518 // Invoker is destroyed. Function should not execute. | |
519 Thread::Current()->ProcessMessages(kWaitTimeout); | |
520 EXPECT_EQ(0, int_value_); | |
521 } | |
Taylor Brandstetter
2017/05/17 18:25:28
Sorry for the late feedback, but these tests need
Taylor Brandstetter
2017/05/17 21:15:06
Here's a CL that adds a test that does what I'm ta
| |
522 | |
523 TEST_F(AsyncInvokeTest, KillInvokerDuringExecute) { | 449 TEST_F(AsyncInvokeTest, KillInvokerDuringExecute) { |
524 // Use these events to get in a state where the functor is in the middle of | 450 // Use these events to get in a state where the functor is in the middle of |
525 // executing, and then to wait for it to finish, ensuring the "EXPECT_FALSE" | 451 // executing, and then to wait for it to finish, ensuring the "EXPECT_FALSE" |
526 // is run. | 452 // is run. |
527 Event functor_started(false, false); | 453 Event functor_started(false, false); |
528 Event functor_continue(false, false); | 454 Event functor_continue(false, false); |
529 Event functor_finished(false, false); | 455 Event functor_finished(false, false); |
530 | 456 |
531 Thread thread; | 457 Thread thread; |
532 thread.Start(); | 458 thread.Start(); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
592 EXPECT_FALSE(flag1.get()); | 518 EXPECT_FALSE(flag1.get()); |
593 EXPECT_TRUE(flag2.get()); | 519 EXPECT_TRUE(flag2.get()); |
594 } | 520 } |
595 | 521 |
596 class GuardedAsyncInvokeTest : public testing::Test { | 522 class GuardedAsyncInvokeTest : public testing::Test { |
597 public: | 523 public: |
598 void IntCallback(int value) { | 524 void IntCallback(int value) { |
599 EXPECT_EQ(expected_thread_, Thread::Current()); | 525 EXPECT_EQ(expected_thread_, Thread::Current()); |
600 int_value_ = value; | 526 int_value_ = value; |
601 } | 527 } |
602 void AsyncInvokeIntCallback(GuardedAsyncInvoker* invoker, Thread* thread) { | |
603 expected_thread_ = thread; | |
604 invoker->AsyncInvoke(RTC_FROM_HERE, RTC_FROM_HERE, FunctorC(), | |
605 &GuardedAsyncInvokeTest::IntCallback, | |
606 static_cast<GuardedAsyncInvokeTest*>(this)); | |
607 invoke_started_.Set(); | |
608 } | |
609 void SetExpectedThreadForIntCallback(Thread* thread) { | 528 void SetExpectedThreadForIntCallback(Thread* thread) { |
610 expected_thread_ = thread; | 529 expected_thread_ = thread; |
611 } | 530 } |
612 | 531 |
613 protected: | 532 protected: |
614 const static int kWaitTimeout = 1000; | 533 const static int kWaitTimeout = 1000; |
615 GuardedAsyncInvokeTest() | 534 GuardedAsyncInvokeTest() |
616 : int_value_(0), | 535 : int_value_(0), |
617 invoke_started_(true, false), | |
618 expected_thread_(nullptr) {} | 536 expected_thread_(nullptr) {} |
619 | 537 |
620 int int_value_; | 538 int int_value_; |
621 Event invoke_started_; | |
622 Thread* expected_thread_; | 539 Thread* expected_thread_; |
623 }; | 540 }; |
624 | 541 |
625 // Functor for creating an invoker. | 542 // Functor for creating an invoker. |
626 struct CreateInvoker { | 543 struct CreateInvoker { |
627 CreateInvoker(std::unique_ptr<GuardedAsyncInvoker>* invoker) | 544 CreateInvoker(std::unique_ptr<GuardedAsyncInvoker>* invoker) |
628 : invoker_(invoker) {} | 545 : invoker_(invoker) {} |
629 void operator()() { invoker_->reset(new GuardedAsyncInvoker()); } | 546 void operator()() { invoker_->reset(new GuardedAsyncInvoker()); } |
630 std::unique_ptr<GuardedAsyncInvoker>* invoker_; | 547 std::unique_ptr<GuardedAsyncInvoker>* invoker_; |
631 }; | 548 }; |
632 | 549 |
633 // Test that we can call AsyncInvoke<void>() after the thread died. | 550 // Test that we can call AsyncInvoke<void>() after the thread died. |
634 TEST_F(GuardedAsyncInvokeTest, KillThreadFireAndForget) { | 551 TEST_F(GuardedAsyncInvokeTest, KillThreadFireAndForget) { |
635 // Create and start the thread. | 552 // Create and start the thread. |
636 std::unique_ptr<Thread> thread(new Thread()); | 553 std::unique_ptr<Thread> thread(new Thread()); |
637 thread->Start(); | 554 thread->Start(); |
638 std::unique_ptr<GuardedAsyncInvoker> invoker; | 555 std::unique_ptr<GuardedAsyncInvoker> invoker; |
639 // Create the invoker on |thread|. | 556 // Create the invoker on |thread|. |
640 thread->Invoke<void>(RTC_FROM_HERE, CreateInvoker(&invoker)); | 557 thread->Invoke<void>(RTC_FROM_HERE, CreateInvoker(&invoker)); |
641 // Kill |thread|. | 558 // Kill |thread|. |
642 thread = nullptr; | 559 thread = nullptr; |
643 // Try calling functor. | 560 // Try calling functor. |
644 AtomicBool called; | 561 AtomicBool called; |
645 EXPECT_FALSE(invoker->AsyncInvoke<void>(RTC_FROM_HERE, FunctorB(&called))); | 562 EXPECT_FALSE(invoker->AsyncInvoke<void>(RTC_FROM_HERE, FunctorB(&called))); |
646 // With thread gone, nothing should happen. | 563 // With thread gone, nothing should happen. |
647 WAIT(called.get(), kWaitTimeout); | 564 WAIT(called.get(), kWaitTimeout); |
648 EXPECT_FALSE(called.get()); | 565 EXPECT_FALSE(called.get()); |
649 } | 566 } |
650 | 567 |
651 // Test that we can call AsyncInvoke with callback after the thread died. | |
652 TEST_F(GuardedAsyncInvokeTest, KillThreadWithCallback) { | |
653 // Create and start the thread. | |
654 std::unique_ptr<Thread> thread(new Thread()); | |
655 thread->Start(); | |
656 std::unique_ptr<GuardedAsyncInvoker> invoker; | |
657 // Create the invoker on |thread|. | |
658 thread->Invoke<void>(RTC_FROM_HERE, CreateInvoker(&invoker)); | |
659 // Kill |thread|. | |
660 thread = nullptr; | |
661 // Try calling functor. | |
662 EXPECT_FALSE( | |
663 invoker->AsyncInvoke(RTC_FROM_HERE, RTC_FROM_HERE, FunctorC(), | |
664 &GuardedAsyncInvokeTest::IntCallback, | |
665 static_cast<GuardedAsyncInvokeTest*>(this))); | |
666 // With thread gone, callback should be cancelled. | |
667 Thread::Current()->ProcessMessages(kWaitTimeout); | |
668 EXPECT_EQ(0, int_value_); | |
669 } | |
670 | |
671 // The remaining tests check that GuardedAsyncInvoker behaves as AsyncInvoker | 568 // The remaining tests check that GuardedAsyncInvoker behaves as AsyncInvoker |
672 // when Thread is still alive. | 569 // when Thread is still alive. |
673 TEST_F(GuardedAsyncInvokeTest, FireAndForget) { | 570 TEST_F(GuardedAsyncInvokeTest, FireAndForget) { |
674 GuardedAsyncInvoker invoker; | 571 GuardedAsyncInvoker invoker; |
675 // Try calling functor. | 572 // Try calling functor. |
676 AtomicBool called; | 573 AtomicBool called; |
677 EXPECT_TRUE(invoker.AsyncInvoke<void>(RTC_FROM_HERE, FunctorB(&called))); | 574 EXPECT_TRUE(invoker.AsyncInvoke<void>(RTC_FROM_HERE, FunctorB(&called))); |
678 EXPECT_TRUE_WAIT(called.get(), kWaitTimeout); | 575 EXPECT_TRUE_WAIT(called.get(), kWaitTimeout); |
679 } | 576 } |
680 | 577 |
681 TEST_F(GuardedAsyncInvokeTest, WithCallback) { | |
682 GuardedAsyncInvoker invoker; | |
683 // Try calling functor. | |
684 SetExpectedThreadForIntCallback(Thread::Current()); | |
685 EXPECT_TRUE(invoker.AsyncInvoke(RTC_FROM_HERE, RTC_FROM_HERE, FunctorA(), | |
686 &GuardedAsyncInvokeTest::IntCallback, | |
687 static_cast<GuardedAsyncInvokeTest*>(this))); | |
688 EXPECT_EQ_WAIT(42, int_value_, kWaitTimeout); | |
689 } | |
690 | |
691 TEST_F(GuardedAsyncInvokeTest, CancelInvoker) { | |
692 // Try destroying invoker during call. | |
693 { | |
694 GuardedAsyncInvoker invoker; | |
695 EXPECT_TRUE( | |
696 invoker.AsyncInvoke(RTC_FROM_HERE, RTC_FROM_HERE, FunctorC(), | |
697 &GuardedAsyncInvokeTest::IntCallback, | |
698 static_cast<GuardedAsyncInvokeTest*>(this))); | |
699 } | |
700 // With invoker gone, callback should be cancelled. | |
701 Thread::Current()->ProcessMessages(kWaitTimeout); | |
702 EXPECT_EQ(0, int_value_); | |
703 } | |
704 | |
705 TEST_F(GuardedAsyncInvokeTest, CancelCallingThread) { | |
706 GuardedAsyncInvoker invoker; | |
707 // Try destroying calling thread during call. | |
708 { | |
709 Thread thread; | |
710 thread.Start(); | |
711 // Try calling functor. | |
712 thread.Invoke<void>(RTC_FROM_HERE, | |
713 Bind(&GuardedAsyncInvokeTest::AsyncInvokeIntCallback, | |
714 static_cast<GuardedAsyncInvokeTest*>(this), | |
715 &invoker, Thread::Current())); | |
716 // Wait for the call to begin. | |
717 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); | |
718 } | |
719 // Calling thread is gone. Return message shouldn't happen. | |
720 Thread::Current()->ProcessMessages(kWaitTimeout); | |
721 EXPECT_EQ(0, int_value_); | |
722 } | |
723 | |
724 TEST_F(GuardedAsyncInvokeTest, KillInvokerBeforeExecute) { | |
725 Thread thread; | |
726 thread.Start(); | |
727 { | |
728 GuardedAsyncInvoker invoker; | |
729 // Try calling functor. | |
730 thread.Invoke<void>(RTC_FROM_HERE, | |
731 Bind(&GuardedAsyncInvokeTest::AsyncInvokeIntCallback, | |
732 static_cast<GuardedAsyncInvokeTest*>(this), | |
733 &invoker, Thread::Current())); | |
734 // Wait for the call to begin. | |
735 ASSERT_TRUE(invoke_started_.Wait(kWaitTimeout)); | |
736 } | |
737 // Invoker is destroyed. Function should not execute. | |
738 Thread::Current()->ProcessMessages(kWaitTimeout); | |
739 EXPECT_EQ(0, int_value_); | |
740 } | |
741 | |
742 TEST_F(GuardedAsyncInvokeTest, Flush) { | 578 TEST_F(GuardedAsyncInvokeTest, Flush) { |
743 GuardedAsyncInvoker invoker; | 579 GuardedAsyncInvoker invoker; |
744 AtomicBool flag1; | 580 AtomicBool flag1; |
745 AtomicBool flag2; | 581 AtomicBool flag2; |
746 // Queue two async calls to the current thread. | 582 // Queue two async calls to the current thread. |
747 EXPECT_TRUE(invoker.AsyncInvoke<void>(RTC_FROM_HERE, FunctorB(&flag1))); | 583 EXPECT_TRUE(invoker.AsyncInvoke<void>(RTC_FROM_HERE, FunctorB(&flag1))); |
748 EXPECT_TRUE(invoker.AsyncInvoke<void>(RTC_FROM_HERE, FunctorB(&flag2))); | 584 EXPECT_TRUE(invoker.AsyncInvoke<void>(RTC_FROM_HERE, FunctorB(&flag2))); |
749 // Because we haven't pumped messages, these should not have run yet. | 585 // Because we haven't pumped messages, these should not have run yet. |
750 EXPECT_FALSE(flag1.get()); | 586 EXPECT_FALSE(flag1.get()); |
751 EXPECT_FALSE(flag2.get()); | 587 EXPECT_FALSE(flag2.get()); |
(...skipping 16 matching lines...) Expand all Loading... | |
768 // Execute pending calls with id == 5. | 604 // Execute pending calls with id == 5. |
769 EXPECT_TRUE(invoker.Flush(5)); | 605 EXPECT_TRUE(invoker.Flush(5)); |
770 EXPECT_TRUE(flag1.get()); | 606 EXPECT_TRUE(flag1.get()); |
771 EXPECT_FALSE(flag2.get()); | 607 EXPECT_FALSE(flag2.get()); |
772 flag1 = false; | 608 flag1 = false; |
773 // Execute all pending calls. The id == 5 call should not execute again. | 609 // Execute all pending calls. The id == 5 call should not execute again. |
774 EXPECT_TRUE(invoker.Flush()); | 610 EXPECT_TRUE(invoker.Flush()); |
775 EXPECT_FALSE(flag1.get()); | 611 EXPECT_FALSE(flag1.get()); |
776 EXPECT_TRUE(flag2.get()); | 612 EXPECT_TRUE(flag2.get()); |
777 } | 613 } |
OLD | NEW |