Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(439)

Side by Side Diff: media/base/bind_to_current_loop_unittest.cc

Issue 2874003002: Update media::BindToCurrentLoop to support base::OnceCallback (Closed)
Patch Set: mod comments Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/base/bind_to_current_loop.h" 5 #include "media/base/bind_to_current_loop.h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/memory/free_deleter.h" 10 #include "base/memory/free_deleter.h"
11 #include "base/message_loop/message_loop.h" 11 #include "base/message_loop/message_loop.h"
12 #include "base/run_loop.h" 12 #include "base/run_loop.h"
13 #include "base/synchronization/waitable_event.h" 13 #include "base/synchronization/waitable_event.h"
14 #include "base/threading/thread.h" 14 #include "base/threading/thread.h"
15 #include "testing/gtest/include/gtest/gtest.h" 15 #include "testing/gtest/include/gtest/gtest.h"
16 16
17 namespace media { 17 namespace media {
18 18
19 void BoundBoolSet(bool* var, bool val) { 19 void BoundBoolSet(bool* var, bool val) {
20 *var = val; 20 *var = val;
21 } 21 }
22 22
23 void BoundBoolSetFromScopedPtr(bool* var, std::unique_ptr<bool> val) { 23 void BoundBoolSetFromUniquePtr(bool* var, std::unique_ptr<bool> val) {
24 *var = *val; 24 *var = *val;
25 } 25 }
26 26
27 void BoundBoolSetFromScopedPtrFreeDeleter( 27 void BoundBoolSetFromUniquePtrFreeDeleter(
28 bool* var, 28 bool* var,
29 std::unique_ptr<bool, base::FreeDeleter> val) { 29 std::unique_ptr<bool, base::FreeDeleter> val) {
30 *var = *val; 30 *var = *val;
31 } 31 }
32 32
33 void BoundBoolSetFromScopedArray(bool* var, std::unique_ptr<bool[]> val) { 33 void BoundBoolSetFromUniquePtrArray(bool* var, std::unique_ptr<bool[]> val) {
34 *var = val[0]; 34 *var = val[0];
35 } 35 }
36 36
37 void BoundBoolSetFromConstRef(bool* var, const bool& val) { 37 void BoundBoolSetFromConstRef(bool* var, const bool& val) {
38 *var = val; 38 *var = val;
39 } 39 }
40 40
41 void BoundIntegersSet(int* a_var, int* b_var, int a_val, int b_val) { 41 void BoundIntegersSet(int* a_var, int* b_var, int a_val, int b_val) {
42 *a_var = a_val; 42 *a_var = a_val;
43 *b_var = b_val; 43 *b_var = b_val;
44 } 44 }
45 45
46 struct ThreadRestrictionChecker { 46 struct ThreadRestrictionChecker {
47 ThreadRestrictionChecker() : bound_loop_(base::MessageLoop::current()) {} 47 ThreadRestrictionChecker() : bound_loop_(base::MessageLoop::current()) {}
48 48
49 void Run() { EXPECT_EQ(bound_loop_, base::MessageLoop::current()); } 49 void Run() { EXPECT_EQ(bound_loop_, base::MessageLoop::current()); }
50 50
51 ~ThreadRestrictionChecker() { 51 ~ThreadRestrictionChecker() {
52 EXPECT_EQ(bound_loop_, base::MessageLoop::current()); 52 EXPECT_EQ(bound_loop_, base::MessageLoop::current());
53 } 53 }
54 54
55 base::MessageLoop* bound_loop_; 55 base::MessageLoop* bound_loop_;
56 }; 56 };
57 57
58 void RunAndClearReference(base::Closure cb) { 58 void ClearReference(base::OnceClosure cb) {}
59 cb.Run();
60 }
61
62 void ClearReference(base::Closure cb) {}
63 59
64 // Various tests that check that the bound function is only actually executed 60 // Various tests that check that the bound function is only actually executed
65 // on the message loop, not during the original Run. 61 // on the message loop, not during the original Run.
66 class BindToCurrentLoopTest : public ::testing::Test { 62 class BindToCurrentLoopTest : public ::testing::Test {
67 protected: 63 protected:
68 base::MessageLoop loop_; 64 base::MessageLoop loop_;
69 }; 65 };
70 66
71 TEST_F(BindToCurrentLoopTest, Closure) { 67 TEST_F(BindToCurrentLoopTest, RepeatingClosure) {
72 // Test the closure is run inside the loop, not outside it. 68 // Test the closure is run inside the loop, not outside it.
73 base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC, 69 base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC,
74 base::WaitableEvent::InitialState::NOT_SIGNALED); 70 base::WaitableEvent::InitialState::NOT_SIGNALED);
75 base::Closure cb = BindToCurrentLoop(base::Bind( 71 base::RepeatingClosure cb = BindToCurrentLoop(base::BindRepeating(
76 &base::WaitableEvent::Signal, base::Unretained(&waiter))); 72 &base::WaitableEvent::Signal, base::Unretained(&waiter)));
77 cb.Run(); 73 cb.Run();
78 EXPECT_FALSE(waiter.IsSignaled()); 74 EXPECT_FALSE(waiter.IsSignaled());
79 base::RunLoop().RunUntilIdle(); 75 base::RunLoop().RunUntilIdle();
80 EXPECT_TRUE(waiter.IsSignaled()); 76 EXPECT_TRUE(waiter.IsSignaled());
81 } 77 }
82 78
83 TEST_F(BindToCurrentLoopTest, Bool) { 79 TEST_F(BindToCurrentLoopTest, OnceClosure) {
80 // Test the closure is run inside the loop, not outside it.
81 base::WaitableEvent waiter(base::WaitableEvent::ResetPolicy::AUTOMATIC,
82 base::WaitableEvent::InitialState::NOT_SIGNALED);
83 base::OnceClosure cb = BindToCurrentLoop(
84 base::BindOnce(&base::WaitableEvent::Signal, base::Unretained(&waiter)));
85 std::move(cb).Run();
86 EXPECT_FALSE(waiter.IsSignaled());
87 base::RunLoop().RunUntilIdle();
88 EXPECT_TRUE(waiter.IsSignaled());
89 }
90
91 TEST_F(BindToCurrentLoopTest, BoolRepeating) {
84 bool bool_var = false; 92 bool bool_var = false;
85 base::Callback<void(bool)> cb = BindToCurrentLoop(base::Bind( 93 base::RepeatingCallback<void(bool)> cb =
86 &BoundBoolSet, &bool_var)); 94 BindToCurrentLoop(base::BindRepeating(&BoundBoolSet, &bool_var));
87 cb.Run(true); 95 cb.Run(true);
88 EXPECT_FALSE(bool_var); 96 EXPECT_FALSE(bool_var);
89 base::RunLoop().RunUntilIdle(); 97 base::RunLoop().RunUntilIdle();
90 EXPECT_TRUE(bool_var); 98 EXPECT_TRUE(bool_var);
91 } 99
92 100 cb.Run(false);
93 TEST_F(BindToCurrentLoopTest, BoundScopedPtrBool) { 101 EXPECT_TRUE(bool_var);
94 bool bool_val = false; 102 base::RunLoop().RunUntilIdle();
95 std::unique_ptr<bool> scoped_ptr_bool(new bool(true)); 103 EXPECT_FALSE(bool_var);
96 base::Closure cb = BindToCurrentLoop(base::Bind( 104 }
97 &BoundBoolSetFromScopedPtr, &bool_val, base::Passed(&scoped_ptr_bool))); 105
106 TEST_F(BindToCurrentLoopTest, BoolOnce) {
107 bool bool_var = false;
108 base::OnceCallback<void(bool)> cb =
109 BindToCurrentLoop(base::BindOnce(&BoundBoolSet, &bool_var));
110 std::move(cb).Run(true);
111 EXPECT_FALSE(bool_var);
112 base::RunLoop().RunUntilIdle();
113 EXPECT_TRUE(bool_var);
114 }
115
116 TEST_F(BindToCurrentLoopTest, BoundUniquePtrBoolRepeating) {
117 bool bool_val = false;
118 std::unique_ptr<bool> unique_ptr_bool(new bool(true));
119 base::RepeatingClosure cb = BindToCurrentLoop(base::BindRepeating(
120 &BoundBoolSetFromUniquePtr, &bool_val, base::Passed(&unique_ptr_bool)));
98 cb.Run(); 121 cb.Run();
99 EXPECT_FALSE(bool_val); 122 EXPECT_FALSE(bool_val);
100 base::RunLoop().RunUntilIdle(); 123 base::RunLoop().RunUntilIdle();
101 EXPECT_TRUE(bool_val); 124 EXPECT_TRUE(bool_val);
102 } 125 }
103 126
104 TEST_F(BindToCurrentLoopTest, PassedScopedPtrBool) { 127 TEST_F(BindToCurrentLoopTest, BoundUniquePtrBoolOnce) {
105 bool bool_val = false; 128 bool bool_val = false;
106 std::unique_ptr<bool> scoped_ptr_bool(new bool(true)); 129 std::unique_ptr<bool> unique_ptr_bool(new bool(true));
107 base::Callback<void(std::unique_ptr<bool>)> cb = 130 base::OnceClosure cb = BindToCurrentLoop(base::BindOnce(
108 BindToCurrentLoop(base::Bind(&BoundBoolSetFromScopedPtr, &bool_val)); 131 &BoundBoolSetFromUniquePtr, &bool_val, std::move(unique_ptr_bool)));
109 cb.Run(std::move(scoped_ptr_bool)); 132 std::move(cb).Run();
110 EXPECT_FALSE(bool_val); 133 EXPECT_FALSE(bool_val);
111 base::RunLoop().RunUntilIdle(); 134 base::RunLoop().RunUntilIdle();
112 EXPECT_TRUE(bool_val); 135 EXPECT_TRUE(bool_val);
113 } 136 }
114 137
115 TEST_F(BindToCurrentLoopTest, BoundScopedArrayBool) { 138 TEST_F(BindToCurrentLoopTest, PassedUniquePtrBoolRepeating) {
116 bool bool_val = false; 139 bool bool_val = false;
117 std::unique_ptr<bool[]> scoped_array_bool(new bool[1]); 140 base::RepeatingCallback<void(std::unique_ptr<bool>)> cb = BindToCurrentLoop(
118 scoped_array_bool[0] = true; 141 base::BindRepeating(&BoundBoolSetFromUniquePtr, &bool_val));
119 base::Closure cb = BindToCurrentLoop(base::Bind( 142 cb.Run(base::MakeUnique<bool>(true));
120 &BoundBoolSetFromScopedArray, &bool_val, 143 EXPECT_FALSE(bool_val);
121 base::Passed(&scoped_array_bool))); 144 base::RunLoop().RunUntilIdle();
145 EXPECT_TRUE(bool_val);
146
147 cb.Run(base::MakeUnique<bool>(false));
148 EXPECT_TRUE(bool_val);
149 base::RunLoop().RunUntilIdle();
150 EXPECT_FALSE(bool_val);
151 }
152
153 TEST_F(BindToCurrentLoopTest, PassedUniquePtrBoolOnce) {
154 bool bool_val = false;
155 base::OnceCallback<void(std::unique_ptr<bool>)> cb =
156 BindToCurrentLoop(base::BindOnce(&BoundBoolSetFromUniquePtr, &bool_val));
157 std::move(cb).Run(base::MakeUnique<bool>(true));
158 EXPECT_FALSE(bool_val);
159 base::RunLoop().RunUntilIdle();
160 EXPECT_TRUE(bool_val);
161 }
162
163 TEST_F(BindToCurrentLoopTest, BoundUniquePtrArrayBoolRepeating) {
164 bool bool_val = false;
165 std::unique_ptr<bool[]> unique_ptr_array_bool(new bool[1]);
166 unique_ptr_array_bool[0] = true;
167 base::RepeatingClosure cb = BindToCurrentLoop(
168 base::BindRepeating(&BoundBoolSetFromUniquePtrArray, &bool_val,
169 base::Passed(&unique_ptr_array_bool)));
122 cb.Run(); 170 cb.Run();
123 EXPECT_FALSE(bool_val); 171 EXPECT_FALSE(bool_val);
124 base::RunLoop().RunUntilIdle(); 172 base::RunLoop().RunUntilIdle();
125 EXPECT_TRUE(bool_val); 173 EXPECT_TRUE(bool_val);
126 } 174 }
127 175
128 TEST_F(BindToCurrentLoopTest, PassedScopedArrayBool) { 176 TEST_F(BindToCurrentLoopTest, BoundUniquePtrArrayBoolOnce) {
129 bool bool_val = false; 177 bool bool_val = false;
130 std::unique_ptr<bool[]> scoped_array_bool(new bool[1]); 178 std::unique_ptr<bool[]> unique_ptr_array_bool(new bool[1]);
131 scoped_array_bool[0] = true; 179 unique_ptr_array_bool[0] = true;
132 base::Callback<void(std::unique_ptr<bool[]>)> cb = 180 base::OnceClosure cb = BindToCurrentLoop(
133 BindToCurrentLoop(base::Bind(&BoundBoolSetFromScopedArray, &bool_val)); 181 base::BindOnce(&BoundBoolSetFromUniquePtrArray, &bool_val,
134 cb.Run(std::move(scoped_array_bool)); 182 std::move(unique_ptr_array_bool)));
135 EXPECT_FALSE(bool_val); 183 std::move(cb).Run();
136 base::RunLoop().RunUntilIdle(); 184 EXPECT_FALSE(bool_val);
137 EXPECT_TRUE(bool_val); 185 base::RunLoop().RunUntilIdle();
138 } 186 EXPECT_TRUE(bool_val);
139 187 }
140 TEST_F(BindToCurrentLoopTest, BoundScopedPtrFreeDeleterBool) { 188
141 bool bool_val = false; 189 TEST_F(BindToCurrentLoopTest, PassedUniquePtrArrayBoolRepeating) {
142 std::unique_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool( 190 bool bool_val = false;
143 static_cast<bool*>(malloc(sizeof(bool)))); 191 base::RepeatingCallback<void(std::unique_ptr<bool[]>)> cb = BindToCurrentLoop(
144 *scoped_ptr_free_deleter_bool = true; 192 base::BindRepeating(&BoundBoolSetFromUniquePtrArray, &bool_val));
145 base::Closure cb = BindToCurrentLoop(base::Bind( 193
146 &BoundBoolSetFromScopedPtrFreeDeleter, &bool_val, 194 std::unique_ptr<bool[]> unique_ptr_array_bool(new bool[1]);
147 base::Passed(&scoped_ptr_free_deleter_bool))); 195 unique_ptr_array_bool[0] = true;
196 cb.Run(std::move(unique_ptr_array_bool));
197 EXPECT_FALSE(bool_val);
198 base::RunLoop().RunUntilIdle();
199 EXPECT_TRUE(bool_val);
200
201 unique_ptr_array_bool.reset(new bool[1]);
202 unique_ptr_array_bool[0] = false;
203 cb.Run(std::move(unique_ptr_array_bool));
204 EXPECT_TRUE(bool_val);
205 base::RunLoop().RunUntilIdle();
206 EXPECT_FALSE(bool_val);
207 }
208
209 TEST_F(BindToCurrentLoopTest, PassedUniquePtrArrayBoolOnce) {
210 bool bool_val = false;
211 base::OnceCallback<void(std::unique_ptr<bool[]>)> cb = BindToCurrentLoop(
212 base::BindOnce(&BoundBoolSetFromUniquePtrArray, &bool_val));
213
214 std::unique_ptr<bool[]> unique_ptr_array_bool(new bool[1]);
215 unique_ptr_array_bool[0] = true;
216 std::move(cb).Run(std::move(unique_ptr_array_bool));
217 EXPECT_FALSE(bool_val);
218 base::RunLoop().RunUntilIdle();
219 EXPECT_TRUE(bool_val);
220 }
221
222 TEST_F(BindToCurrentLoopTest, BoundUniquePtrFreeDeleterBoolRepeating) {
223 bool bool_val = false;
224 std::unique_ptr<bool, base::FreeDeleter> unique_ptr_free_deleter_bool(
225 static_cast<bool*>(malloc(sizeof(bool))));
226 *unique_ptr_free_deleter_bool = true;
227 base::RepeatingClosure cb = BindToCurrentLoop(
228 base::BindRepeating(&BoundBoolSetFromUniquePtrFreeDeleter, &bool_val,
229 base::Passed(&unique_ptr_free_deleter_bool)));
148 cb.Run(); 230 cb.Run();
149 EXPECT_FALSE(bool_val); 231 EXPECT_FALSE(bool_val);
150 base::RunLoop().RunUntilIdle(); 232 base::RunLoop().RunUntilIdle();
151 EXPECT_TRUE(bool_val); 233 EXPECT_TRUE(bool_val);
152 } 234 }
153 235
154 TEST_F(BindToCurrentLoopTest, PassedScopedPtrFreeDeleterBool) { 236 TEST_F(BindToCurrentLoopTest, BoundUniquePtrFreeDeleterBoolOnce) {
155 bool bool_val = false; 237 bool bool_val = false;
156 std::unique_ptr<bool, base::FreeDeleter> scoped_ptr_free_deleter_bool( 238 std::unique_ptr<bool, base::FreeDeleter> unique_ptr_free_deleter_bool(
157 static_cast<bool*>(malloc(sizeof(bool)))); 239 static_cast<bool*>(malloc(sizeof(bool))));
158 *scoped_ptr_free_deleter_bool = true; 240 *unique_ptr_free_deleter_bool = true;
159 base::Callback<void(std::unique_ptr<bool, base::FreeDeleter>)> cb = 241 base::OnceClosure cb = BindToCurrentLoop(
242 base::BindOnce(&BoundBoolSetFromUniquePtrFreeDeleter, &bool_val,
243 std::move(unique_ptr_free_deleter_bool)));
244 std::move(cb).Run();
245 EXPECT_FALSE(bool_val);
246 base::RunLoop().RunUntilIdle();
247 EXPECT_TRUE(bool_val);
248 }
249
250 TEST_F(BindToCurrentLoopTest, PassedUniquePtrFreeDeleterBoolRepeating) {
251 bool bool_val = false;
252 base::RepeatingCallback<void(std::unique_ptr<bool, base::FreeDeleter>)> cb =
253 BindToCurrentLoop(base::BindRepeating(
254 &BoundBoolSetFromUniquePtrFreeDeleter, &bool_val));
255
256 std::unique_ptr<bool, base::FreeDeleter> unique_ptr_free_deleter_bool(
257 static_cast<bool*>(malloc(sizeof(bool))));
258 *unique_ptr_free_deleter_bool = true;
259 cb.Run(std::move(unique_ptr_free_deleter_bool));
260 EXPECT_FALSE(bool_val);
261 base::RunLoop().RunUntilIdle();
262 EXPECT_TRUE(bool_val);
263
264 unique_ptr_free_deleter_bool.reset(static_cast<bool*>(malloc(sizeof(bool))));
265 *unique_ptr_free_deleter_bool = false;
266 cb.Run(std::move(unique_ptr_free_deleter_bool));
267 EXPECT_TRUE(bool_val);
268 base::RunLoop().RunUntilIdle();
269 EXPECT_FALSE(bool_val);
270 }
271
272 TEST_F(BindToCurrentLoopTest, PassedUniquePtrFreeDeleterBoolOnce) {
273 bool bool_val = false;
274 base::OnceCallback<void(std::unique_ptr<bool, base::FreeDeleter>)> cb =
160 BindToCurrentLoop( 275 BindToCurrentLoop(
161 base::Bind(&BoundBoolSetFromScopedPtrFreeDeleter, &bool_val)); 276 base::BindOnce(&BoundBoolSetFromUniquePtrFreeDeleter, &bool_val));
162 cb.Run(std::move(scoped_ptr_free_deleter_bool)); 277
163 EXPECT_FALSE(bool_val); 278 std::unique_ptr<bool, base::FreeDeleter> unique_ptr_free_deleter_bool(
164 base::RunLoop().RunUntilIdle(); 279 static_cast<bool*>(malloc(sizeof(bool))));
165 EXPECT_TRUE(bool_val); 280 *unique_ptr_free_deleter_bool = true;
166 } 281 std::move(cb).Run(std::move(unique_ptr_free_deleter_bool));
167 282 EXPECT_FALSE(bool_val);
168 TEST_F(BindToCurrentLoopTest, BoolConstRef) { 283 base::RunLoop().RunUntilIdle();
169 bool bool_var = false; 284 EXPECT_TRUE(bool_val);
170 bool true_var = true; 285 }
171 const bool& true_ref = true_var; 286
172 base::Closure cb = BindToCurrentLoop(base::Bind( 287 TEST_F(BindToCurrentLoopTest, IntegersRepeating) {
173 &BoundBoolSetFromConstRef, &bool_var, true_ref));
174 cb.Run();
175 EXPECT_FALSE(bool_var);
176 base::RunLoop().RunUntilIdle();
177 EXPECT_TRUE(bool_var);
178 }
179
180 TEST_F(BindToCurrentLoopTest, Integers) {
181 int a = 0; 288 int a = 0;
182 int b = 0; 289 int b = 0;
183 base::Callback<void(int, int)> cb = BindToCurrentLoop(base::Bind( 290 base::RepeatingCallback<void(int, int)> cb =
184 &BoundIntegersSet, &a, &b)); 291 BindToCurrentLoop(base::BindRepeating(&BoundIntegersSet, &a, &b));
185 cb.Run(1, -1); 292 cb.Run(1, -1);
186 EXPECT_EQ(a, 0); 293 EXPECT_EQ(a, 0);
187 EXPECT_EQ(b, 0); 294 EXPECT_EQ(b, 0);
188 base::RunLoop().RunUntilIdle(); 295 base::RunLoop().RunUntilIdle();
189 EXPECT_EQ(a, 1); 296 EXPECT_EQ(a, 1);
190 EXPECT_EQ(b, -1); 297 EXPECT_EQ(b, -1);
191 } 298
192 299 cb.Run(2, -2);
193 TEST_F(BindToCurrentLoopTest, DestroyedOnBoundLoop) { 300 EXPECT_EQ(a, 1);
301 EXPECT_EQ(b, -1);
302 base::RunLoop().RunUntilIdle();
303 EXPECT_EQ(a, 2);
304 EXPECT_EQ(b, -2);
305 }
306
307 TEST_F(BindToCurrentLoopTest, IntegersOnce) {
308 int a = 0;
309 int b = 0;
310 base::OnceCallback<void(int, int)> cb =
311 BindToCurrentLoop(base::BindOnce(&BoundIntegersSet, &a, &b));
312 std::move(cb).Run(1, -1);
313 EXPECT_EQ(a, 0);
314 EXPECT_EQ(b, 0);
315 base::RunLoop().RunUntilIdle();
316 EXPECT_EQ(a, 1);
317 EXPECT_EQ(b, -1);
318 }
319
320 TEST_F(BindToCurrentLoopTest, DestroyedOnBoundLoopRepeating) {
194 base::Thread target_thread("testing"); 321 base::Thread target_thread("testing");
195 ASSERT_TRUE(target_thread.Start()); 322 ASSERT_TRUE(target_thread.Start());
196 323
197 // Ensure that the bound object is also destroyed on the correct thread even 324 // Ensure that the bound object is also destroyed on the correct thread even
198 // if the last reference to the callback is dropped on the other thread. 325 // if the last reference to the callback is dropped on the other thread.
199 // TODO(tzik): Remove RunAndClearReference once TaskRunner migrates to 326 base::RepeatingClosure cb = BindToCurrentLoop(
200 // OnceClosure. RunAndCleareReference is needed to ensure no reference to |cb| 327 base::BindRepeating(&ThreadRestrictionChecker::Run,
201 // is left to the original thread. 328 base::MakeUnique<ThreadRestrictionChecker>()));
202 base::Closure cb = BindToCurrentLoop( 329 target_thread.task_runner()->PostTask(FROM_HERE, std::move(cb));
203 base::Bind(&ThreadRestrictionChecker::Run,
204 base::MakeUnique<ThreadRestrictionChecker>()));
205 target_thread.task_runner()->PostTask(
206 FROM_HERE, base::Bind(&RunAndClearReference, base::Passed(&cb)));
207 ASSERT_FALSE(cb); 330 ASSERT_FALSE(cb);
208 target_thread.FlushForTesting(); 331 target_thread.FlushForTesting();
209 base::RunLoop().RunUntilIdle(); 332 base::RunLoop().RunUntilIdle();
333
334 // Ensure that the bound object is destroyed on the target thread even if
335 // the callback is destroyed without invocation.
336 cb = BindToCurrentLoop(
337 base::BindRepeating(&ThreadRestrictionChecker::Run,
338 base::MakeUnique<ThreadRestrictionChecker>()));
339 target_thread.task_runner()->PostTask(
340 FROM_HERE, base::BindOnce(&ClearReference, std::move(cb)));
341 target_thread.FlushForTesting();
342 ASSERT_FALSE(cb);
343 base::RunLoop().RunUntilIdle();
344
345 target_thread.Stop();
346 }
347
348 TEST_F(BindToCurrentLoopTest, DestroyedOnBoundLoopOnce) {
349 base::Thread target_thread("testing");
350 ASSERT_TRUE(target_thread.Start());
351
352 // Ensure that the bound object is also destroyed on the correct thread even
353 // if the last reference to the callback is dropped on the other thread.
354 base::OnceClosure cb = BindToCurrentLoop(
355 base::BindOnce(&ThreadRestrictionChecker::Run,
356 base::MakeUnique<ThreadRestrictionChecker>()));
357 target_thread.task_runner()->PostTask(FROM_HERE, std::move(cb));
358 ASSERT_FALSE(cb);
359 target_thread.FlushForTesting();
360 base::RunLoop().RunUntilIdle();
210 361
211 // Ensure that the bound object is destroyed on the target thread even if 362 // Ensure that the bound object is destroyed on the target thread even if
212 // the callback is destroyed without invocation. 363 // the callback is destroyed without invocation.
213 cb = BindToCurrentLoop( 364 cb = BindToCurrentLoop(
214 base::Bind(&ThreadRestrictionChecker::Run, 365 base::BindOnce(&ThreadRestrictionChecker::Run,
215 base::MakeUnique<ThreadRestrictionChecker>())); 366 base::MakeUnique<ThreadRestrictionChecker>()));
216 target_thread.task_runner()->PostTask( 367 target_thread.task_runner()->PostTask(
217 FROM_HERE, base::Bind(&ClearReference, base::Passed(&cb))); 368 FROM_HERE, base::BindOnce(&ClearReference, std::move(cb)));
218 target_thread.FlushForTesting(); 369 target_thread.FlushForTesting();
219 ASSERT_FALSE(cb); 370 ASSERT_FALSE(cb);
220 base::RunLoop().RunUntilIdle(); 371 base::RunLoop().RunUntilIdle();
221 372
222 target_thread.Stop(); 373 target_thread.Stop();
223 } 374 }
224 375
225 } // namespace media 376 } // namespace media
OLDNEW
« media/base/bind_to_current_loop.h ('K') | « media/base/bind_to_current_loop.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698