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

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

Powered by Google App Engine
This is Rietveld 408576698