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 11namespace media { 12 13void BoundBoolSet(bool* var, bool val) { 14 *var = val; 15} 16 17void BoundBoolSetFromScopedPtr(bool* var, scoped_ptr<bool> val) { 18 *var = *val; 19} 20 21void BoundBoolSetFromScopedPtrFreeDeleter( 22 bool* var, 23 scoped_ptr<bool, base::FreeDeleter> val) { 24 *var = val; 25} 26 27void BoundBoolSetFromScopedArray(bool* var, scoped_ptr<bool[]> val) { 28 *var = val[0]; 29} 30 31void BoundBoolSetFromConstRef(bool* var, const bool& val) { 32 *var = val; 33} 34 35void 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. 42class BindToCurrentLoopTest : public ::testing::Test { 43 protected: 44 base::MessageLoop loop_; 45}; 46 47TEST_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 58TEST_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 68TEST_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 79TEST_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 90TEST_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 103TEST_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 115TEST_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 129TEST_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 143TEST_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 155TEST_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