Remove unnecessary copies from AsyncInvoke
Currently, the way the AsyncInvoke is implemented, the lambda invoked is copied multiple times. This causes two problems: (1) a reduced performance where captured variables are copied unnecessarily, (2) lambdas with non-copyable captures are not possible to invoke.
This cl attempts to address both points.
Change-Id: I8d907287d6e4851330d469f184760d165fa8bc08
Bug: webrtc:9028
Reviewed-on: https://webrtc-review.googlesource.com/61346
Commit-Queue: Tommi <tommi@webrtc.org>
Reviewed-by: Tommi <tommi@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#22471}
diff --git a/rtc_base/asyncinvoker.h b/rtc_base/asyncinvoker.h
index 523e9a9..74e8689 100644
--- a/rtc_base/asyncinvoker.h
+++ b/rtc_base/asyncinvoker.h
@@ -97,10 +97,11 @@
template <class ReturnT, class FunctorT>
void AsyncInvoke(const Location& posted_from,
Thread* thread,
- const FunctorT& functor,
+ FunctorT&& functor,
uint32_t id = 0) {
std::unique_ptr<AsyncClosure> closure(
- new FireAndForgetAsyncClosure<FunctorT>(this, functor));
+ new FireAndForgetAsyncClosure<FunctorT>(
+ this, std::forward<FunctorT>(functor)));
DoInvoke(posted_from, thread, std::move(closure), id);
}
@@ -109,11 +110,12 @@
template <class ReturnT, class FunctorT>
void AsyncInvokeDelayed(const Location& posted_from,
Thread* thread,
- const FunctorT& functor,
+ FunctorT&& functor,
uint32_t delay_ms,
uint32_t id = 0) {
std::unique_ptr<AsyncClosure> closure(
- new FireAndForgetAsyncClosure<FunctorT>(this, functor));
+ new FireAndForgetAsyncClosure<FunctorT>(
+ this, std::forward<FunctorT>(functor)));
DoInvokeDelayed(posted_from, thread, std::move(closure), delay_ms, id);
}
@@ -188,12 +190,13 @@
// immediately. Returns false if the thread has died.
template <class ReturnT, class FunctorT>
bool AsyncInvoke(const Location& posted_from,
- const FunctorT& functor,
+ FunctorT&& functor,
uint32_t id = 0) {
CritScope cs(&crit_);
if (thread_ == nullptr)
return false;
- invoker_.AsyncInvoke<ReturnT, FunctorT>(posted_from, thread_, functor, id);
+ invoker_.AsyncInvoke<ReturnT, FunctorT>(
+ posted_from, thread_, std::forward<FunctorT>(functor), id);
return true;
}
@@ -201,14 +204,14 @@
// completion. Returns immediately. Returns false if the thread has died.
template <class ReturnT, class FunctorT>
bool AsyncInvokeDelayed(const Location& posted_from,
- const FunctorT& functor,
+ FunctorT&& functor,
uint32_t delay_ms,
uint32_t id = 0) {
CritScope cs(&crit_);
if (thread_ == nullptr)
return false;
- invoker_.AsyncInvokeDelayed<ReturnT, FunctorT>(posted_from, thread_,
- functor, delay_ms, id);
+ invoker_.AsyncInvokeDelayed<ReturnT, FunctorT>(
+ posted_from, thread_, std::forward<FunctorT>(functor), delay_ms, id);
return true;
}
@@ -217,7 +220,7 @@
template <class ReturnT, class FunctorT, class HostT>
bool AsyncInvoke(const Location& posted_from,
const Location& callback_posted_from,
- const FunctorT& functor,
+ FunctorT&& functor,
void (HostT::*callback)(ReturnT),
HostT* callback_host,
uint32_t id = 0) {
@@ -225,8 +228,8 @@
if (thread_ == nullptr)
return false;
invoker_.AsyncInvoke<ReturnT, FunctorT, HostT>(
- posted_from, callback_posted_from, thread_, functor, callback,
- callback_host, id);
+ posted_from, callback_posted_from, thread_,
+ std::forward<FunctorT>(functor), callback, callback_host, id);
return true;
}
@@ -235,7 +238,7 @@
template <class ReturnT, class FunctorT, class HostT>
bool AsyncInvoke(const Location& posted_from,
const Location& callback_posted_from,
- const FunctorT& functor,
+ FunctorT&& functor,
void (HostT::*callback)(),
HostT* callback_host,
uint32_t id = 0) {
@@ -243,8 +246,8 @@
if (thread_ == nullptr)
return false;
invoker_.AsyncInvoke<ReturnT, FunctorT, HostT>(
- posted_from, callback_posted_from, thread_, functor, callback,
- callback_host, id);
+ posted_from, callback_posted_from, thread_,
+ std::forward<FunctorT>(functor), callback, callback_host, id);
return true;
}