Chromium Code Reviews| Index: webrtc/base/thread_unittest.cc |
| diff --git a/webrtc/base/thread_unittest.cc b/webrtc/base/thread_unittest.cc |
| index b0c8cb59af952a3f7afea26702d758934987bdac..e4e74d6db00a662241c24096b52ba3daa137c499 100644 |
| --- a/webrtc/base/thread_unittest.cc |
| +++ b/webrtc/base/thread_unittest.cc |
| @@ -356,13 +356,14 @@ TEST(ThreadTest, ThreeThreadsInvoke) { |
| // Asynchronously invoke SetAndInvokeSet on |thread1| and wait until |
| // |thread1| starts the call. |
| - static void AsyncInvokeSetAndWait( |
| - Thread* thread1, Thread* thread2, LockedBool* out) { |
| + static void AsyncInvokeSetAndWait(AsyncInvoker* invoker, |
| + Thread* thread1, |
| + Thread* thread2, |
| + LockedBool* out) { |
| CriticalSection crit; |
| LockedBool async_invoked(false); |
| - AsyncInvoker invoker; |
| - invoker.AsyncInvoke<void>( |
| + invoker->AsyncInvoke<void>( |
| RTC_FROM_HERE, thread1, |
| Bind(&SetAndInvokeSet, &async_invoked, thread2, out)); |
| @@ -370,14 +371,15 @@ TEST(ThreadTest, ThreeThreadsInvoke) { |
| } |
| }; |
| + AsyncInvoker invoker; |
| LockedBool thread_a_called(false); |
| // Start the sequence A --(invoke)--> B --(async invoke)--> C --(invoke)--> A. |
| // Thread B returns when C receives the call and C should be blocked until A |
| // starts to process messages. |
| thread_b.Invoke<void>(RTC_FROM_HERE, |
| - Bind(&LocalFuncs::AsyncInvokeSetAndWait, &thread_c, |
| - thread_a, &thread_a_called)); |
| + Bind(&LocalFuncs::AsyncInvokeSetAndWait, &invoker, |
| + &thread_c, thread_a, &thread_a_called)); |
| EXPECT_FALSE(thread_a_called.Get()); |
| EXPECT_TRUE_WAIT(thread_a_called.Get(), 2000); |
| @@ -524,6 +526,41 @@ TEST_F(AsyncInvokeTest, KillInvokerBeforeExecute) { |
| EXPECT_EQ(0, int_value_); |
| } |
| +TEST_F(AsyncInvokeTest, KillInvokerDuringExecute) { |
| + // Use these events to get in a state where the functor is in the middle of |
| + // executing, and then to wait for it to finish, ensuring the "EXPECT_FALSE" |
| + // is run. |
| + Event functor_started(false, false); |
| + Event functor_continue(false, false); |
| + Event functor_finished(false, false); |
| + |
| + Thread thread; |
| + thread.Start(); |
| + volatile bool invoker_destroyed = false; |
| + { |
| + AsyncInvoker invoker; |
| + invoker.AsyncInvoke<void>(RTC_FROM_HERE, &thread, |
| + [&functor_started, &functor_continue, |
| + &functor_finished, &invoker_destroyed] { |
| + functor_started.Set(); |
| + functor_continue.Wait(Event::kForever); |
| + rtc::Thread::Current()->SleepMs(kWaitTimeout); |
| + EXPECT_FALSE(invoker_destroyed); |
| + functor_finished.Set(); |
| + }); |
| + functor_started.Wait(Event::kForever); |
| + |
| + // Allow the functor to continue and immediately destroy the invoker. |
| + functor_continue.Set(); |
| + } |
| + |
| + // If the destructor DIDN'T wait for the functor to finish executing, it will |
| + // hit the EXPECT_FALSE(invoker_destroyed) after it finishes sleeping for a |
| + // second. |
| + invoker_destroyed = true; |
| + functor_finished.Wait(Event::kForever); |
|
pthatcher1
2017/02/17 18:19:38
Nice unit test
|
| +} |
| + |
| TEST_F(AsyncInvokeTest, Flush) { |
| AsyncInvoker invoker; |
| AtomicBool flag1; |