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..367d540222e80da2aad95271aa6eb774ac34cbe2 100644 |
--- a/media/base/bind_to_current_loop.h |
+++ b/media/base/bind_to_current_loop.h |
@@ -6,6 +6,7 @@ |
#define MEDIA_BASE_BIND_TO_CURRENT_LOOP_H_ |
#include <memory> |
+#include <utility> |
#include "base/bind.h" |
#include "base/location.h" |
@@ -57,7 +58,6 @@ class TrampolineHelper<void(Args...)> { |
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_; |
@@ -71,16 +71,73 @@ inline void TrampolineHelper<void()>::Run() { |
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))); |
+ task_runner_->PostTask(posted_from_, std::move(cb)); |
+} |
+ |
+// First, tell the compiler OnceTrampolineHelper 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 OnceTrampolineHelper; |
+ |
+template <typename... Args> |
+class OnceTrampolineHelper<void(Args...)> { |
+ public: |
+ using CallbackType = base::OnceCallback<void(Args...)>; |
+ |
+ OnceTrampolineHelper(const tracked_objects::Location& posted_from, |
+ scoped_refptr<base::SequencedTaskRunner> task_runner, |
+ CallbackType callback) |
+ : posted_from_(posted_from), |
+ task_runner_(std::move(task_runner)), |
+ callback_(std::move(callback)) { |
+ DCHECK(task_runner_); |
+ DCHECK(callback_); |
+ } |
+ |
+ inline void Run(Args... args); |
+ |
+ ~OnceTrampolineHelper() { |
+ if (callback_) { |
+ task_runner_->PostTask( |
+ posted_from_, |
+ base::BindOnce(&OnceTrampolineHelper::ClearCallbackOnTargetTaskRunner, |
+ std::move(callback_))); |
+ } |
+ } |
+ |
+ private: |
+ static void ClearCallbackOnTargetTaskRunner(CallbackType) {} |
+ |
+ tracked_objects::Location posted_from_; |
+ scoped_refptr<base::SequencedTaskRunner> task_runner_; |
+ CallbackType callback_; |
+}; |
+ |
+template <> |
+inline void OnceTrampolineHelper<void()>::Run() { |
+ task_runner_->PostTask(posted_from_, std::move(callback_)); |
+} |
+ |
+template <typename... Args> |
+inline void OnceTrampolineHelper<void(Args...)>::Run(Args... args) { |
+ base::OnceClosure cb = |
+ base::BindOnce(std::move(callback_), std::forward<Args>(args)...); |
+ task_runner_->PostTask(posted_from_, std::move(cb)); |
} |
} // namespace internal |
+template <typename T> |
+inline base::OnceCallback<T> BindToCurrentLoop(base::OnceCallback<T> cb) { |
+ return base::BindOnce( |
+ &internal::OnceTrampolineHelper<T>::Run, |
+ base::MakeUnique<internal::OnceTrampolineHelper<T>>( |
+ FROM_HERE, // TODO(tzik): Propagate FROM_HERE from the caller. |
+ base::ThreadTaskRunnerHandle::Get(), std::move(cb))); |
+} |
+ |
template <typename T> |
inline base::Callback<T> BindToCurrentLoop(base::Callback<T> cb) { |
return base::Bind( |