1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "media/base/bind_to_current_loop.h" 6 7 #include "base/message_loop/message_loop.h" 8 #include "base/synchronization/waitable_event.h" 9 #include "testing/gtest/include/gtest/gtest.h" 10 11 namespace media { 12 13 void BoundBoolSet(bool* var, bool val) { 14 *var = val; 15 } 16 17 void BoundBoolSetFromScopedPtr(bool* var, scoped_ptr<bool> val) { 18 *var = *val; 19 } 20 21 void BoundBoolSetFromScopedPtrFreeDeleter( 22 bool* var, 23 scoped_ptr<bool, base::FreeDeleter> val) { 24 *var = val; 25 } 26 27 void BoundBoolSetFromScopedArray(bool* var, scoped_ptr<bool[]> val) { 28 *var = val[0]; 29 } 30 31 void BoundBoolSetFromConstRef(bool* var, const bool& val) { 32 *var = val; 33 } 34 35 void BoundIntegersSet(int* a_var, int* b_var, int a_val, int b_val) { 36 *a_var = a_val; 37 *b_var = b_val; 38 } 39 40 // Various tests that check that the bound function is only actually executed 41 // on the message loop, not during the original Run. 42 class BindToCurrentLoopTest : public ::testing::Test { 43 protected: 44 base::MessageLoop loop_; 45 }; 46 47 TEST_F(BindToCurrentLoopTest, Closure) { 48 // Test the closure is run inside the loop, not outside it. 49 base::WaitableEvent waiter(false, false); 50 base::Closure cb = BindToCurrentLoop(base::Bind( 51 &base::WaitableEvent::Signal, base::Unretained(&waiter))); 52 cb.Run(); 53 EXPECT_FALSE(waiter.IsSignaled()); 54 loop_.RunUntilIdle(); 55 EXPECT_TRUE(waiter.IsSignaled()); 56 } 57 58 TEST_F(BindToCurrentLoopTest, Bool) { 59 bool bool_var = false; 60 base::Callback<void(bool)> cb = BindToCurrentLoop(base::Bind( 61 &BoundBoolSet, &bool_var)); 62 cb.Run(true); 63 EXPECT_FALSE(bool_var); 64 loop_.RunUntilIdle(); 65 EXPECT_TRUE(bool_var); 66 } 67 68 TEST_F(BindToCurrentLoopTest, BoundScopedPtrBool) { 69 bool bool_val = false; 70 scoped_ptr<bool> scoped_ptr_bool(new bool(true)); 71 base::Closure cb = BindToCurrentLoop(base::Bind( 72 &BoundBoolSetFromScopedPtr, &bool_val, base::Passed(&scoped_ptr_bool))); 73 cb.Run(); 74 EXPECT_FALSE(bool_val); 75 loop_.RunUntilIdle(); 76 EXPECT_TRUE(bool_val); 77 } 78 79 TEST_F(BindToCurrentLoopTest, PassedScopedPtrBool) { 80 bool bool_val = false; 81 scoped_ptr<bool> scoped_ptr_bool(new bool(true)); 82 base::Callback<void(scoped_ptr<bool>)> cb = BindToCurrentLoop(base::Bind( 83 &BoundBoolSetFromScopedPtr, &bool_val)); 84 cb.Run(scoped_ptr_bool.Pass()); 85 EXPECT_FALSE(bool_val); 86 loop_.RunUntilIdle(); 87 EXPECT_TRUE(bool_val); 88 } 89 90 TEST_F(BindToCurrentLoopTest, BoundScopedArrayBool) { 91 bool bool_val = false; 92 scoped_ptr<bool[]> scoped_array_bool(new bool[1]); 93 scoped_array_bool[0] = true; 94 base::Closure cb = BindToCurrentLoop(base::Bind( 95 &BoundBoolSetFromScopedArray, &bool_val, 96 base::Passed(&scoped_array_bool))); 97 cb.Run(); 98 EXPECT_FALSE(bool_val); 99 loop_.RunUntilIdle(); 100 EXPECT_TRUE(bool_val); 101 } 102 103 TEST_F(BindToCurrentLoopTest, PassedScopedArrayBool) { 104 bool bool_val = false; 105 scoped_ptr<bool[]> scoped_array_bool(new bool[1]); 106 scoped_array_bool[0] = true; 107 base::Callback<void(scoped_ptr<bool[]>)> cb = BindToCurrentLoop(base::Bind( 108 &BoundBoolSetFromScopedArray, &bool_val)); 109 cb.Run(scoped_array_bool.Pass()); 110 EXPECT_FALSE(bool_val); 111 loop_.RunUntilIdle(); 112 EXPECT_TRUE(bool_val); 113 } 114 115 TEST_F(BindToCurrentLoopTest, BoundScopedPtrFreeDeleterBool) { 116 bool bool_val = false; 117 scoped_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool( 118 static_cast<bool*>(malloc(sizeof(bool)))); 119 *scoped_ptr_free_deleter_bool = true; 120 base::Closure cb = BindToCurrentLoop(base::Bind( 121 &BoundBoolSetFromScopedPtrFreeDeleter, &bool_val, 122 base::Passed(&scoped_ptr_free_deleter_bool))); 123 cb.Run(); 124 EXPECT_FALSE(bool_val); 125 loop_.RunUntilIdle(); 126 EXPECT_TRUE(bool_val); 127 } 128 129 TEST_F(BindToCurrentLoopTest, PassedScopedPtrFreeDeleterBool) { 130 bool bool_val = false; 131 scoped_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool( 132 static_cast<bool*>(malloc(sizeof(bool)))); 133 *scoped_ptr_free_deleter_bool = true; 134 base::Callback<void(scoped_ptr<bool, base::FreeDeleter>)> cb = 135 BindToCurrentLoop(base::Bind(&BoundBoolSetFromScopedPtrFreeDeleter, 136 &bool_val)); 137 cb.Run(scoped_ptr_free_deleter_bool.Pass()); 138 EXPECT_FALSE(bool_val); 139 loop_.RunUntilIdle(); 140 EXPECT_TRUE(bool_val); 141 } 142 143 TEST_F(BindToCurrentLoopTest, BoolConstRef) { 144 bool bool_var = false; 145 bool true_var = true; 146 const bool& true_ref = true_var; 147 base::Closure cb = BindToCurrentLoop(base::Bind( 148 &BoundBoolSetFromConstRef, &bool_var, true_ref)); 149 cb.Run(); 150 EXPECT_FALSE(bool_var); 151 loop_.RunUntilIdle(); 152 EXPECT_TRUE(bool_var); 153 } 154 155 TEST_F(BindToCurrentLoopTest, Integers) { 156 int a = 0; 157 int b = 0; 158 base::Callback<void(int, int)> cb = BindToCurrentLoop(base::Bind( 159 &BoundIntegersSet, &a, &b)); 160 cb.Run(1, -1); 161 EXPECT_EQ(a, 0); 162 EXPECT_EQ(b, 0); 163 loop_.RunUntilIdle(); 164 EXPECT_EQ(a, 1); 165 EXPECT_EQ(b, -1); 166 } 167 168 } // namespace media 169