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

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

Issue 1082113004: BindToCurrentLoop should delete callback on original thread Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 8 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 "base/barrier_closure.h"
7 #include "base/message_loop/message_loop.h" 8 #include "base/message_loop/message_loop.h"
9 #include "base/run_loop.h"
8 #include "base/synchronization/waitable_event.h" 10 #include "base/synchronization/waitable_event.h"
11 #include "base/threading/thread.h"
9 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
10 13
11 namespace media { 14 namespace media {
12 15
13 void BoundBoolSet(bool* var, bool val) { 16 void BoundBoolSet(bool* var, bool val) {
14 *var = val; 17 *var = val;
15 } 18 }
16 19
17 void BoundBoolSetFromScopedPtr(bool* var, scoped_ptr<bool> val) { 20 void BoundBoolSetFromScopedPtr(bool* var, scoped_ptr<bool> val) {
18 *var = *val; 21 *var = *val;
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
158 base::Callback<void(int, int)> cb = BindToCurrentLoop(base::Bind( 161 base::Callback<void(int, int)> cb = BindToCurrentLoop(base::Bind(
159 &BoundIntegersSet, &a, &b)); 162 &BoundIntegersSet, &a, &b));
160 cb.Run(1, -1); 163 cb.Run(1, -1);
161 EXPECT_EQ(a, 0); 164 EXPECT_EQ(a, 0);
162 EXPECT_EQ(b, 0); 165 EXPECT_EQ(b, 0);
163 loop_.RunUntilIdle(); 166 loop_.RunUntilIdle();
164 EXPECT_EQ(a, 1); 167 EXPECT_EQ(a, 1);
165 EXPECT_EQ(b, -1); 168 EXPECT_EQ(b, -1);
166 } 169 }
167 170
171 namespace {
172
173 void ExpectRunOn(scoped_refptr<base::SingleThreadTaskRunner> loop,
174 const base::Closure& done_closure) {
175 EXPECT_TRUE(loop->BelongsToCurrentThread());
176 done_closure.Run();
177 }
178
179 } // namespace
180
181 TEST_F(BindToCurrentLoopTest, CalledOnOriginalThread) {
182 scoped_refptr<base::SingleThreadTaskRunner> origin_loop =
183 base::ThreadTaskRunnerHandle::Get();
184 ASSERT_TRUE(origin_loop->BelongsToCurrentThread());
185
186 base::Thread thread("Other thread");
187 ASSERT_TRUE(thread.Start());
188 scoped_refptr<base::SingleThreadTaskRunner> thread_loop =
189 thread.task_runner();
190 ASSERT_FALSE(thread_loop->BelongsToCurrentThread());
191
192 base::RunLoop run_loop;
193 base::Closure barrier_closure =
194 base::BarrierClosure(2, BindToCurrentLoop(run_loop.QuitClosure()));
195
196 base::Closure thread_cb = base::Bind(
197 &ExpectRunOn, thread_loop, barrier_closure);
198 base::Closure origin_cb = BindToCurrentLoop(base::Bind(
199 &ExpectRunOn, origin_loop, barrier_closure));
200
201 thread_loop->PostTask(FROM_HERE, thread_cb);
202 thread_loop->PostTask(FROM_HERE, origin_cb);
203
204 run_loop.Run();
205
206 thread.Stop();
207 }
208
209 namespace {
210
211 class ExpectDeletedOnOrigin {
212 public:
213 ExpectDeletedOnOrigin(
214 scoped_refptr<base::SingleThreadTaskRunner> origin_loop,
215 const base::Closure& deleted_closure)
216 : origin_loop_(origin_loop),
217 deleted_closure_(deleted_closure) {}
218
219 ~ExpectDeletedOnOrigin() {
220 EXPECT_TRUE(origin_loop_->BelongsToCurrentThread());
221 deleted_closure_.Run();
222 }
223
224 scoped_refptr<base::SingleThreadTaskRunner> origin_loop_;
225 base::Closure deleted_closure_;
226 };
227
228 class RefCountedExpectDeletedOnOrigin
229 : public ExpectDeletedOnOrigin,
230 public base::RefCountedThreadSafe<RefCountedExpectDeletedOnOrigin> {
231 public:
232 RefCountedExpectDeletedOnOrigin(
233 scoped_refptr<base::SingleThreadTaskRunner> origin_loop,
234 const base::Closure& deleted_closure)
235 : ExpectDeletedOnOrigin(origin_loop, deleted_closure) {}
236
237 private:
238 friend class base::RefCountedThreadSafe<RefCountedExpectDeletedOnOrigin>;
239 ~RefCountedExpectDeletedOnOrigin() {}
240 };
241
242 void CallbackWithParamsToDelete(
243 ExpectDeletedOnOrigin* unused_owned,
244 scoped_ptr<ExpectDeletedOnOrigin> unused_passed,
245 scoped_refptr<RefCountedExpectDeletedOnOrigin> unused_ref_counted) {}
246
247 } // namespace
248
249 TEST_F(BindToCurrentLoopTest, CallbackDeletedOnOriginalThread) {
250 scoped_refptr<base::SingleThreadTaskRunner> origin_loop =
251 base::ThreadTaskRunnerHandle::Get();
252
253 base::Thread thread("Other thread");
254 ASSERT_TRUE(thread.Start());
255 scoped_refptr<base::SingleThreadTaskRunner> thread_loop =
256 thread.task_runner();
257
258 base::RunLoop run_loop;
259 base::Closure barrier_closure =
260 base::BarrierClosure(3, BindToCurrentLoop(run_loop.QuitClosure()));
261
262 base::Closure* origin_cb_ptr;
263 {
264 ExpectDeletedOnOrigin* new_delete_on_origin =
265 new ExpectDeletedOnOrigin(origin_loop, barrier_closure);
266 scoped_ptr<ExpectDeletedOnOrigin> scoped_delete_on_origin(
267 new ExpectDeletedOnOrigin(origin_loop, barrier_closure));
268 scoped_refptr<RefCountedExpectDeletedOnOrigin> counted_delete_on_origin =
269 new RefCountedExpectDeletedOnOrigin(origin_loop, barrier_closure);
270 origin_cb_ptr = new base::Closure(BindToCurrentLoop(base::Bind(
271 &CallbackWithParamsToDelete,
272 base::Owned(new_delete_on_origin),
273 base::Passed(&scoped_delete_on_origin),
274 counted_delete_on_origin)));
275 }
276
277 // Delete the callback returned by BindToCurrentLoop on the other thread. This
278 // must cause the wrapped callback that was passed in to BindToCurrentLoop to
279 // be deleted on the origin thread (where BindToCurrentLoop was invoked), and
280 // hence the parameters of that wrapped callback must also be deleted on the
281 // origin thread.
282 thread_loop->DeleteSoon(FROM_HERE, origin_cb_ptr);
283
284 // If this test times out, that means one of the ExpectDeletedOnOrigin or
285 // RefCountedExpectDeletedOnOrigin objects failed to be deleted (bad).
286 run_loop.Run();
287
288 thread.Stop();
289 }
290
168 } // namespace media 291 } // 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