Commit 940c095e authored by Giuseppe Ottaviano's avatar Giuseppe Ottaviano Committed by Facebook GitHub Bot

Type-erase setCallback

Summary:
`setCallback()` functions just store the argument as a `Function`, so we don't need to specialize the templates all the way down, we can pass directly a `Function`.

This reduces code size, and should not have runtime impact: either the move is elided in both cases, or if not there's no particular reason why a `Function` move should be more expensive than an arbitrary functor's (could even be faster).

Reviewed By: yfeldblum, luciang

Differential Revision: D20561695

fbshipit-source-id: 1973c47a5410a43eb44beea36cb1105663094eb3
parent e7b465ec
...@@ -309,13 +309,12 @@ void FutureBase<T>::raise(exception_wrapper exception) { ...@@ -309,13 +309,12 @@ void FutureBase<T>::raise(exception_wrapper exception) {
} }
template <class T> template <class T>
template <class F>
void FutureBase<T>::setCallback_( void FutureBase<T>::setCallback_(
F&& func, CoreCallback&& func,
futures::detail::InlineContinuation allowInline) { futures::detail::InlineContinuation allowInline) {
throwIfContinued(); throwIfContinued();
getCore().setCallback( getCore().setCallback(
std::forward<F>(func), RequestContext::saveContext(), allowInline); std::move(func), RequestContext::saveContext(), allowInline);
} }
template <class T> template <class T>
......
...@@ -120,6 +120,10 @@ namespace futures { ...@@ -120,6 +120,10 @@ namespace futures {
namespace detail { namespace detail {
template <class T> template <class T>
class FutureBase { class FutureBase {
protected:
using Core = futures::detail::Core<T>;
using CoreCallback = typename Core::Callback;
public: public:
typedef T value_type; typedef T value_type;
...@@ -265,8 +269,9 @@ class FutureBase { ...@@ -265,8 +269,9 @@ class FutureBase {
/// This needs to be public because it's used by make* and when*, and it's /// This needs to be public because it's used by make* and when*, and it's
/// not worth listing all those and their fancy template signatures as /// not worth listing all those and their fancy template signatures as
/// friends. But it's not for public consumption. /// friends. But it's not for public consumption.
template <class F> void setCallback_(
void setCallback_(F&& func, InlineContinuation = InlineContinuation::forbid); CoreCallback&& func,
InlineContinuation = InlineContinuation::forbid);
/// Provides a threadsafe back-channel so the consumer's thread can send an /// Provides a threadsafe back-channel so the consumer's thread can send an
/// interrupt-object to the producer's thread. /// interrupt-object to the producer's thread.
...@@ -357,8 +362,6 @@ class FutureBase { ...@@ -357,8 +362,6 @@ class FutureBase {
template <class> template <class>
friend class Future; friend class Future;
using Core = futures::detail::Core<T>;
// Throws FutureInvalid if there is no shared state object; else returns it // Throws FutureInvalid if there is no shared state object; else returns it
// by ref. // by ref.
// //
......
...@@ -579,14 +579,13 @@ class Core final { ...@@ -579,14 +579,13 @@ class Core final {
/// If it transitions to Done, synchronously initiates a call to the callback, /// If it transitions to Done, synchronously initiates a call to the callback,
/// and might also synchronously execute that callback (e.g., if there is no /// and might also synchronously execute that callback (e.g., if there is no
/// executor or if the executor is inline). /// executor or if the executor is inline).
template <typename F>
void setCallback( void setCallback(
F&& func, Callback&& func,
std::shared_ptr<folly::RequestContext>&& context, std::shared_ptr<folly::RequestContext>&& context,
futures::detail::InlineContinuation allowInline) { futures::detail::InlineContinuation allowInline) {
DCHECK(!hasCallback()); DCHECK(!hasCallback());
::new (&callback_) Callback(std::forward<F>(func)); ::new (&callback_) Callback(std::move(func));
::new (&context_) Context(std::move(context)); ::new (&context_) Context(std::move(context));
auto state = state_.load(std::memory_order_acquire); auto state = state_.load(std::memory_order_acquire);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment