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_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 BoundBoolSetFromScopedPtrMalloc(bool* var, scoped_ptr_malloc<bool> val) { 22 *var = val; 23 } 24 25 void BoundBoolSetFromScopedArray(bool* var, scoped_ptr<bool[]> val) { 26 *var = val[0]; 27 } 28 29 void BoundBoolSetFromConstRef(bool* var, const bool& val) { 30 *var = val; 31 } 32 33 void BoundIntegersSet(int* a_var, int* b_var, int a_val, int b_val) { 34 *a_var = a_val; 35 *b_var = b_val; 36 } 37 38 // Various tests that check that the bound function is only actually executed 39 // on the message loop, not during the original Run. 40 class BindToLoopTest : public ::testing::Test { 41 public: 42 BindToLoopTest() : proxy_(loop_.message_loop_proxy()) {} 43 44 protected: 45 base::MessageLoop loop_; 46 scoped_refptr<base::MessageLoopProxy> proxy_; 47 }; 48 49 TEST_F(BindToLoopTest, Closure) { 50 // Test the closure is run inside the loop, not outside it. 51 base::WaitableEvent waiter(false, false); 52 base::Closure cb = BindToLoop(proxy_, base::Bind( 53 &base::WaitableEvent::Signal, base::Unretained(&waiter))); 54 cb.Run(); 55 EXPECT_FALSE(waiter.IsSignaled()); 56 loop_.RunUntilIdle(); 57 EXPECT_TRUE(waiter.IsSignaled()); 58 } 59 60 TEST_F(BindToLoopTest, Bool) { 61 bool bool_var = false; 62 base::Callback<void(bool)> cb = BindToLoop(proxy_, base::Bind( 63 &BoundBoolSet, &bool_var)); 64 cb.Run(true); 65 EXPECT_FALSE(bool_var); 66 loop_.RunUntilIdle(); 67 EXPECT_TRUE(bool_var); 68 } 69 70 TEST_F(BindToLoopTest, BoundScopedPtrBool) { 71 bool bool_val = false; 72 scoped_ptr<bool> scoped_ptr_bool(new bool(true)); 73 base::Closure cb = BindToLoop(proxy_, base::Bind( 74 &BoundBoolSetFromScopedPtr, &bool_val, base::Passed(&scoped_ptr_bool))); 75 cb.Run(); 76 EXPECT_FALSE(bool_val); 77 loop_.RunUntilIdle(); 78 EXPECT_TRUE(bool_val); 79 } 80 81 TEST_F(BindToLoopTest, PassedScopedPtrBool) { 82 bool bool_val = false; 83 scoped_ptr<bool> scoped_ptr_bool(new bool(true)); 84 base::Callback<void(scoped_ptr<bool>)> cb = BindToLoop(proxy_, base::Bind( 85 &BoundBoolSetFromScopedPtr, &bool_val)); 86 cb.Run(scoped_ptr_bool.Pass()); 87 EXPECT_FALSE(bool_val); 88 loop_.RunUntilIdle(); 89 EXPECT_TRUE(bool_val); 90 } 91 92 TEST_F(BindToLoopTest, BoundScopedArrayBool) { 93 bool bool_val = false; 94 scoped_ptr<bool[]> scoped_array_bool(new bool[1]); 95 scoped_array_bool[0] = true; 96 base::Closure cb = BindToLoop(proxy_, base::Bind( 97 &BoundBoolSetFromScopedArray, &bool_val, 98 base::Passed(&scoped_array_bool))); 99 cb.Run(); 100 EXPECT_FALSE(bool_val); 101 loop_.RunUntilIdle(); 102 EXPECT_TRUE(bool_val); 103 } 104 105 TEST_F(BindToLoopTest, PassedScopedArrayBool) { 106 bool bool_val = false; 107 scoped_ptr<bool[]> scoped_array_bool(new bool[1]); 108 scoped_array_bool[0] = true; 109 base::Callback<void(scoped_ptr<bool[]>)> cb = BindToLoop(proxy_, base::Bind( 110 &BoundBoolSetFromScopedArray, &bool_val)); 111 cb.Run(scoped_array_bool.Pass()); 112 EXPECT_FALSE(bool_val); 113 loop_.RunUntilIdle(); 114 EXPECT_TRUE(bool_val); 115 } 116 117 TEST_F(BindToLoopTest, BoundScopedPtrMallocBool) { 118 bool bool_val = false; 119 scoped_ptr_malloc<bool> scoped_ptr_malloc_bool( 120 static_cast<bool*>(malloc(sizeof(bool)))); 121 *scoped_ptr_malloc_bool = true; 122 base::Closure cb = BindToLoop(proxy_, base::Bind( 123 &BoundBoolSetFromScopedPtrMalloc, &bool_val, 124 base::Passed(&scoped_ptr_malloc_bool))); 125 cb.Run(); 126 EXPECT_FALSE(bool_val); 127 loop_.RunUntilIdle(); 128 EXPECT_TRUE(bool_val); 129 } 130 131 TEST_F(BindToLoopTest, PassedScopedPtrMallocBool) { 132 bool bool_val = false; 133 scoped_ptr_malloc<bool> scoped_ptr_malloc_bool( 134 static_cast<bool*>(malloc(sizeof(bool)))); 135 *scoped_ptr_malloc_bool = true; 136 base::Callback<void(scoped_ptr_malloc<bool>)> cb = BindToLoop( 137 proxy_, base::Bind(&BoundBoolSetFromScopedPtrMalloc, &bool_val)); 138 cb.Run(scoped_ptr_malloc_bool.Pass()); 139 EXPECT_FALSE(bool_val); 140 loop_.RunUntilIdle(); 141 EXPECT_TRUE(bool_val); 142 } 143 144 TEST_F(BindToLoopTest, BoolConstRef) { 145 bool bool_var = false; 146 bool true_var = true; 147 const bool& true_ref = true_var; 148 base::Closure cb = BindToLoop(proxy_, base::Bind( 149 &BoundBoolSetFromConstRef, &bool_var, true_ref)); 150 cb.Run(); 151 EXPECT_FALSE(bool_var); 152 loop_.RunUntilIdle(); 153 EXPECT_TRUE(bool_var); 154 } 155 156 TEST_F(BindToLoopTest, Integers) { 157 int a = 0; 158 int b = 0; 159 base::Callback<void(int, int)> cb = BindToLoop(proxy_, base::Bind( 160 &BoundIntegersSet, &a, &b)); 161 cb.Run(1, -1); 162 EXPECT_EQ(a, 0); 163 EXPECT_EQ(b, 0); 164 loop_.RunUntilIdle(); 165 EXPECT_EQ(a, 1); 166 EXPECT_EQ(b, -1); 167 } 168 169 } // namespace media 170