| Index: media/base/bind_to_loop.h.pump
|
| diff --git a/media/base/bind_to_loop.h.pump b/media/base/bind_to_loop.h.pump
|
| index 8490413eb1cc333cb2279712014f825c7487779c..b7e90714647ce8b7cc89cd489b5590c45ad07b1b 100644
|
| --- a/media/base/bind_to_loop.h.pump
|
| +++ b/media/base/bind_to_loop.h.pump
|
| @@ -18,6 +18,7 @@ $var MAX_ARITY = 7
|
| #include "base/bind.h"
|
| #include "base/location.h"
|
| #include "base/message_loop/message_loop_proxy.h"
|
| +#include "base/synchronization/waitable_event.h"
|
|
|
| // This is a helper utility for base::Bind()ing callbacks on to particular
|
| // MessageLoops. A typical use is when |a| (of class |A|) wants to hand a
|
| @@ -29,9 +30,19 @@ $var MAX_ARITY = 7
|
| // media::BindToLoop(MessageLoopProxy::current(),
|
| // base::Bind(&MyClass::MyMethod, this)));
|
| //
|
| -// Note that like base::Bind(), BindToLoop() can't bind non-constant references,
|
| -// and that *unlike* base::Bind(), BindToLoop() makes copies of its arguments,
|
| -// and thus can't be used with arrays.
|
| +// For synchronous usage, where the callback needs to be executed on another
|
| +// MessageLoop, but the calling thread should block until the callback has been
|
| +// completed, there is BindToLoopSync(), as below:
|
| +//
|
| +// Typical usage: make a request to another thread, and wait for it:
|
| +// do_something_callback =
|
| +// media::BindToLoopSync(other_message_loop, &OtherClass::DoRequest, other);
|
| +// // ...
|
| +// do_something_callback.Run(); // will block until completion
|
| +//
|
| +// Note that like base::Bind(), BindToLoop() and BindToLoopSync() can't bind
|
| +// non-constant references, and that *unlike* base::Bind(), BindToLoop*() makes
|
| +// copies of its arguments, and thus can't be used with arrays.
|
|
|
| namespace media {
|
|
|
| @@ -55,6 +66,10 @@ base::internal::PassedWrapper<ScopedVector<T> > TrampolineForward(
|
|
|
| template <typename T> struct TrampolineHelper;
|
|
|
| +// Caller helper to call a base::Closure synchronously
|
| +void TrampolineSyncCaller(const base::Closure& closure,
|
| + base::WaitableEvent* waiter);
|
| +
|
| $range ARITY 0..MAX_ARITY
|
| $for ARITY [[
|
| $range ARG 1..ARITY
|
| @@ -71,6 +86,24 @@ $for ARG , [[A$(ARG) a$(ARG)]]
|
| $if ARITY != 0 [[, ]]
|
| $for ARG , [[internal::TrampolineForward(a$(ARG))]]));
|
| }
|
| + static void RunSync(
|
| + const scoped_refptr<base::MessageLoopProxy>& loop,
|
| + const base::Callback<void($for ARG , [[A$(ARG)]])>& cb
|
| +$if ARITY != 0 [[, ]]
|
| +$for ARG , [[A$(ARG) a$(ARG)]]
|
| +) {
|
| + DCHECK(!loop->BelongsToCurrentThread());
|
| + base::WaitableEvent waiter(false, false);
|
| + loop->PostTask(
|
| + FROM_HERE,
|
| + base::Bind(
|
| + &TrampolineSyncCaller,
|
| + base::Bind(cb
|
| +$if ARITY != 0 [[, ]]
|
| +$for ARG , [[internal::TrampolineForward(a$(ARG))]]),
|
| + &waiter));
|
| + waiter.Wait();
|
| + }
|
| };
|
|
|
|
|
| @@ -86,6 +119,13 @@ static base::Callback<T> BindToLoop(
|
| }
|
|
|
| template<typename T>
|
| +static base::Callback<T> BindToLoopSync(
|
| + const scoped_refptr<base::MessageLoopProxy>& loop,
|
| + const base::Callback<T>& cb) {
|
| + return base::Bind(&internal::TrampolineHelper<T>::RunSync, loop, cb);
|
| +}
|
| +
|
| +template<typename T>
|
| static base::Callback<T> BindToCurrentLoop(
|
| const base::Callback<T>& cb) {
|
| return BindToLoop(base::MessageLoopProxy::current(), cb);
|
|
|