OLD | NEW |
---|---|
1 // This file was GENERATED by command: | 1 // This file was GENERATED by command: |
2 // pump.py bind_to_loop.h.pump | 2 // pump.py bind_to_loop.h.pump |
3 // DO NOT EDIT BY HAND!!! | 3 // DO NOT EDIT BY HAND!!! |
4 | 4 |
5 | 5 |
6 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 6 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
7 // Use of this source code is governed by a BSD-style license that can be | 7 // Use of this source code is governed by a BSD-style license that can be |
8 // found in the LICENSE file. | 8 // found in the LICENSE file. |
9 | 9 |
10 #ifndef MEDIA_BASE_BIND_TO_LOOP_H_ | 10 #ifndef MEDIA_BASE_BIND_TO_LOOP_H_ |
11 #define MEDIA_BASE_BIND_TO_LOOP_H_ | 11 #define MEDIA_BASE_BIND_TO_LOOP_H_ |
12 | 12 |
13 #include "base/bind.h" | 13 #include "base/bind.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/message_loop/message_loop_proxy.h" | 15 #include "base/message_loop/message_loop_proxy.h" |
16 #include "base/synchronization/waitable_event.h" | |
16 | 17 |
17 // This is a helper utility for base::Bind()ing callbacks on to particular | 18 // This is a helper utility for base::Bind()ing callbacks on to particular |
18 // MessageLoops. A typical use is when |a| (of class |A|) wants to hand a | 19 // MessageLoops. A typical use is when |a| (of class |A|) wants to hand a |
19 // callback such as base::Bind(&A::AMethod, a) to |b|, but needs to ensure that | 20 // callback such as base::Bind(&A::AMethod, a) to |b|, but needs to ensure that |
20 // when |b| executes the callback, it does so on a particular MessageLoop. | 21 // when |b| executes the callback, it does so on a particular MessageLoop. |
21 // | 22 // |
22 // Typical usage: request to be called back on the current thread: | 23 // Typical usage: request to be called back on the current thread: |
23 // other->StartAsyncProcessAndCallMeBack( | 24 // other->StartAsyncProcessAndCallMeBack( |
24 // media::BindToLoop(MessageLoopProxy::current(), | 25 // media::BindToLoop(MessageLoopProxy::current(), |
25 // base::Bind(&MyClass::MyMethod, this))); | 26 // base::Bind(&MyClass::MyMethod, this))); |
26 // | 27 // |
27 // Note that like base::Bind(), BindToLoop() can't bind non-constant references, | 28 // For synchronous usage, where the callback needs to be executed on another |
28 // and that *unlike* base::Bind(), BindToLoop() makes copies of its arguments, | 29 // MessageLoop, but the calling thread should block until the callback has been |
29 // and thus can't be used with arrays. | 30 // completed, there is BindToLoopSync(), as below: |
31 // | |
32 // Typical usage: make a request to another thread, and wait for it: | |
33 // do_something_callback = | |
34 // media::BindToLoopSync(other_message_loop, &OtherClass::DoRequest, other); | |
35 // // ... | |
36 // do_something_callback.Run(); // will block until completion | |
37 // | |
38 // Note that like base::Bind(), BindToLoop() and BindToLoopSync() can't bind | |
39 // non-constant references, and that *unlike* base::Bind(), BindToLoop*() makes | |
40 // copies of its arguments, and thus can't be used with arrays. | |
30 | 41 |
31 namespace media { | 42 namespace media { |
32 | 43 |
33 // Mimic base::internal::CallbackForward, replacing p.Pass() with | 44 // Mimic base::internal::CallbackForward, replacing p.Pass() with |
34 // base::Passed(&p) to account for the extra layer of indirection. | 45 // base::Passed(&p) to account for the extra layer of indirection. |
35 namespace internal { | 46 namespace internal { |
36 template <typename T> | 47 template <typename T> |
37 T& TrampolineForward(T& t) { return t; } | 48 T& TrampolineForward(T& t) { return t; } |
38 | 49 |
39 template <typename T> | 50 template <typename T> |
40 base::internal::PassedWrapper<scoped_ptr<T> > TrampolineForward( | 51 base::internal::PassedWrapper<scoped_ptr<T> > TrampolineForward( |
41 scoped_ptr<T>& p) { return base::Passed(&p); } | 52 scoped_ptr<T>& p) { return base::Passed(&p); } |
42 | 53 |
43 template <typename T, typename R> | 54 template <typename T, typename R> |
44 base::internal::PassedWrapper<scoped_ptr_malloc<T, R> > TrampolineForward( | 55 base::internal::PassedWrapper<scoped_ptr_malloc<T, R> > TrampolineForward( |
45 scoped_ptr_malloc<T, R>& p) { return base::Passed(&p); } | 56 scoped_ptr_malloc<T, R>& p) { return base::Passed(&p); } |
46 | 57 |
47 template <typename T> | 58 template <typename T> |
48 base::internal::PassedWrapper<ScopedVector<T> > TrampolineForward( | 59 base::internal::PassedWrapper<ScopedVector<T> > TrampolineForward( |
49 ScopedVector<T>& p) { return base::Passed(&p); } | 60 ScopedVector<T>& p) { return base::Passed(&p); } |
50 | 61 |
51 template <typename T> struct TrampolineHelper; | 62 template <typename T> struct TrampolineHelper; |
52 | 63 |
64 // Caller helper to call a base::Closure synchronously | |
65 void TrampolineSyncCaller(const base::Closure& closure, | |
66 base::WaitableEvent* waiter); | |
67 | |
53 template <> | 68 template <> |
54 struct TrampolineHelper<void()> { | 69 struct TrampolineHelper<void()> { |
55 static void Run( | 70 static void Run( |
56 const scoped_refptr<base::MessageLoopProxy>& loop, | 71 const scoped_refptr<base::MessageLoopProxy>& loop, |
57 const base::Callback<void()>& cb) { | 72 const base::Callback<void()>& cb) { |
58 loop->PostTask(FROM_HERE, base::Bind(cb)); | 73 loop->PostTask(FROM_HERE, base::Bind(cb)); |
59 } | 74 } |
75 static void RunSync( | |
76 const scoped_refptr<base::MessageLoopProxy>& loop, | |
77 const base::Callback<void()>& cb) { | |
78 DCHECK(!loop->BelongsToCurrentThread()); | |
79 base::WaitableEvent waiter(false, false); | |
80 loop->PostTask( | |
81 FROM_HERE, | |
82 base::Bind( | |
83 &TrampolineSyncCaller, | |
84 base::Bind(cb), | |
85 &waiter)); | |
86 waiter.Wait(); | |
87 } | |
60 }; | 88 }; |
61 | 89 |
62 | 90 |
63 template <typename A1> | 91 template <typename A1> |
64 struct TrampolineHelper<void(A1)> { | 92 struct TrampolineHelper<void(A1)> { |
65 static void Run( | 93 static void Run( |
66 const scoped_refptr<base::MessageLoopProxy>& loop, | 94 const scoped_refptr<base::MessageLoopProxy>& loop, |
67 const base::Callback<void(A1)>& cb, A1 a1) { | 95 const base::Callback<void(A1)>& cb, A1 a1) { |
68 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1))); | 96 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1))); |
69 } | 97 } |
98 static void RunSync( | |
99 const scoped_refptr<base::MessageLoopProxy>& loop, | |
100 const base::Callback<void(A1)>& cb, A1 a1) { | |
101 DCHECK(!loop->BelongsToCurrentThread()); | |
102 base::WaitableEvent waiter(false, false); | |
103 loop->PostTask( | |
104 FROM_HERE, | |
105 base::Bind( | |
106 &TrampolineSyncCaller, | |
107 base::Bind(cb, internal::TrampolineForward(a1)), | |
108 &waiter)); | |
109 waiter.Wait(); | |
110 } | |
70 }; | 111 }; |
71 | 112 |
72 | 113 |
73 template <typename A1, typename A2> | 114 template <typename A1, typename A2> |
74 struct TrampolineHelper<void(A1, A2)> { | 115 struct TrampolineHelper<void(A1, A2)> { |
75 static void Run( | 116 static void Run( |
76 const scoped_refptr<base::MessageLoopProxy>& loop, | 117 const scoped_refptr<base::MessageLoopProxy>& loop, |
77 const base::Callback<void(A1, A2)>& cb, A1 a1, A2 a2) { | 118 const base::Callback<void(A1, A2)>& cb, A1 a1, A2 a2) { |
78 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), | 119 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), |
79 internal::TrampolineForward(a2))); | 120 internal::TrampolineForward(a2))); |
80 } | 121 } |
122 static void RunSync( | |
123 const scoped_refptr<base::MessageLoopProxy>& loop, | |
124 const base::Callback<void(A1, A2)>& cb, A1 a1, A2 a2) { | |
125 DCHECK(!loop->BelongsToCurrentThread()); | |
126 base::WaitableEvent waiter(false, false); | |
127 loop->PostTask( | |
128 FROM_HERE, | |
129 base::Bind( | |
130 &TrampolineSyncCaller, | |
131 base::Bind(cb, internal::TrampolineForward(a1), | |
132 internal::TrampolineForward(a2)), | |
133 &waiter)); | |
134 waiter.Wait(); | |
135 } | |
81 }; | 136 }; |
82 | 137 |
83 | 138 |
84 template <typename A1, typename A2, typename A3> | 139 template <typename A1, typename A2, typename A3> |
85 struct TrampolineHelper<void(A1, A2, A3)> { | 140 struct TrampolineHelper<void(A1, A2, A3)> { |
86 static void Run( | 141 static void Run( |
87 const scoped_refptr<base::MessageLoopProxy>& loop, | 142 const scoped_refptr<base::MessageLoopProxy>& loop, |
88 const base::Callback<void(A1, A2, A3)>& cb, A1 a1, A2 a2, A3 a3) { | 143 const base::Callback<void(A1, A2, A3)>& cb, A1 a1, A2 a2, A3 a3) { |
89 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), | 144 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), |
90 internal::TrampolineForward(a2), internal::TrampolineForward(a3))); | 145 internal::TrampolineForward(a2), internal::TrampolineForward(a3))); |
91 } | 146 } |
147 static void RunSync( | |
148 const scoped_refptr<base::MessageLoopProxy>& loop, | |
149 const base::Callback<void(A1, A2, A3)>& cb, A1 a1, A2 a2, A3 a3) { | |
150 DCHECK(!loop->BelongsToCurrentThread()); | |
151 base::WaitableEvent waiter(false, false); | |
152 loop->PostTask( | |
153 FROM_HERE, | |
154 base::Bind( | |
155 &TrampolineSyncCaller, | |
156 base::Bind(cb, internal::TrampolineForward(a1), | |
157 internal::TrampolineForward(a2), | |
158 internal::TrampolineForward(a3)), | |
159 &waiter)); | |
160 waiter.Wait(); | |
161 } | |
92 }; | 162 }; |
93 | 163 |
94 | 164 |
95 template <typename A1, typename A2, typename A3, typename A4> | 165 template <typename A1, typename A2, typename A3, typename A4> |
96 struct TrampolineHelper<void(A1, A2, A3, A4)> { | 166 struct TrampolineHelper<void(A1, A2, A3, A4)> { |
97 static void Run( | 167 static void Run( |
98 const scoped_refptr<base::MessageLoopProxy>& loop, | 168 const scoped_refptr<base::MessageLoopProxy>& loop, |
99 const base::Callback<void(A1, A2, A3, A4)>& cb, A1 a1, A2 a2, A3 a3, | 169 const base::Callback<void(A1, A2, A3, A4)>& cb, A1 a1, A2 a2, A3 a3, |
100 A4 a4) { | 170 A4 a4) { |
101 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), | 171 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), |
102 internal::TrampolineForward(a2), internal::TrampolineForward(a3), | 172 internal::TrampolineForward(a2), internal::TrampolineForward(a3), |
103 internal::TrampolineForward(a4))); | 173 internal::TrampolineForward(a4))); |
104 } | 174 } |
175 static void RunSync( | |
176 const scoped_refptr<base::MessageLoopProxy>& loop, | |
177 const base::Callback<void(A1, A2, A3, A4)>& cb, A1 a1, A2 a2, A3 a3, | |
178 A4 a4) { | |
179 DCHECK(!loop->BelongsToCurrentThread()); | |
180 base::WaitableEvent waiter(false, false); | |
181 loop->PostTask( | |
182 FROM_HERE, | |
183 base::Bind( | |
184 &TrampolineSyncCaller, | |
185 base::Bind(cb, internal::TrampolineForward(a1), | |
186 internal::TrampolineForward(a2), | |
187 internal::TrampolineForward(a3), | |
188 internal::TrampolineForward(a4)), | |
189 &waiter)); | |
190 waiter.Wait(); | |
191 } | |
105 }; | 192 }; |
106 | 193 |
107 | 194 |
108 template <typename A1, typename A2, typename A3, typename A4, typename A5> | 195 template <typename A1, typename A2, typename A3, typename A4, typename A5> |
109 struct TrampolineHelper<void(A1, A2, A3, A4, A5)> { | 196 struct TrampolineHelper<void(A1, A2, A3, A4, A5)> { |
110 static void Run( | 197 static void Run( |
111 const scoped_refptr<base::MessageLoopProxy>& loop, | 198 const scoped_refptr<base::MessageLoopProxy>& loop, |
112 const base::Callback<void(A1, A2, A3, A4, A5)>& cb, A1 a1, A2 a2, A3 a3, | 199 const base::Callback<void(A1, A2, A3, A4, A5)>& cb, A1 a1, A2 a2, A3 a3, |
113 A4 a4, A5 a5) { | 200 A4 a4, A5 a5) { |
114 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), | 201 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), |
115 internal::TrampolineForward(a2), internal::TrampolineForward(a3), | 202 internal::TrampolineForward(a2), internal::TrampolineForward(a3), |
116 internal::TrampolineForward(a4), internal::TrampolineForward(a5))); | 203 internal::TrampolineForward(a4), internal::TrampolineForward(a5))); |
117 } | 204 } |
205 static void RunSync( | |
206 const scoped_refptr<base::MessageLoopProxy>& loop, | |
207 const base::Callback<void(A1, A2, A3, A4, A5)>& cb, A1 a1, A2 a2, A3 a3, | |
208 A4 a4, A5 a5) { | |
209 DCHECK(!loop->BelongsToCurrentThread()); | |
210 base::WaitableEvent waiter(false, false); | |
211 loop->PostTask( | |
212 FROM_HERE, | |
213 base::Bind( | |
214 &TrampolineSyncCaller, | |
215 base::Bind(cb, internal::TrampolineForward(a1), | |
216 internal::TrampolineForward(a2), | |
217 internal::TrampolineForward(a3), | |
218 internal::TrampolineForward(a4), | |
219 internal::TrampolineForward(a5)), | |
220 &waiter)); | |
221 waiter.Wait(); | |
222 } | |
118 }; | 223 }; |
119 | 224 |
120 | 225 |
121 template <typename A1, typename A2, typename A3, typename A4, typename A5, | 226 template <typename A1, typename A2, typename A3, typename A4, typename A5, |
122 typename A6> | 227 typename A6> |
123 struct TrampolineHelper<void(A1, A2, A3, A4, A5, A6)> { | 228 struct TrampolineHelper<void(A1, A2, A3, A4, A5, A6)> { |
124 static void Run( | 229 static void Run( |
125 const scoped_refptr<base::MessageLoopProxy>& loop, | 230 const scoped_refptr<base::MessageLoopProxy>& loop, |
126 const base::Callback<void(A1, A2, A3, A4, A5, A6)>& cb, A1 a1, A2 a2, | 231 const base::Callback<void(A1, A2, A3, A4, A5, A6)>& cb, A1 a1, A2 a2, |
127 A3 a3, A4 a4, A5 a5, A6 a6) { | 232 A3 a3, A4 a4, A5 a5, A6 a6) { |
128 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), | 233 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), |
129 internal::TrampolineForward(a2), internal::TrampolineForward(a3), | 234 internal::TrampolineForward(a2), internal::TrampolineForward(a3), |
130 internal::TrampolineForward(a4), internal::TrampolineForward(a5), | 235 internal::TrampolineForward(a4), internal::TrampolineForward(a5), |
131 internal::TrampolineForward(a6))); | 236 internal::TrampolineForward(a6))); |
132 } | 237 } |
238 static void RunSync( | |
239 const scoped_refptr<base::MessageLoopProxy>& loop, | |
240 const base::Callback<void(A1, A2, A3, A4, A5, A6)>& cb, A1 a1, A2 a2, | |
241 A3 a3, A4 a4, A5 a5, A6 a6) { | |
242 DCHECK(!loop->BelongsToCurrentThread()); | |
243 base::WaitableEvent waiter(false, false); | |
244 loop->PostTask( | |
245 FROM_HERE, | |
246 base::Bind( | |
247 &TrampolineSyncCaller, | |
248 base::Bind(cb, internal::TrampolineForward(a1), | |
249 internal::TrampolineForward(a2), | |
250 internal::TrampolineForward(a3), | |
251 internal::TrampolineForward(a4), | |
252 internal::TrampolineForward(a5), | |
253 internal::TrampolineForward(a6)), | |
254 &waiter)); | |
255 waiter.Wait(); | |
256 } | |
133 }; | 257 }; |
134 | 258 |
135 | 259 |
136 template <typename A1, typename A2, typename A3, typename A4, typename A5, | 260 template <typename A1, typename A2, typename A3, typename A4, typename A5, |
137 typename A6, typename A7> | 261 typename A6, typename A7> |
138 struct TrampolineHelper<void(A1, A2, A3, A4, A5, A6, A7)> { | 262 struct TrampolineHelper<void(A1, A2, A3, A4, A5, A6, A7)> { |
139 static void Run( | 263 static void Run( |
140 const scoped_refptr<base::MessageLoopProxy>& loop, | 264 const scoped_refptr<base::MessageLoopProxy>& loop, |
141 const base::Callback<void(A1, A2, A3, A4, A5, A6, A7)>& cb, A1 a1, A2 a2, | 265 const base::Callback<void(A1, A2, A3, A4, A5, A6, A7)>& cb, A1 a1, A2 a2, |
142 A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { | 266 A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { |
143 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), | 267 loop->PostTask(FROM_HERE, base::Bind(cb, internal::TrampolineForward(a1), |
144 internal::TrampolineForward(a2), internal::TrampolineForward(a3), | 268 internal::TrampolineForward(a2), internal::TrampolineForward(a3), |
145 internal::TrampolineForward(a4), internal::TrampolineForward(a5), | 269 internal::TrampolineForward(a4), internal::TrampolineForward(a5), |
146 internal::TrampolineForward(a6), internal::TrampolineForward(a7))); | 270 internal::TrampolineForward(a6), internal::TrampolineForward(a7))); |
147 } | 271 } |
272 static void RunSync( | |
273 const scoped_refptr<base::MessageLoopProxy>& loop, | |
274 const base::Callback<void(A1, A2, A3, A4, A5, A6, A7)>& cb, A1 a1, A2 a2, | |
275 A3 a3, A4 a4, A5 a5, A6 a6, A7 a7) { | |
276 DCHECK(!loop->BelongsToCurrentThread()); | |
277 base::WaitableEvent waiter(false, false); | |
278 loop->PostTask( | |
279 FROM_HERE, | |
280 base::Bind( | |
281 &TrampolineSyncCaller, | |
282 base::Bind(cb, internal::TrampolineForward(a1), | |
283 internal::TrampolineForward(a2), | |
284 internal::TrampolineForward(a3), | |
285 internal::TrampolineForward(a4), | |
286 internal::TrampolineForward(a5), | |
287 internal::TrampolineForward(a6), | |
288 internal::TrampolineForward(a7)), | |
289 &waiter)); | |
290 waiter.Wait(); | |
291 } | |
148 }; | 292 }; |
149 | 293 |
150 | 294 |
151 } // namespace internal | 295 } // namespace internal |
152 | 296 |
153 template<typename T> | 297 template<typename T> |
154 static base::Callback<T> BindToLoop( | 298 static base::Callback<T> BindToLoop( |
155 const scoped_refptr<base::MessageLoopProxy>& loop, | 299 const scoped_refptr<base::MessageLoopProxy>& loop, |
156 const base::Callback<T>& cb) { | 300 const base::Callback<T>& cb) { |
157 return base::Bind(&internal::TrampolineHelper<T>::Run, loop, cb); | 301 return base::Bind(&internal::TrampolineHelper<T>::Run, loop, cb); |
158 } | 302 } |
159 | 303 |
160 template<typename T> | 304 template<typename T> |
305 static base::Callback<T> BindToLoopSync( | |
jam
2013/10/28 20:11:08
I'm concerned about this. This makes it easy for c
sheu
2013/10/28 20:32:58
There's no guarantee, other than a general exhorta
jam
2013/10/28 20:43:25
If there's one thing I've learnt on Chrome, it's i
| |
306 const scoped_refptr<base::MessageLoopProxy>& loop, | |
307 const base::Callback<T>& cb) { | |
308 return base::Bind(&internal::TrampolineHelper<T>::RunSync, loop, cb); | |
309 } | |
310 | |
311 template<typename T> | |
161 static base::Callback<T> BindToCurrentLoop( | 312 static base::Callback<T> BindToCurrentLoop( |
162 const base::Callback<T>& cb) { | 313 const base::Callback<T>& cb) { |
163 return BindToLoop(base::MessageLoopProxy::current(), cb); | 314 return BindToLoop(base::MessageLoopProxy::current(), cb); |
164 } | 315 } |
165 | 316 |
166 } // namespace media | 317 } // namespace media |
167 | 318 |
168 #endif // MEDIA_BASE_BIND_TO_LOOP_H_ | 319 #endif // MEDIA_BASE_BIND_TO_LOOP_H_ |
OLD | NEW |