Index: media/base/bind_to_current_loop.h |
diff --git a/media/base/bind_to_current_loop.h b/media/base/bind_to_current_loop.h |
index b7c90f6d757ac3feee07d19366be6f81fb42bcd8..cf1c44594b2209fa12b5510d5ebbe57bd5e24111 100644 |
--- a/media/base/bind_to_current_loop.h |
+++ b/media/base/bind_to_current_loop.h |
@@ -25,17 +25,29 @@ |
namespace media { |
namespace internal { |
-// First, tell the compiler TrampolineHelper is a struct template with one |
-// type parameter. Then define specializations where the type is a function |
-// returning void and taking zero or more arguments. |
-template <typename Signature> |
-class TrampolineHelper; |
+inline base::OnceClosure MakeClosure(base::RepeatingClosure* callback) { |
+ return *callback; |
+} |
-template <typename... Args> |
-class TrampolineHelper<void(Args...)> { |
- public: |
- using CallbackType = base::Callback<void(Args...)>; |
+inline base::OnceClosure MakeClosure(base::OnceClosure* callback) { |
+ return std::move(*callback); |
+} |
+template <typename Signature, typename... Args> |
+base::OnceClosure MakeClosure(base::RepeatingCallback<Signature>* callback, |
+ Args&&... args) { |
+ return base::BindOnce(*callback, std::forward<Args>(args)...); |
+} |
+ |
+template <typename Signature, typename... Args> |
+base::OnceClosure MakeClosure(base::OnceCallback<Signature>* callback, |
+ Args&&... args) { |
+ return base::BindOnce(std::move(*callback), std::forward<Args>(args)...); |
+} |
+ |
+template <typename CallbackType> |
+class TrampolineHelper { |
+ public: |
TrampolineHelper(const tracked_objects::Location& posted_from, |
scoped_refptr<base::SequencedTaskRunner> task_runner, |
CallbackType callback) |
@@ -46,48 +58,54 @@ class TrampolineHelper<void(Args...)> { |
DCHECK(callback_); |
} |
- inline void Run(Args... args); |
+ template <typename... Args> |
+ void Run(Args... args) { |
+ // MakeClosure consumes |callback_| if it's OnceCallback. |
+ task_runner_->PostTask( |
+ posted_from_, MakeClosure(&callback_, std::forward<Args>(args)...)); |
+ } |
~TrampolineHelper() { |
- task_runner_->PostTask( |
- posted_from_, |
- base::Bind(&TrampolineHelper::ClearCallbackOnTargetTaskRunner, |
- base::Passed(&callback_))); |
+ if (callback_) { |
+ task_runner_->PostTask( |
+ posted_from_, |
+ base::BindOnce(&TrampolineHelper::ClearCallbackOnTargetTaskRunner, |
+ std::move(callback_))); |
+ } |
} |
private: |
static void ClearCallbackOnTargetTaskRunner(CallbackType) {} |
- static void RunOnceClosure(base::OnceClosure cb) { std::move(cb).Run(); } |
tracked_objects::Location posted_from_; |
scoped_refptr<base::SequencedTaskRunner> task_runner_; |
CallbackType callback_; |
}; |
-template <> |
-inline void TrampolineHelper<void()>::Run() { |
- task_runner_->PostTask(posted_from_, callback_); |
-} |
+} // namespace internal |
template <typename... Args> |
-inline void TrampolineHelper<void(Args...)>::Run(Args... args) { |
- // TODO(tzik): Use OnceCallback directly without RunOnceClosure, once |
- // TaskRunner::PostTask migrates to OnceClosure. |
- base::OnceClosure cb = base::BindOnce(callback_, std::forward<Args>(args)...); |
- task_runner_->PostTask( |
- posted_from_, |
- base::Bind(&TrampolineHelper::RunOnceClosure, base::Passed(&cb))); |
+inline base::RepeatingCallback<void(Args...)> BindToCurrentLoop( |
+ base::RepeatingCallback<void(Args...)> cb) { |
+ using CallbackType = base::RepeatingCallback<void(Args...)>; |
+ using Helper = internal::TrampolineHelper<CallbackType>; |
+ using RunnerType = void (Helper::*)(Args...); |
+ RunnerType run = &Helper::Run; |
+ return base::BindRepeating( |
+ run, base::MakeUnique<Helper>( |
+ FROM_HERE, base::ThreadTaskRunnerHandle::Get(), std::move(cb))); |
xhwang
2017/05/11 18:29:02
Do we still need the old TODO here?
// TODO(tzik)
tzik
2017/05/12 04:05:54
Done.
|
} |
-} // namespace internal |
- |
-template <typename T> |
-inline base::Callback<T> BindToCurrentLoop(base::Callback<T> cb) { |
- return base::Bind( |
- &internal::TrampolineHelper<T>::Run, |
- base::MakeUnique<internal::TrampolineHelper<T>>( |
- FROM_HERE, // TODO(tzik): Propagate FROM_HERE from the caller. |
- base::ThreadTaskRunnerHandle::Get(), std::move(cb))); |
+template <typename... Args> |
+inline base::OnceCallback<void(Args...)> BindToCurrentLoop( |
+ base::OnceCallback<void(Args...)> cb) { |
+ using CallbackType = base::OnceCallback<void(Args...)>; |
+ using Helper = internal::TrampolineHelper<CallbackType>; |
+ using RunnerType = void (Helper::*)(Args...); |
+ RunnerType run = &Helper::Run; |
+ return base::BindOnce( |
+ run, base::MakeUnique<Helper>( |
+ FROM_HERE, base::ThreadTaskRunnerHandle::Get(), std::move(cb))); |
} |
} // namespace media |