Fix copyright lines
[folly.git] / folly / futures / Future.h
index 399574701f0104de12055b39aecd32b35d07208f..6d4a403f9228f5b78b156e1f0e83e73beeea3cd7 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2017 Facebook, Inc.
+ * Copyright 2014-present Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,7 +13,6 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
 #pragma once
 
 #include <algorithm>
@@ -25,6 +24,7 @@
 
 #include <folly/Optional.h>
 #include <folly/Portability.h>
+#include <folly/ScopeGuard.h>
 #include <folly/Try.h>
 #include <folly/Utility.h>
 #include <folly/executors/DrivableExecutor.h>
@@ -58,7 +58,8 @@ class FutureBase {
   template <
       class T2 = T,
       typename = typename std::enable_if<
-          !isFuture<typename std::decay<T2>::type>::value>::type>
+          !isFuture<typename std::decay<T2>::type>::value &&
+          !isSemiFuture<typename std::decay<T2>::type>::value>::type>
   /* implicit */ FutureBase(T2&& val);
 
   template <class T2 = T>
@@ -95,29 +96,12 @@ class FutureBase {
   T&& value() &&;
   T const&& value() const&&;
 
-  /// Returns an inactive Future which will call back on the other side of
-  /// executor (when it is activated).
-  ///
-  /// NB remember that Futures activate when they destruct. This is good,
-  /// it means that this will work:
-  ///
-  ///   f.via(e).then(a).then(b);
-  ///
-  /// a and b will execute in the same context (the far side of e), because
-  /// the Future (temporary variable) created by via(e) does not call back
-  /// until it destructs, which is after then(a) and then(b) have been wired
-  /// up.
-  ///
-  /// But this is still racy:
-  ///
-  ///   f = f.via(e).then(a);
-  ///   f.then(b);
-  // The ref-qualifier allows for `this` to be moved out so we
-  // don't get access-after-free situations in chaining.
-  // https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/
-  inline Future<T> via(
-      Executor* executor,
-      int8_t priority = Executor::MID_PRI) &&;
+  /// Returns a reference to the try of the result. Throws as for value if
+  /// future is not valid.
+  Try<T>& result() &;
+  Try<T> const& result() const&;
+  Try<T>&& result() &&;
+  Try<T> const&& result() const&&;
 
   /** True when the result (or exception) is ready. */
   bool isReady() const;
@@ -128,9 +112,6 @@ class FutureBase {
   /// sugar for getTry().hasException()
   bool hasException();
 
-  /** A reference to the Try of the value */
-  Try<T>& getTry();
-
   /// If the promise has been fulfilled, return an Optional with the Try<T>.
   /// Otherwise return an empty Optional.
   /// Note that this moves the Try<T> out.
@@ -218,6 +199,7 @@ template <class T>
 class SemiFuture : private futures::detail::FutureBase<T> {
  private:
   using Base = futures::detail::FutureBase<T>;
+  using DeferredExecutor = futures::detail::DeferredExecutor;
 
  public:
   static SemiFuture<T> makeEmpty(); // equivalent to moved-from
@@ -231,7 +213,8 @@ class SemiFuture : private futures::detail::FutureBase<T> {
   template <
       class T2 = T,
       typename = typename std::enable_if<
-          !isFuture<typename std::decay<T2>::type>::value>::type>
+          !isFuture<typename std::decay<T2>::type>::value &&
+          !isSemiFuture<typename std::decay<T2>::type>::value>::type>
   /* implicit */ SemiFuture(T2&& val) : Base(std::forward<T2>(val)) {}
 
   template <class T2 = T>
@@ -253,7 +236,6 @@ class SemiFuture : private futures::detail::FutureBase<T> {
   /* implicit */ SemiFuture(Future<T>&&) noexcept;
 
   using Base::cancel;
-  using Base::getTry;
   using Base::hasException;
   using Base::hasValue;
   using Base::isActive;
@@ -262,7 +244,7 @@ class SemiFuture : private futures::detail::FutureBase<T> {
   using Base::raise;
   using Base::setCallback_;
   using Base::value;
-  using Base::via;
+  using Base::result;
 
   SemiFuture& operator=(SemiFuture const&) = delete;
   SemiFuture& operator=(SemiFuture&&) noexcept;
@@ -277,6 +259,24 @@ class SemiFuture : private futures::detail::FutureBase<T> {
   /// exception).
   T get(Duration dur) &&;
 
+  /// Block until the future is fulfilled, or until timed out. Returns the
+  /// Try of the value (moved out).
+  Try<T> getTry() &&;
+
+  /// Block until the future is fulfilled, or until timed out. Returns the
+  /// Try of the value (moved out) or may throw a TimedOut exception.
+  Try<T> getTry(Duration dur) &&;
+
+  /// Call e->drive() repeatedly until the future is fulfilled. Examples
+  /// of DrivableExecutor include EventBase and ManualExecutor. Returns the
+  /// value (moved out), or throws the exception.
+  T getVia(DrivableExecutor* e) &&;
+
+  /// Call e->drive() repeatedly until the future is fulfilled. Examples
+  /// of DrivableExecutor include EventBase and ManualExecutor. Returns the
+  /// Try of the value (moved out).
+  Try<T> getTryVia(DrivableExecutor* e) &&;
+
   /// Block until this Future is complete. Returns a reference to this Future.
   SemiFuture<T>& wait() &;
 
@@ -290,11 +290,67 @@ class SemiFuture : private futures::detail::FutureBase<T> {
   /// Overload of wait(Duration) for rvalue Futures
   SemiFuture<T>&& wait(Duration) &&;
 
+  /// Call e->drive() repeatedly until the future is fulfilled. Examples
+  /// of DrivableExecutor include EventBase and ManualExecutor. Returns a
+  /// reference to this SemiFuture so that you can chain calls if desired.
+  /// value (moved out), or throws the exception.
+  SemiFuture<T>& waitVia(DrivableExecutor* e) &;
+
+  /// Overload of waitVia() for rvalue Futures
+  SemiFuture<T>&& waitVia(DrivableExecutor* e) &&;
+
+  /// Returns an inactive Future which will call back on the other side of
+  /// executor (when it is activated).
+  ///
+  /// NB remember that Futures activate when they destruct. This is good,
+  /// it means that this will work:
+  ///
+  ///   f.via(e).then(a).then(b);
+  ///
+  /// a and b will execute in the same context (the far side of e), because
+  /// the Future (temporary variable) created by via(e) does not call back
+  /// until it destructs, which is after then(a) and then(b) have been wired
+  /// up.
+  ///
+  /// But this is still racy:
+  ///
+  ///   f = f.via(e).then(a);
+  ///   f.then(b);
+  // The ref-qualifier allows for `this` to be moved out so we
+  // don't get access-after-free situations in chaining.
+  // https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/
+  inline Future<T> via(
+      Executor* executor,
+      int8_t priority = Executor::MID_PRI) &&;
+
+  /**
+   * Defer work to run on the consumer of the future.
+   * This work will be run eithe ron 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.
+   */
+  template <typename F>
+  SemiFuture<typename futures::detail::callableResult<T, F>::Return::value_type>
+  defer(F&& func) &&;
+
+  // Public as for setCallback_
+  // Ensure that a boostable executor performs work to chain deferred work
+  // cleanly
+  void boost_();
+
  private:
+  friend class Promise<T>;
   template <class>
   friend class futures::detail::FutureBase;
+  template <class>
+  friend class SemiFuture;
 
   using typename Base::corePtr;
+  using Base::setExecutor;
+  using Base::throwIfInvalid;
 
   template <class T2>
   friend SemiFuture<T2> makeSemiFuture(Try<T2>&&);
@@ -320,7 +376,8 @@ class Future : private futures::detail::FutureBase<T> {
   template <
       class T2 = T,
       typename = typename std::enable_if<
-          !isFuture<typename std::decay<T2>::type>::value>::type>
+          !isFuture<typename std::decay<T2>::type>::value &&
+          !isSemiFuture<typename std::decay<T2>::type>::value>::type>
   /* implicit */ Future(T2&& val) : Base(std::forward<T2>(val)) {}
 
   template <class T2 = T>
@@ -365,7 +422,6 @@ class Future : private futures::detail::FutureBase<T> {
   Future& operator=(Future<T2>&&);
 
   using Base::cancel;
-  using Base::getTry;
   using Base::hasException;
   using Base::hasValue;
   using Base::isActive;
@@ -374,7 +430,7 @@ class Future : private futures::detail::FutureBase<T> {
   using Base::raise;
   using Base::setCallback_;
   using Base::value;
-  using Base::via;
+  using Base::result;
 
   static Future<T> makeEmpty(); // equivalent to moved-from
 
@@ -384,16 +440,16 @@ class Future : private futures::detail::FutureBase<T> {
   // movable
   Future& operator=(Future&&) noexcept;
 
-  /// Call e->drive() repeatedly until the future is fulfilled. Examples
-  /// of DrivableExecutor include EventBase and ManualExecutor. Returns a
-  /// reference to the Try of the value.
-  Try<T>& getTryVia(DrivableExecutor* e);
-
   /// Call e->drive() repeatedly until the future is fulfilled. Examples
   /// of DrivableExecutor include EventBase and ManualExecutor. Returns the
   /// value (moved out), or throws the exception.
   T getVia(DrivableExecutor* e);
 
+  /// Call e->drive() repeatedly until the future is fulfilled. Examples
+  /// of DrivableExecutor include EventBase and ManualExecutor. Returns a
+  /// reference to the Try of the value.
+  Try<T>& getTryVia(DrivableExecutor* e);
+
   /// Unwraps the case of a Future<Future<T>> instance, and returns a simple
   /// Future<T> instance.
   template <class F = T>
@@ -401,6 +457,30 @@ class Future : private futures::detail::FutureBase<T> {
       enable_if<isFuture<F>::value, Future<typename isFuture<T>::Inner>>::type
       unwrap();
 
+  /// Returns an inactive Future which will call back on the other side of
+  /// executor (when it is activated).
+  ///
+  /// NB remember that Futures activate when they destruct. This is good,
+  /// it means that this will work:
+  ///
+  ///   f.via(e).then(a).then(b);
+  ///
+  /// a and b will execute in the same context (the far side of e), because
+  /// the Future (temporary variable) created by via(e) does not call back
+  /// until it destructs, which is after then(a) and then(b) have been wired
+  /// up.
+  ///
+  /// But this is still racy:
+  ///
+  ///   f = f.via(e).then(a);
+  ///   f.then(b);
+  // The ref-qualifier allows for `this` to be moved out so we
+  // don't get access-after-free situations in chaining.
+  // https://akrzemi1.wordpress.com/2014/06/02/ref-qualifiers/
+  inline Future<T> via(
+      Executor* executor,
+      int8_t priority = Executor::MID_PRI) &&;
+
   /// This variant creates a new future, where the ref-qualifier && version
   /// moves `this` out. This one is less efficient but avoids confusing users
   /// when "return f.via(x);" fails.
@@ -596,6 +676,9 @@ class Future : private futures::detail::FutureBase<T> {
   /// exception).
   T get(Duration dur);
 
+  /** A reference to the Try of the value */
+  Try<T>& getTry();
+
   /// Block until this Future is complete. Returns a reference to this Future.
   Future<T>& wait() &;
 
@@ -693,7 +776,11 @@ class Future : private futures::detail::FutureBase<T> {
   friend class futures::detail::FutureBase;
   template <class>
   friend class Future;
+  template <class>
+  friend class SemiFuture;
 
+  using Base::setExecutor;
+  using Base::throwIfInvalid;
   using typename Base::corePtr;
 
   explicit Future(corePtr obj) : Base(obj) {}