Chromium Code Reviews| 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 |