proxygen
folly::SemiFuture< T > Class Template Reference

#include <Future-pre.h>

Inheritance diagram for folly::SemiFuture< T >:
folly::futures::detail::FutureBase< T >

Public Types

typedef T value_type
 

Public Member Functions

 ~SemiFuture ()
 
template<class T2 = T, typename = typename std::enable_if< !isFuture<typename std::decay<T2>::type>::value && !isSemiFuture<typename std::decay<T2>::type>::value>::type>
 SemiFuture (T2 &&val)
 
template<class T2 = T>
 SemiFuture (typename std::enable_if< std::is_same< Unit, T2 >::value >::type *p=nullptr)
 
template<class... Args, typename std::enable_if< std::is_constructible< T, Args &&... >::value, int >::type = 0>
 SemiFuture (in_place_t, Args &&...args)
 
 SemiFuture (SemiFuture< T > const &)=delete
 
 SemiFuture (SemiFuture< T > &&) noexcept
 
 SemiFuture (Future< T > &&) noexcept
 
SemiFutureoperator= (SemiFuture const &)=delete
 
SemiFutureoperator= (SemiFuture &&) noexcept
 
SemiFutureoperator= (Future< T > &&) noexcept
 
T get ()&&
 
T get ()&=delete
 
T get (Duration dur)&&
 
T get (Duration dur)&=delete
 
Try< TgetTry ()&&
 
Try< TgetTry (Duration dur)&&
 
SemiFuture< T > & wait ()&
 
SemiFuture< T > && wait ()&&
 
bool wait (Duration dur)&&
 
Future< Tvia (Executor *executor, int8_t priority=Executor::MID_PRI)&&
 Returns a Future which will call back on the other side of executor. More...
 
Future< Tvia (Executor::KeepAlive<> executor, int8_t priority=Executor::MID_PRI)&&
 
template<typename F >
SemiFuture< typename futures::detail::tryCallableResult< T, F >::value_typedefer (F &&func)&&
 
template<typename R , typename... Args>
auto defer (R(&func)(Args...))&&
 
template<typename F >
SemiFuture< typename futures::detail::valueCallableResult< T, F >::value_typedeferValue (F &&func)&&
 
template<typename R , typename... Args>
auto deferValue (R(&func)(Args...))&&
 
template<class ExceptionType , class F >
SemiFuture< TdeferError (F &&func)&&
 
template<class ExceptionType , class R , class... Args>
SemiFuture< TdeferError (R(&func)(Args...))&&
 
template<class F >
SemiFuture< TdeferError (F &&func)&&
 
template<class R , class... Args>
SemiFuture< TdeferError (R(&func)(Args...))&&
 
SemiFuture< Twithin (Duration dur, Timekeeper *tk=nullptr)&&
 
template<class E >
SemiFuture< Twithin (Duration dur, E e, Timekeeper *tk=nullptr)&&
 
SemiFuture< Tdelayed (Duration dur, Timekeeper *tk=nullptr)&&
 
Future< TtoUnsafeFuture ()&&
 

Static Public Member Functions

static SemiFuture< TmakeEmpty ()
 

Private Types

using Base = futures::detail::FutureBase< T >
 
using DeferredExecutor = futures::detail::DeferredExecutor
 
using TimePoint = std::chrono::system_clock::time_point
 
using Core = futures::detail::Core< T >
 
- Private Types inherited from folly::futures::detail::FutureBase< T >
typedef T value_type
 
using Core = futures::detail::Core< T >
 

Private Member Functions

 SemiFuture (Core *obj)
 
 SemiFuture (futures::detail::EmptyConstruct) noexcept
 
DeferredExecutorgetDeferredExecutor () const
 
folly::Executor::KeepAlive< DeferredExecutorstealDeferredExecutor () const
 
SemiFuture< T > & wait (Duration dur)&
 
- Private Member Functions inherited from folly::futures::detail::FutureBase< T >
template<class T2 = T, typename = typename std::enable_if< !isFuture<typename std::decay<T2>::type>::value && !isSemiFuture<typename std::decay<T2>::type>::value>::type>
 FutureBase (T2 &&val)
 
template<class T2 = T>
 FutureBase (typename std::enable_if< std::is_same< Unit, T2 >::value >::type *)
 
template<class... Args, typename std::enable_if< std::is_constructible< T, Args &&... >::value, int >::type = 0>
 FutureBase (in_place_t, Args &&...args)
 
 FutureBase (FutureBase< T > const &)=delete
 
 FutureBase (SemiFuture< T > &&) noexcept
 
 FutureBase (Future< T > &&) noexcept
 
 FutureBase (Future< T > const &)=delete
 
 FutureBase (SemiFuture< T > const &)=delete
 
 ~FutureBase ()
 
bool valid () const noexcept
 
Tvalue ()&
 
T const & value () const &
 
T && value ()&&
 
T const && value () const &&
 
Try< T > & result ()&
 
Try< T > const & result () const &
 
Try< T > && result ()&&
 
Try< T > const && result () const &&
 
bool isReady () const
 
bool hasValue () const
 
bool hasException () const
 
Optional< Try< T > > poll ()
 
template<class F >
void setCallback_ (F &&func)
 
template<class F >
void setCallback_ (F &&func, std::shared_ptr< folly::RequestContext > context)
 
void raise (exception_wrapper interrupt)
 
template<class E >
void raise (E &&exception)
 
void cancel ()
 
int8_t getPriority () const
 
CoregetCore ()
 
Core const & getCore () const
 
Try< T > & getCoreTryChecked ()
 
Try< T > const & getCoreTryChecked () const
 
 FutureBase (Core *obj)
 
 FutureBase (futures::detail::EmptyConstruct) noexcept
 
void detach ()
 
void throwIfInvalid () const
 
void throwIfContinued () const
 
void assign (FutureBase< T > &&other) noexcept
 
ExecutorgetExecutor () const
 
void setExecutor (Executor *x, int8_t priority=Executor::MID_PRI)
 
void setExecutor (Executor::KeepAlive<> x, int8_t priority=Executor::MID_PRI)
 
template<typename F , typename R >
std::enable_if<!R::ReturnsFuture::value, typename R::Return >::type thenImplementation (F &&func, R)
 
template<typename F , typename R >
std::enable_if< R::ReturnsFuture::value, typename R::Return >::type thenImplementation (F &&func, R)
 
template<typename E >
SemiFuture< TwithinImplementation (Duration dur, E e, Timekeeper *tk)&&
 

Static Private Member Functions

static void releaseDeferredExecutor (Core *core)
 
- Static Private Member Functions inherited from folly::futures::detail::FutureBase< T >
template<typename Self >
static decltype(auto) getCoreImpl (Self &self)
 
template<typename Self >
static decltype(auto) getCoreTryChecked (Self &self)
 

Friends

class Promise< T >
 
template<class >
class futures::detail::FutureBase
 
template<class >
class SemiFuture
 
template<class >
class Future
 
folly::Executor::KeepAlive< DeferredExecutorfutures::detail::stealDeferredExecutor (SemiFuture &)
 
DeferredExecutorfutures::detail::getDeferredExecutor (SemiFuture &)
 
template<class T2 >
SemiFuture< T2makeSemiFuture (Try< T2 >)
 

Additional Inherited Members

- Private Attributes inherited from folly::futures::detail::FutureBase< T >
Corecore_
 

Detailed Description

template<class T>
class folly::SemiFuture< T >

The interface (along with Future) for the consumer-side of a producer/consumer pair.

Future vs. SemiFuture:

  • The consumer-side should generally start with a SemiFuture, not a Future.
  • Example, when a library creates and returns a future, it should usually return a SemiFuture, not a Future.
  • Reason: so the thread policy for continuations (.thenValue, etc.) can be specified by the library's caller (using .via()).
  • A SemiFuture is converted to a Future using .via().
  • Use makePromiseContract() when creating both a Promise and an associated SemiFuture/Future.

When practical, prefer SemiFuture/Future's nonblocking style/pattern:

  • the nonblocking style uses continuations, e.g., .thenValue, etc.; the continuations are deferred until the result is available.
  • the blocking style blocks until complete, e.g., .wait(), .get(), etc.
  • the two styles cannot be mixed within the same future; use one or the other.

SemiFuture/Future also provide a back-channel so an interrupt can be sent from consumer to producer; see SemiFuture/Future's raise() and Promise's setInterruptHandler().

The consumer-side SemiFuture/Future objects should generally be accessed via a single thread. That thread is referred to as the 'consumer thread.'

Definition at line 26 of file Future-pre.h.

Member Typedef Documentation

template<class T>
using folly::SemiFuture< T >::Base = futures::detail::FutureBase<T>
private

Definition at line 490 of file Future.h.

template<class T>
using folly::futures::detail::FutureBase< T >::Core = futures::detail::Core<T>
private

Definition at line 359 of file Future.h.

Definition at line 491 of file Future.h.

template<class T>
using folly::SemiFuture< T >::TimePoint = std::chrono::system_clock::time_point
private

Definition at line 492 of file Future.h.

template<class T>
typedef T folly::futures::detail::FutureBase< T >::value_type

Definition at line 117 of file Future.h.

Constructor & Destructor Documentation

template<class T >
folly::SemiFuture< T >::~SemiFuture ( )

Definition at line 815 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::core_.

815  {
817 }
static void releaseDeferredExecutor(Core *core)
Definition: Future-inl.h:803
template<class T>
template<class T2 = T, typename = typename std::enable_if< !isFuture<typename std::decay<T2>::type>::value && !isSemiFuture<typename std::decay<T2>::type>::value>::type>
folly::SemiFuture< T >::SemiFuture ( T2 &&  val)
inline

Construct a SemiFuture from a value (perfect forwarding)

Postconditions:

Definition at line 521 of file Future.h.

521 : Base(std::forward<T2>(val)) {}
futures::detail::FutureBase< T > Base
Definition: Future.h:490
template<class T>
template<class T2 = T>
folly::SemiFuture< T >::SemiFuture ( typename std::enable_if< std::is_same< Unit, T2 >::value >::type p = nullptr)
inline

Construct a (logical) SemiFuture-of-void.

Postconditions:

Definition at line 531 of file Future.h.

References testing::Args(), folly::T, type, and folly::value().

533  : Base(p) {}
futures::detail::FutureBase< T > Base
Definition: Future.h:490
template<class T>
template<class... Args, typename std::enable_if< std::is_constructible< T, Args &&... >::value, int >::type = 0>
folly::SemiFuture< T >::SemiFuture ( in_place_t  ,
Args &&...  args 
)
inlineexplicit

Construct a SemiFuture from a T constructed from args

Postconditions:

Definition at line 548 of file Future.h.

References testing::Args(), folly::pushmi::operators::defer, folly::pushmi::executor, int8_t, folly::Executor::MID_PRI, folly::pushmi::__adl::noexcept(), folly::netops::poll(), value, folly::via(), and folly::detail::distributed_mutex::wait().

549  : Base(in_place, std::forward<Args>(args)...) {}
futures::detail::FutureBase< T > Base
Definition: Future.h:490
in_place_tag in_place(in_place_tag={})
Definition: Utility.h:235
template<class T>
folly::SemiFuture< T >::SemiFuture ( SemiFuture< T > const &  )
delete
template<class T >
folly::SemiFuture< T >::SemiFuture ( SemiFuture< T > &&  other)
noexcept

Definition at line 820 of file Future-inl.h.

821  : futures::detail::FutureBase<T>(std::move(other)) {}
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T >
folly::SemiFuture< T >::SemiFuture ( Future< T > &&  other)
noexcept

Definition at line 824 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::core_, and folly::futures::detail::FutureBase< T >::setExecutor().

825  : futures::detail::FutureBase<T>(std::move(other)) {
826  // SemiFuture should not have an executor on construction
827  if (this->core_) {
828  this->setExecutor(nullptr);
829  }
830 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
void setExecutor(Executor *x, int8_t priority=Executor::MID_PRI)
Definition: Future.h:420
template<class T>
folly::SemiFuture< T >::SemiFuture ( Core obj)
inlineexplicitprivate

Definition at line 897 of file Future.h.

897 : Base(obj) {}
futures::detail::FutureBase< T > Base
Definition: Future.h:490
template<class T>
folly::SemiFuture< T >::SemiFuture ( futures::detail::EmptyConstruct  )
inlineexplicitprivatenoexcept

Definition at line 899 of file Future.h.

References folly::futures::detail::getDeferredExecutor(), folly::futures::detail::stealDeferredExecutor(), and folly::detail::distributed_mutex::wait().

900  : Base(futures::detail::EmptyConstruct{}) {}
futures::detail::FutureBase< T > Base
Definition: Future.h:490

Member Function Documentation

template<class T >
template<typename F >
SemiFuture< typename futures::detail::tryCallableResult< T, F >::value_type > folly::SemiFuture< T >::defer ( F &&  func)

Defer work to run on the consumer of the future. Function must take a Try as a parameter. This work will be run either on an executor that the caller sets on the SemiFuture, or inline with the call to .get().

NB: This is a custom method because boost-blocking executors is a special-case for work deferral in folly. With more general boost-blocking support all executors would boost block and we would simply use some form of driveable executor here.

Preconditions:

Postconditions:

  • valid() == false
  • RESULT.valid() == true

Definition at line 882 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::core_, folly::futures::detail::DeferredExecutor::create(), folly::futures::detail::getDeferredExecutor(), folly::gen::move, folly::futures::detail::FutureBase< T >::setExecutor(), and folly::futures::detail::Core< T >::setExecutor().

882  {
883  DeferredExecutor* deferredExecutor = getDeferredExecutor();
884  if (!deferredExecutor) {
885  auto newDeferredExecutor = DeferredExecutor::create();
886  deferredExecutor = newDeferredExecutor.get();
887  this->setExecutor(std::move(newDeferredExecutor));
888  }
889 
890  auto sf = Future<T>(this->core_).thenTry(std::forward<F>(func)).semi();
891  this->core_ = nullptr;
892  // Carry deferred executor through chain as constructor from Future will
893  // nullify it
894  sf.setExecutor(deferredExecutor);
895  return sf;
896 }
futures::detail::DeferredExecutor DeferredExecutor
Definition: Future.h:491
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static KeepAlive< DeferredExecutor > create()
Definition: Future-inl.h:578
DeferredExecutor * getDeferredExecutor() const
Definition: Future-inl.h:780
void setExecutor(Executor::KeepAlive<> x, int8_t priority=Executor::MID_PRI)
Definition: Core.h:424
void setExecutor(Executor *x, int8_t priority=Executor::MID_PRI)
Definition: Future.h:420
template<class T>
template<typename R , typename... Args>
auto folly::SemiFuture< T >::defer ( R(&)(Args...)  func)
inline

Definition at line 701 of file Future.h.

References testing::Args(), and folly::gen::move.

701  {
702  return std::move(*this).defer(&func);
703  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T >
template<class ExceptionType , class F >
SemiFuture< T > folly::SemiFuture< T >::deferError ( F &&  func)

Set an error continuation for this SemiFuture where the continuation can be called with a known exception type and returns a T, Future<T>, or SemiFuture<T>.

Example:

.defer([] {
throw std::runtime_error("oh no!");
return 42;
})
.deferError<std::runtime_error>([] (auto const& e) {
LOG(INFO) << "std::runtime_error: " << e.what();
return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1)
});

Preconditions:

Postconditions:

  • valid() == false
  • RESULT.valid() == true

Definition at line 913 of file Future-inl.h.

References folly::gen::move, and folly::pushmi::detail::t.

913  {
914  return std::move(*this).defer(
915  [func = std::forward<F>(func)](Try<T>&& t) mutable {
916  if (auto e = t.template tryGetExceptionObject<ExceptionType>()) {
917  return makeSemiFutureWith(
918  [&]() mutable { return std::forward<F>(func)(*e); });
919  } else {
920  return makeSemiFuture<T>(std::move(t));
921  }
922  });
923 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T>
template<class ExceptionType , class R , class... Args>
SemiFuture<T> folly::SemiFuture< T >::deferError ( R(&)(Args...)  func)
inline

Definition at line 754 of file Future.h.

References testing::Args(), and folly::gen::move.

754  {
755  return std::move(*this).template deferError<ExceptionType>(&func);
756  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T >
template<class F >
SemiFuture< T > folly::SemiFuture< T >::deferError ( F &&  func)

Set an error continuation for this SemiFuture where the continuation can be called with exception_wrapper&& and returns a T, Future<T>, or SemiFuture<T>.

Example:

makeSemiFuture() .defer([] { throw std::runtime_error("oh no!"); return 42; }) .deferError([] (exception_wrapper&& e) { LOG(INFO) << e.what(); return -1; // or makeFuture<int>(-1) or makeSemiFuture<int>(-1) });

Preconditions:

Postconditions:

  • valid() == false
  • RESULT.valid() == true

Definition at line 927 of file Future-inl.h.

References folly::gen::move, and folly::pushmi::detail::t.

927  {
928  return std::move(*this).defer(
929  [func = std::forward<F>(func)](Try<T> t) mutable {
930  if (t.hasException()) {
931  return makeSemiFutureWith([&]() mutable {
932  return std::forward<F>(func)(std::move(t.exception()));
933  });
934  } else {
935  return makeSemiFuture<T>(std::move(t));
936  }
937  });
938 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T>
template<class R , class... Args>
SemiFuture<T> folly::SemiFuture< T >::deferError ( R(&)(Args...)  func)
inline

Definition at line 786 of file Future.h.

References folly::gen::move.

786  {
787  return std::move(*this).deferError(&func);
788  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T >
template<typename F >
SemiFuture< typename futures::detail::valueCallableResult< T, F >::value_type > folly::SemiFuture< T >::deferValue ( F &&  func)

Defer for functions taking a T rather than a Try<T>.

Preconditions:

Postconditions:

  • valid() == false
  • RESULT.valid() == true

Definition at line 901 of file Future-inl.h.

References f, folly::gen::move, and folly::pushmi::detail::t.

901  {
902  return std::move(*this).defer([f = std::forward<F>(func)](
903  folly::Try<T>&& t) mutable {
904  return std::forward<F>(f)(
905  t.template get<
906  false,
907  typename futures::detail::valueCallableResult<T, F>::FirstArg>());
908  });
909 }
auto f
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
Definition: Try.h:51
template<class T>
template<typename R , typename... Args>
auto folly::SemiFuture< T >::deferValue ( R(&)(Args...)  func)
inline

Definition at line 720 of file Future.h.

References testing::Args(), and folly::gen::move.

720  {
721  return std::move(*this).deferValue(&func);
722  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<typename T >
SemiFuture< T > folly::SemiFuture< T >::delayed ( Duration  dur,
Timekeeper tk = nullptr 
)

Delay the completion of this SemiFuture for at least this duration from now. The optional Timekeeper is as with futures::sleep().

Preconditions:

Postconditions:

  • valid() == false
  • RESULT.valid() == true

Definition at line 941 of file Future-inl.h.

References folly::collectAllSemiFuture(), folly::gen::move, folly::futures::sleep(), and folly::pushmi::detail::t.

941  {
942  return collectAllSemiFuture(*this, futures::sleep(dur, tk))
943  .toUnsafeFuture()
944  .thenValue([](std::tuple<Try<T>, Try<Unit>> tup) {
945  Try<T>& t = std::get<0>(tup);
946  return makeFuture<T>(std::move(t));
947  });
948 }
Future< Unit > sleep(Duration dur, Timekeeper *tk)
Definition: Future.cpp:42
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
SemiFuture< std::tuple< Try< typename remove_cvref_t< Fs >::value_type >... > > collectAllSemiFuture(Fs &&...fs)
Definition: Future-inl.h:1441
template<class T >
T folly::SemiFuture< T >::get ( )

Blocks until the promise is fulfilled, either by value (which is returned) or exception (which is thrown).

Preconditions:

  • valid() == true (else throws FutureInvalid)
  • must not have a continuation, e.g., via .thenValue() or similar

Postconditions:

Definition at line 2167 of file Future-inl.h.

References folly::gen::move.

2167  {
2168  return std::move(*this).getTry().value();
2169 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T>
T folly::SemiFuture< T >::get ( )
delete
template<class T >
T folly::SemiFuture< T >::get ( Duration  dur)

Blocks until the semifuture is fulfilled, or until dur elapses. Returns the value (moved-out), or throws the exception (which might be a FutureTimeout exception).

Preconditions:

Postconditions:

Definition at line 2172 of file Future-inl.h.

References folly::gen::move.

2172  {
2173  return std::move(*this).getTry(dur).value();
2174 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T>
T folly::SemiFuture< T >::get ( Duration  dur)
delete
template<class T >
SemiFuture< T >::DeferredExecutor * folly::SemiFuture< T >::getDeferredExecutor ( ) const
private

Definition at line 780 of file Future-inl.h.

References folly::pushmi::executor, and folly::futures::detail::FutureBase< T >::getExecutor().

Referenced by folly::futures::detail::getDeferredExecutor().

781  {
782  if (auto executor = this->getExecutor()) {
783  assert(dynamic_cast<DeferredExecutor*>(executor) != nullptr);
784  return static_cast<DeferredExecutor*>(executor);
785  }
786  return nullptr;
787 }
futures::detail::DeferredExecutor DeferredExecutor
Definition: Future.h:491
Executor * getExecutor() const
Definition: Future.h:412
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
template<class T >
Try< T > folly::SemiFuture< T >::getTry ( )

Blocks until the future is fulfilled. Returns the Try of the result (moved-out).

Preconditions:

Postconditions:

Definition at line 2177 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::core_, folly::Future< T >::getTry(), folly::gen::move, and folly::Future< T >::wait().

2177  {
2178  wait();
2179  auto future = folly::Future<T>(this->core_);
2180  this->core_ = nullptr;
2181  return std::move(std::move(future).getTry());
2182 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
SemiFuture< T > & wait()&
Definition: Future-inl.h:2106
Try< T > getTry()&&
Definition: Future-inl.h:2177
template<class T >
Try< T > folly::SemiFuture< T >::getTry ( Duration  dur)

Blocks until the future is fulfilled, or until dur elapses. Returns the Try of the result (moved-out), or throws FutureTimeout exception.

Preconditions:

Postconditions:

Definition at line 2185 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::core_, folly::Future< T >::getTry(), folly::gen::move, and folly::Future< T >::wait().

2185  {
2186  wait(dur);
2187  auto future = folly::Future<T>(this->core_);
2188  this->core_ = nullptr;
2189 
2190  if (!future.isReady()) {
2191  throw_exception<FutureTimeout>();
2192  }
2193  return std::move(std::move(future).getTry());
2194 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
SemiFuture< T > & wait()&
Definition: Future-inl.h:2106
Try< T > getTry()&&
Definition: Future-inl.h:2177
template<class T >
SemiFuture< T > folly::SemiFuture< T >::makeEmpty ( )
static

Creates/returns an invalid SemiFuture, that is, one with no shared state.

Postcondition:

  • RESULT.valid() == false

Definition at line 775 of file Future-inl.h.

Referenced by TEST().

775  {
776  return SemiFuture<T>(futures::detail::EmptyConstruct{});
777 }
template<class T>
SemiFuture& folly::SemiFuture< T >::operator= ( SemiFuture< T > const &  )
delete
template<class T >
SemiFuture< T > & folly::SemiFuture< T >::operator= ( SemiFuture< T > &&  other)
noexcept

Definition at line 833 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::assign(), folly::futures::detail::FutureBase< T >::core_, and folly::gen::move.

833  {
835  this->assign(std::move(other));
836  return *this;
837 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static void releaseDeferredExecutor(Core *core)
Definition: Future-inl.h:803
void assign(FutureBase< T > &&other) noexcept
Definition: Future-inl.h:167
template<class T >
SemiFuture< T > & folly::SemiFuture< T >::operator= ( Future< T > &&  other)
noexcept

Definition at line 840 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::assign(), folly::futures::detail::FutureBase< T >::core_, folly::gen::move, and folly::futures::detail::FutureBase< T >::setExecutor().

840  {
842  this->assign(std::move(other));
843  // SemiFuture should not have an executor on construction
844  if (this->core_) {
845  this->setExecutor(nullptr);
846  }
847  return *this;
848 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static void releaseDeferredExecutor(Core *core)
Definition: Future-inl.h:803
void assign(FutureBase< T > &&other) noexcept
Definition: Future-inl.h:167
void setExecutor(Executor *x, int8_t priority=Executor::MID_PRI)
Definition: Future.h:420
template<class T >
void folly::SemiFuture< T >::releaseDeferredExecutor ( Core core)
staticprivate

Definition at line 803 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::detach(), folly::pushmi::executor, folly::futures::detail::Core< T >::getExecutor(), and folly::futures::detail::Core< T >::setExecutor().

803  {
804  if (!core) {
805  return;
806  }
807  if (auto executor = core->getExecutor()) {
808  assert(dynamic_cast<DeferredExecutor*>(executor) != nullptr);
809  static_cast<DeferredExecutor*>(executor)->detach();
810  core->setExecutor(nullptr);
811  }
812 }
futures::detail::DeferredExecutor DeferredExecutor
Definition: Future.h:491
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
template<class T >
folly::Executor::KeepAlive< typename SemiFuture< T >::DeferredExecutor > folly::SemiFuture< T >::stealDeferredExecutor ( ) const
private

Definition at line 791 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::core_, folly::pushmi::executor, folly::futures::detail::FutureBase< T >::getExecutor(), folly::getKeepAliveToken(), and folly::futures::detail::Core< T >::setExecutor().

Referenced by folly::futures::detail::stealDeferredExecutor().

791  {
792  if (auto executor = this->getExecutor()) {
793  assert(dynamic_cast<DeferredExecutor*>(executor) != nullptr);
794  auto executorKeepAlive =
795  folly::getKeepAliveToken(static_cast<DeferredExecutor*>(executor));
796  this->core_->setExecutor(nullptr);
797  return executorKeepAlive;
798  }
799  return {};
800 }
Executor * getExecutor() const
Definition: Future.h:412
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
void setExecutor(Executor::KeepAlive<> x, int8_t priority=Executor::MID_PRI)
Definition: Core.h:424
Executor::KeepAlive< ExecutorT > getKeepAliveToken(ExecutorT *executor)
Definition: Executor.h:200
template<class T >
Future< T > folly::SemiFuture< T >::toUnsafeFuture ( )

Returns a future that completes inline, as if the future had no executor. Intended for porting legacy code without behavioral change, and for rare cases where this is really the intended behavior. Future is unsafe in the sense that the executor it completes on is non-deterministic in the standard case. For new code, or to update code that temporarily uses this, please use via and pass a meaningful executor.

Preconditions:

Postconditions:

  • valid() == false
  • RESULT.valid() == true

Definition at line 875 of file Future-inl.h.

References folly::InlineExecutor::instance(), and folly::gen::move.

875  {
876  return std::move(*this).via(&InlineExecutor::instance());
877 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
FOLLY_ATTR_VISIBILITY_HIDDEN static FOLLY_ALWAYS_INLINE InlineExecutor & instance() noexcept
template<class T >
Future< T > folly::SemiFuture< T >::via ( Executor executor,
int8_t  priority = Executor::MID_PRI 
)

Returns a Future which will call back on the other side of executor.

Definition at line 870 of file Future-inl.h.

References folly::pushmi::executor, folly::getKeepAliveToken(), and folly::gen::move.

870  {
871  return std::move(*this).via(getKeepAliveToken(executor), priority);
872 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
Executor::KeepAlive< ExecutorT > getKeepAliveToken(ExecutorT *executor)
Definition: Executor.h:200
template<class T >
Future< T > folly::SemiFuture< T >::via ( Executor::KeepAlive<>  executor,
int8_t  priority = Executor::MID_PRI 
)

Definition at line 851 of file Future-inl.h.

References folly::futures::detail::FutureBase< T >::core_, folly::pushmi::executor, folly::futures::detail::getDeferredExecutor(), folly::gen::move, and folly::futures::detail::Core< T >::setExecutor().

853  {
854  if (!executor) {
855  throw_exception<FutureNoExecutor>();
856  }
857 
858  if (auto deferredExecutor = getDeferredExecutor()) {
859  deferredExecutor->setExecutor(executor.copy());
860  }
861 
862  auto newFuture = Future<T>(this->core_);
863  this->core_ = nullptr;
864  newFuture.setExecutor(std::move(executor), priority);
865 
866  return newFuture;
867 }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
PUSHMI_INLINE_VAR constexpr __adl::get_executor_fn executor
DeferredExecutor * getDeferredExecutor() const
Definition: Future-inl.h:780
void setExecutor(Executor::KeepAlive<> x, int8_t priority=Executor::MID_PRI)
Definition: Core.h:424
template<class T >
SemiFuture< T > && folly::SemiFuture< T >::wait ( )

Blocks the caller's thread until this Future isReady(), i.e., until the asynchronous producer has stored a result or exception.

Preconditions:

Postconditions:

Definition at line 2106 of file Future-inl.h.

References folly::futures::detail::WaitExecutor::create(), folly::futures::detail::FutureBase< T >::detach(), folly::futures::detail::getDeferredExecutor(), folly::Promise< T >::getSemiFuture(), folly::gen::move, folly::futures::detail::FutureBase< T >::setCallback_(), folly::Future< T >::wait(), and folly::futures::detail::waitImpl().

Referenced by folly::SemiFuture< T >::wait().

2106  {
2107  if (auto deferredExecutor = getDeferredExecutor()) {
2108  // Make sure that the last callback in the future chain will be run on the
2109  // WaitExecutor.
2110  Promise<T> promise;
2111  auto ret = promise.getSemiFuture();
2112  setCallback_(
2113  [p = std::move(promise)](auto&& r) mutable { p.setTry(std::move(r)); });
2114  auto waitExecutor = futures::detail::WaitExecutor::create();
2115  deferredExecutor->setExecutor(waitExecutor.copy());
2116  while (!ret.isReady()) {
2117  waitExecutor->drive();
2118  }
2119  waitExecutor->detach();
2120  this->detach();
2121  *this = std::move(ret);
2122  } else {
2124  }
2125  return *this;
2126 }
void waitImpl(FutureType &f)
Definition: Future-inl.h:2004
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
DeferredExecutor * getDeferredExecutor() const
Definition: Future-inl.h:780
friend class Promise< T >
Definition: Future.h:879
static KeepAlive< WaitExecutor > create()
Definition: Future-inl.h:656
template<class T>
SemiFuture<T>&& folly::SemiFuture< T >::wait ( )

Blocks the caller's thread until this Future isReady(), i.e., until the asynchronous producer has stored a result or exception.

Preconditions:

Postconditions:

  • valid() == true (but the calling code can trivially move-out *this by assigning or constructing the result into a distinct object).
  • &RESULT == this
  • isReady() == true
template<class T >
bool folly::SemiFuture< T >::wait ( Duration  dur)

Blocks until the future is fulfilled, or dur elapses. Returns true if the future was fulfilled.

Preconditions:

Postconditions:

Definition at line 2134 of file Future-inl.h.

References folly::futures::detail::WaitExecutor::create(), folly::futures::detail::FutureBase< T >::detach(), folly::futures::detail::getDeferredExecutor(), folly::Promise< T >::getSemiFuture(), folly::gen::move, now(), folly::futures::detail::FutureBase< T >::setCallback_(), folly::SemiFuture< T >::wait(), and folly::futures::detail::waitImpl().

2134  {
2135  if (auto deferredExecutor = getDeferredExecutor()) {
2136  // Make sure that the last callback in the future chain will be run on the
2137  // WaitExecutor.
2138  Promise<T> promise;
2139  auto ret = promise.getSemiFuture();
2140  setCallback_(
2141  [p = std::move(promise)](auto&& r) mutable { p.setTry(std::move(r)); });
2142  auto waitExecutor = futures::detail::WaitExecutor::create();
2143  auto deadline = futures::detail::WaitExecutor::Clock::now() + dur;
2144  deferredExecutor->setExecutor(waitExecutor.copy());
2145  while (!ret.isReady()) {
2146  if (!waitExecutor->driveUntil(deadline)) {
2147  break;
2148  }
2149  }
2150  waitExecutor->detach();
2151  this->detach();
2152  *this = std::move(ret);
2153  } else {
2154  futures::detail::waitImpl(*this, dur);
2155  }
2156  return *this;
2157 }
void waitImpl(FutureType &f)
Definition: Future-inl.h:2004
std::chrono::steady_clock::time_point now()
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
DeferredExecutor * getDeferredExecutor() const
Definition: Future-inl.h:780
friend class Promise< T >
Definition: Future.h:879
static KeepAlive< WaitExecutor > create()
Definition: Future-inl.h:656
template<class T>
SemiFuture<T>& folly::SemiFuture< T >::wait ( Duration  dur)
private

Blocks until the future is fulfilled, or dur elapses.

Preconditions:

Postconditions:

  • valid() == true
  • &RESULT == this
  • isReady() will be indeterminate - may or may not be true
template<class T>
SemiFuture<T> folly::SemiFuture< T >::within ( Duration  dur,
Timekeeper tk = nullptr 
)
inline

Definition at line 790 of file Future.h.

References folly::gen::move.

790  {
791  return std::move(*this).within(dur, FutureTimeout(), tk);
792  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
template<class T>
template<class E >
SemiFuture<T> folly::SemiFuture< T >::within ( Duration  dur,
E  e,
Timekeeper tk = nullptr 
)
inline

Definition at line 795 of file Future.h.

References folly::coro::co_viaIfAsync(), folly::gen::move, promise_, and folly::value().

795  {
796  return this->isReady() ? std::move(*this)
797  : std::move(*this).withinImplementation(dur, e, tk);
798  }
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
SemiFuture< T > withinImplementation(Duration dur, E e, Timekeeper *tk)&&
Definition: Future-inl.h:430

Friends And Related Function Documentation

template<class T>
template<class >
friend class Future
friend

Definition at line 885 of file Future.h.

template<class T>
template<class >
friend class futures::detail::FutureBase
friend

Definition at line 881 of file Future.h.

template<class T>
DeferredExecutor* futures::detail::getDeferredExecutor ( SemiFuture< T > &  )
friend
template<class T>
template<class T2 >
SemiFuture<T2> makeSemiFuture ( Try< T2 )
friend
template<class T>
friend class Promise< T >
friend

Definition at line 879 of file Future.h.

template<class T>
template<class >
friend class SemiFuture
friend

Definition at line 883 of file Future.h.


The documentation for this class was generated from the following files: