| Index: media/base/bind_to_current_loop_unittest.cc
|
| diff --git a/media/base/bind_to_current_loop_unittest.cc b/media/base/bind_to_current_loop_unittest.cc
|
| index b0f5cdef436f875d94230bceb99f60b5e8b9a6ef..6d0a1a40524dcf0c8a41ae9eb07de69ff72afb4c 100644
|
| --- a/media/base/bind_to_current_loop_unittest.cc
|
| +++ b/media/base/bind_to_current_loop_unittest.cc
|
| @@ -20,17 +20,17 @@ void BoundBoolSet(bool* var, bool val) {
|
| *var = val;
|
| }
|
|
|
| -void BoundBoolSetFromScopedPtr(bool* var, std::unique_ptr<bool> val) {
|
| +void BoundBoolSetFromUniquePtr(bool* var, std::unique_ptr<bool> val) {
|
| *var = *val;
|
| }
|
|
|
| -void BoundBoolSetFromScopedPtrFreeDeleter(
|
| +void BoundBoolSetFromUniquePtrFreeDeleter(
|
| bool* var,
|
| std::unique_ptr<bool, base::FreeDeleter> val) {
|
| *var = *val;
|
| }
|
|
|
| -void BoundBoolSetFromScopedArray(bool* var, std::unique_ptr<bool[]> val) {
|
| +void BoundBoolSetFromUniquePtrArray(bool* var, std::unique_ptr<bool[]> val) {
|
| *var = val[0];
|
| }
|
|
|
| @@ -55,11 +55,7 @@ struct ThreadRestrictionChecker {
|
| base::MessageLoop* bound_loop_;
|
| };
|
|
|
| -void RunAndClearReference(base::Closure cb) {
|
| - cb.Run();
|
| -}
|
| -
|
| -void ClearReference(base::Closure cb) {}
|
| +void ClearReference(base::OnceClosure cb) {}
|
|
|
| // Various tests that check that the bound function is only actually executed
|
| // on the message loop, not during the original Run.
|
| @@ -68,11 +64,11 @@ class BindToCurrentLoopTest : public ::testing::Test {
|
| base::MessageLoop loop_;
|
| };
|
|
|
| -TEST_F(BindToCurrentLoopTest, Closure) {
|
| +TEST_F(BindToCurrentLoopTest, RepeatingClosure) {
|
| // Test the closure is run inside the loop, not outside it.
|
| base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
| base::WaitableEvent::InitialState::NOT_SIGNALED);
|
| - base::Closure cb = BindToCurrentLoop(base::Bind(
|
| + base::RepeatingClosure cb = BindToCurrentLoop(base::BindRepeating(
|
| &base::WaitableEvent::Signal, base::Unretained(&waiter)));
|
| cb.Run();
|
| EXPECT_FALSE(waiter.IsSignaled());
|
| @@ -80,130 +76,285 @@ TEST_F(BindToCurrentLoopTest, Closure) {
|
| EXPECT_TRUE(waiter.IsSignaled());
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, Bool) {
|
| +TEST_F(BindToCurrentLoopTest, OnceClosure) {
|
| + // Test the closure is run inside the loop, not outside it.
|
| + base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC,
|
| + base::WaitableEvent::InitialState::NOT_SIGNALED);
|
| + base::OnceClosure cb = BindToCurrentLoop(
|
| + base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&waiter)));
|
| + std::move(cb).Run();
|
| + EXPECT_FALSE(waiter.IsSignaled());
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(waiter.IsSignaled());
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, BoolRepeating) {
|
| bool bool_var = false;
|
| - base::Callback<void(bool)> cb = BindToCurrentLoop(base::Bind(
|
| - &BoundBoolSet, &bool_var));
|
| + base::RepeatingCallback<void(bool)> cb =
|
| + BindToCurrentLoop(base::BindRepeating(&BoundBoolSet, &bool_var));
|
| cb.Run(true);
|
| EXPECT_FALSE(bool_var);
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_TRUE(bool_var);
|
| +
|
| + cb.Run(false);
|
| + EXPECT_TRUE(bool_var);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_FALSE(bool_var);
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, BoolOnce) {
|
| + bool bool_var = false;
|
| + base::OnceCallback<void(bool)> cb =
|
| + BindToCurrentLoop(base::BindOnce(&BoundBoolSet, &bool_var));
|
| + std::move(cb).Run(true);
|
| + EXPECT_FALSE(bool_var);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(bool_var);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, BoundScopedPtrBool) {
|
| +TEST_F(BindToCurrentLoopTest, BoundUniquePtrBoolRepeating) {
|
| bool bool_val = false;
|
| - std::unique_ptr<bool> scoped_ptr_bool(new bool(true));
|
| - base::Closure cb = BindToCurrentLoop(base::Bind(
|
| - &BoundBoolSetFromScopedPtr, &bool_val, base::Passed(&scoped_ptr_bool)));
|
| + std::unique_ptr<bool> unique_ptr_bool(new bool(true));
|
| + base::RepeatingClosure cb = BindToCurrentLoop(base::BindRepeating(
|
| + &BoundBoolSetFromUniquePtr, &bool_val, base::Passed(&unique_ptr_bool)));
|
| cb.Run();
|
| EXPECT_FALSE(bool_val);
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_TRUE(bool_val);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, PassedScopedPtrBool) {
|
| +TEST_F(BindToCurrentLoopTest, BoundUniquePtrBoolOnce) {
|
| bool bool_val = false;
|
| - std::unique_ptr<bool> scoped_ptr_bool(new bool(true));
|
| - base::Callback<void(std::unique_ptr<bool>)> cb =
|
| - BindToCurrentLoop(base::Bind(&BoundBoolSetFromScopedPtr, &bool_val));
|
| - cb.Run(std::move(scoped_ptr_bool));
|
| + std::unique_ptr<bool> unique_ptr_bool(new bool(true));
|
| + base::OnceClosure cb = BindToCurrentLoop(base::BindOnce(
|
| + &BoundBoolSetFromUniquePtr, &bool_val, std::move(unique_ptr_bool)));
|
| + std::move(cb).Run();
|
| EXPECT_FALSE(bool_val);
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_TRUE(bool_val);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, BoundScopedArrayBool) {
|
| +TEST_F(BindToCurrentLoopTest, PassedUniquePtrBoolRepeating) {
|
| bool bool_val = false;
|
| - std::unique_ptr<bool[]> scoped_array_bool(new bool[1]);
|
| - scoped_array_bool[0] = true;
|
| - base::Closure cb = BindToCurrentLoop(base::Bind(
|
| - &BoundBoolSetFromScopedArray, &bool_val,
|
| - base::Passed(&scoped_array_bool)));
|
| + base::RepeatingCallback<void(std::unique_ptr<bool>)> cb = BindToCurrentLoop(
|
| + base::BindRepeating(&BoundBoolSetFromUniquePtr, &bool_val));
|
| + cb.Run(base::MakeUnique<bool>(true));
|
| + EXPECT_FALSE(bool_val);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(bool_val);
|
| +
|
| + cb.Run(base::MakeUnique<bool>(false));
|
| + EXPECT_TRUE(bool_val);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_FALSE(bool_val);
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, PassedUniquePtrBoolOnce) {
|
| + bool bool_val = false;
|
| + base::OnceCallback<void(std::unique_ptr<bool>)> cb =
|
| + BindToCurrentLoop(base::BindOnce(&BoundBoolSetFromUniquePtr, &bool_val));
|
| + std::move(cb).Run(base::MakeUnique<bool>(true));
|
| + EXPECT_FALSE(bool_val);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(bool_val);
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, BoundUniquePtrArrayBoolRepeating) {
|
| + bool bool_val = false;
|
| + std::unique_ptr<bool[]> unique_ptr_array_bool(new bool[1]);
|
| + unique_ptr_array_bool[0] = true;
|
| + base::RepeatingClosure cb = BindToCurrentLoop(
|
| + base::BindRepeating(&BoundBoolSetFromUniquePtrArray, &bool_val,
|
| + base::Passed(&unique_ptr_array_bool)));
|
| cb.Run();
|
| EXPECT_FALSE(bool_val);
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_TRUE(bool_val);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, PassedScopedArrayBool) {
|
| +TEST_F(BindToCurrentLoopTest, BoundUniquePtrArrayBoolOnce) {
|
| bool bool_val = false;
|
| - std::unique_ptr<bool[]> scoped_array_bool(new bool[1]);
|
| - scoped_array_bool[0] = true;
|
| - base::Callback<void(std::unique_ptr<bool[]>)> cb =
|
| - BindToCurrentLoop(base::Bind(&BoundBoolSetFromScopedArray, &bool_val));
|
| - cb.Run(std::move(scoped_array_bool));
|
| + std::unique_ptr<bool[]> unique_ptr_array_bool(new bool[1]);
|
| + unique_ptr_array_bool[0] = true;
|
| + base::OnceClosure cb = BindToCurrentLoop(
|
| + base::BindOnce(&BoundBoolSetFromUniquePtrArray, &bool_val,
|
| + std::move(unique_ptr_array_bool)));
|
| + std::move(cb).Run();
|
| + EXPECT_FALSE(bool_val);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(bool_val);
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, PassedUniquePtrArrayBoolRepeating) {
|
| + bool bool_val = false;
|
| + base::RepeatingCallback<void(std::unique_ptr<bool[]>)> cb = BindToCurrentLoop(
|
| + base::BindRepeating(&BoundBoolSetFromUniquePtrArray, &bool_val));
|
| +
|
| + std::unique_ptr<bool[]> unique_ptr_array_bool(new bool[1]);
|
| + unique_ptr_array_bool[0] = true;
|
| + cb.Run(std::move(unique_ptr_array_bool));
|
| + EXPECT_FALSE(bool_val);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(bool_val);
|
| +
|
| + unique_ptr_array_bool.reset(new bool[1]);
|
| + unique_ptr_array_bool[0] = false;
|
| + cb.Run(std::move(unique_ptr_array_bool));
|
| + EXPECT_TRUE(bool_val);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_FALSE(bool_val);
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, PassedUniquePtrArrayBoolOnce) {
|
| + bool bool_val = false;
|
| + base::OnceCallback<void(std::unique_ptr<bool[]>)> cb = BindToCurrentLoop(
|
| + base::BindOnce(&BoundBoolSetFromUniquePtrArray, &bool_val));
|
| +
|
| + std::unique_ptr<bool[]> unique_ptr_array_bool(new bool[1]);
|
| + unique_ptr_array_bool[0] = true;
|
| + std::move(cb).Run(std::move(unique_ptr_array_bool));
|
| EXPECT_FALSE(bool_val);
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_TRUE(bool_val);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, BoundScopedPtrFreeDeleterBool) {
|
| +TEST_F(BindToCurrentLoopTest, BoundUniquePtrFreeDeleterBoolRepeating) {
|
| bool bool_val = false;
|
| - std::unique_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool(
|
| + std::unique_ptr<bool, base::FreeDeleter> unique_ptr_free_deleter_bool(
|
| static_cast<bool*>(malloc(sizeof(bool))));
|
| - *scoped_ptr_free_deleter_bool = true;
|
| - base::Closure cb = BindToCurrentLoop(base::Bind(
|
| - &BoundBoolSetFromScopedPtrFreeDeleter, &bool_val,
|
| - base::Passed(&scoped_ptr_free_deleter_bool)));
|
| + *unique_ptr_free_deleter_bool = true;
|
| + base::RepeatingClosure cb = BindToCurrentLoop(
|
| + base::BindRepeating(&BoundBoolSetFromUniquePtrFreeDeleter, &bool_val,
|
| + base::Passed(&unique_ptr_free_deleter_bool)));
|
| cb.Run();
|
| EXPECT_FALSE(bool_val);
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_TRUE(bool_val);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, PassedScopedPtrFreeDeleterBool) {
|
| +TEST_F(BindToCurrentLoopTest, BoundUniquePtrFreeDeleterBoolOnce) {
|
| bool bool_val = false;
|
| - std::unique_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool(
|
| + std::unique_ptr<bool, base::FreeDeleter> unique_ptr_free_deleter_bool(
|
| static_cast<bool*>(malloc(sizeof(bool))));
|
| - *scoped_ptr_free_deleter_bool = true;
|
| - base::Callback<void(std::unique_ptr<bool, base::FreeDeleter>)> cb =
|
| - BindToCurrentLoop(
|
| - base::Bind(&BoundBoolSetFromScopedPtrFreeDeleter, &bool_val));
|
| - cb.Run(std::move(scoped_ptr_free_deleter_bool));
|
| + *unique_ptr_free_deleter_bool = true;
|
| + base::OnceClosure cb = BindToCurrentLoop(
|
| + base::BindOnce(&BoundBoolSetFromUniquePtrFreeDeleter, &bool_val,
|
| + std::move(unique_ptr_free_deleter_bool)));
|
| + std::move(cb).Run();
|
| EXPECT_FALSE(bool_val);
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_TRUE(bool_val);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, BoolConstRef) {
|
| - bool bool_var = false;
|
| - bool true_var = true;
|
| - const bool& true_ref = true_var;
|
| - base::Closure cb = BindToCurrentLoop(base::Bind(
|
| - &BoundBoolSetFromConstRef, &bool_var, true_ref));
|
| - cb.Run();
|
| - EXPECT_FALSE(bool_var);
|
| +TEST_F(BindToCurrentLoopTest, PassedUniquePtrFreeDeleterBoolRepeating) {
|
| + bool bool_val = false;
|
| + base::RepeatingCallback<void(std::unique_ptr<bool, base::FreeDeleter>)> cb =
|
| + BindToCurrentLoop(base::BindRepeating(
|
| + &BoundBoolSetFromUniquePtrFreeDeleter, &bool_val));
|
| +
|
| + std::unique_ptr<bool, base::FreeDeleter> unique_ptr_free_deleter_bool(
|
| + static_cast<bool*>(malloc(sizeof(bool))));
|
| + *unique_ptr_free_deleter_bool = true;
|
| + cb.Run(std::move(unique_ptr_free_deleter_bool));
|
| + EXPECT_FALSE(bool_val);
|
| base::RunLoop().RunUntilIdle();
|
| - EXPECT_TRUE(bool_var);
|
| + EXPECT_TRUE(bool_val);
|
| +
|
| + unique_ptr_free_deleter_bool.reset(static_cast<bool*>(malloc(sizeof(bool))));
|
| + *unique_ptr_free_deleter_bool = false;
|
| + cb.Run(std::move(unique_ptr_free_deleter_bool));
|
| + EXPECT_TRUE(bool_val);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_FALSE(bool_val);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, Integers) {
|
| +TEST_F(BindToCurrentLoopTest, PassedUniquePtrFreeDeleterBoolOnce) {
|
| + bool bool_val = false;
|
| + base::OnceCallback<void(std::unique_ptr<bool, base::FreeDeleter>)> cb =
|
| + BindToCurrentLoop(
|
| + base::BindOnce(&BoundBoolSetFromUniquePtrFreeDeleter, &bool_val));
|
| +
|
| + std::unique_ptr<bool, base::FreeDeleter> unique_ptr_free_deleter_bool(
|
| + static_cast<bool*>(malloc(sizeof(bool))));
|
| + *unique_ptr_free_deleter_bool = true;
|
| + std::move(cb).Run(std::move(unique_ptr_free_deleter_bool));
|
| + EXPECT_FALSE(bool_val);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_TRUE(bool_val);
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, IntegersRepeating) {
|
| int a = 0;
|
| int b = 0;
|
| - base::Callback<void(int, int)> cb = BindToCurrentLoop(base::Bind(
|
| - &BoundIntegersSet, &a, &b));
|
| + base::RepeatingCallback<void(int, int)> cb =
|
| + BindToCurrentLoop(base::BindRepeating(&BoundIntegersSet, &a, &b));
|
| cb.Run(1, -1);
|
| EXPECT_EQ(a, 0);
|
| EXPECT_EQ(b, 0);
|
| base::RunLoop().RunUntilIdle();
|
| EXPECT_EQ(a, 1);
|
| EXPECT_EQ(b, -1);
|
| +
|
| + cb.Run(2, -2);
|
| + EXPECT_EQ(a, 1);
|
| + EXPECT_EQ(b, -1);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(a, 2);
|
| + EXPECT_EQ(b, -2);
|
| }
|
|
|
| -TEST_F(BindToCurrentLoopTest, DestroyedOnBoundLoop) {
|
| +TEST_F(BindToCurrentLoopTest, IntegersOnce) {
|
| + int a = 0;
|
| + int b = 0;
|
| + base::OnceCallback<void(int, int)> cb =
|
| + BindToCurrentLoop(base::BindOnce(&BoundIntegersSet, &a, &b));
|
| + std::move(cb).Run(1, -1);
|
| + EXPECT_EQ(a, 0);
|
| + EXPECT_EQ(b, 0);
|
| + base::RunLoop().RunUntilIdle();
|
| + EXPECT_EQ(a, 1);
|
| + EXPECT_EQ(b, -1);
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, DestroyedOnBoundLoopRepeating) {
|
| base::Thread target_thread("testing");
|
| ASSERT_TRUE(target_thread.Start());
|
|
|
| // Ensure that the bound object is also destroyed on the correct thread even
|
| // if the last reference to the callback is dropped on the other thread.
|
| - // TODO(tzik): Remove RunAndClearReference once TaskRunner migrates to
|
| - // OnceClosure. RunAndCleareReference is needed to ensure no reference to |cb|
|
| - // is left to the original thread.
|
| - base::Closure cb = BindToCurrentLoop(
|
| - base::Bind(&ThreadRestrictionChecker::Run,
|
| - base::MakeUnique<ThreadRestrictionChecker>()));
|
| + base::RepeatingClosure cb = BindToCurrentLoop(
|
| + base::BindRepeating(&ThreadRestrictionChecker::Run,
|
| + base::MakeUnique<ThreadRestrictionChecker>()));
|
| + target_thread.task_runner()->PostTask(FROM_HERE, std::move(cb));
|
| + ASSERT_FALSE(cb);
|
| + target_thread.FlushForTesting();
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Ensure that the bound object is destroyed on the target thread even if
|
| + // the callback is destroyed without invocation.
|
| + cb = BindToCurrentLoop(
|
| + base::BindRepeating(&ThreadRestrictionChecker::Run,
|
| + base::MakeUnique<ThreadRestrictionChecker>()));
|
| target_thread.task_runner()->PostTask(
|
| - FROM_HERE, base::Bind(&RunAndClearReference, base::Passed(&cb)));
|
| + FROM_HERE, base::BindOnce(&ClearReference, std::move(cb)));
|
| + target_thread.FlushForTesting();
|
| + ASSERT_FALSE(cb);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + target_thread.Stop();
|
| +}
|
| +
|
| +TEST_F(BindToCurrentLoopTest, DestroyedOnBoundLoopOnce) {
|
| + base::Thread target_thread("testing");
|
| + ASSERT_TRUE(target_thread.Start());
|
| +
|
| + // Ensure that the bound object is also destroyed on the correct thread even
|
| + // if the last reference to the callback is dropped on the other thread.
|
| + base::OnceClosure cb = BindToCurrentLoop(
|
| + base::BindOnce(&ThreadRestrictionChecker::Run,
|
| + base::MakeUnique<ThreadRestrictionChecker>()));
|
| + target_thread.task_runner()->PostTask(FROM_HERE, std::move(cb));
|
| ASSERT_FALSE(cb);
|
| target_thread.FlushForTesting();
|
| base::RunLoop().RunUntilIdle();
|
| @@ -211,10 +362,10 @@ TEST_F(BindToCurrentLoopTest, DestroyedOnBoundLoop) {
|
| // Ensure that the bound object is destroyed on the target thread even if
|
| // the callback is destroyed without invocation.
|
| cb = BindToCurrentLoop(
|
| - base::Bind(&ThreadRestrictionChecker::Run,
|
| - base::MakeUnique<ThreadRestrictionChecker>()));
|
| + base::BindOnce(&ThreadRestrictionChecker::Run,
|
| + base::MakeUnique<ThreadRestrictionChecker>()));
|
| target_thread.task_runner()->PostTask(
|
| - FROM_HERE, base::Bind(&ClearReference, base::Passed(&cb)));
|
| + FROM_HERE, base::BindOnce(&ClearReference, std::move(cb)));
|
| target_thread.FlushForTesting();
|
| ASSERT_FALSE(cb);
|
| base::RunLoop().RunUntilIdle();
|
|
|