(wangle) s/FutureObject/detail::State/
authorHans Fugal <fugalh@fb.com>
Mon, 30 Jun 2014 20:22:56 +0000 (13:22 -0700)
committerTudor Bosman <tudorb@fb.com>
Mon, 7 Jul 2014 15:42:04 +0000 (08:42 -0700)
Summary:
codemod
I never was satisfied with this name. `State` feels a little better. More descriptive. But still pretty generic, so I'm open to alternative ideas.

Test Plan: It still builds and tests pass.

Reviewed By: hannesr@fb.com

Subscribers: jsedgwick, net-systems@, fugalh, exa

FB internal diff: D1411506

folly/wangle/Future-inl.h
folly/wangle/Future.h
folly/wangle/Promise-inl.h
folly/wangle/Promise.h
folly/wangle/detail.h [deleted file]
folly/wangle/detail/State.h [new file with mode: 0644]

index aa45cb26d6a3ec8f5e7c2fe98aea49d1ee3dd801..27af013e757e3b5958390b63b409dcd18f43bb96 100644 (file)
@@ -16,7 +16,7 @@
 
 #pragma once
 
-#include "detail.h"
+#include "detail/State.h"
 #include <folly/LifoSem.h>
 
 namespace folly { namespace wangle {
@@ -32,26 +32,26 @@ struct isFuture<Future<T> > {
 };
 
 template <class T>
-Future<T>::Future(Future<T>&& other) noexcept : obj_(other.obj_) {
-  other.obj_ = nullptr;
+Future<T>::Future(Future<T>&& other) noexcept : state_(other.state_) {
+  other.state_ = nullptr;
 }
 
 template <class T>
 Future<T>& Future<T>::operator=(Future<T>&& other) {
-  std::swap(obj_, other.obj_);
+  std::swap(state_, other.state_);
   return *this;
 }
 
 template <class T>
 Future<T>::~Future() {
-  if (obj_) {
+  if (state_) {
     setCallback_([](Try<T>&&) {}); // detach
   }
 }
 
 template <class T>
 void Future<T>::throwIfInvalid() const {
-  if (!obj_)
+  if (!state_)
     throw NoState();
 }
 
@@ -59,8 +59,8 @@ template <class T>
 template <class F>
 void Future<T>::setCallback_(F&& func) {
   throwIfInvalid();
-  obj_->setCallback_(std::move(func));
-  obj_ = nullptr;
+  state_->setCallback_(std::move(func));
+  state_ = nullptr;
 }
 
 template <class T>
@@ -87,10 +87,10 @@ Future<T>::then(F&& func) {
      sophisticated that avoids making a new Future object when it can, as an
      optimization. But this is correct.
 
-     obj_ can't be moved, it is explicitly disallowed (as is copying). But
+     state_ can't be moved, it is explicitly disallowed (as is copying). But
      if there's ever a reason to allow it, this is one place that makes that
      assumption and would need to be fixed. We use a standard shared pointer
-     for obj_ (by copying it in), which means in essence obj holds a shared
+     for state_ (by copying it in), which means in essence obj holds a shared
      pointer to itself.  But this shouldn't leak because Promise will not
      outlive the continuation, because Promise will setException() with a
      broken Promise if it is destructed before completed. We could use a
@@ -102,11 +102,11 @@ Future<T>::then(F&& func) {
      We have to move in the Promise and func using the MoveWrapper
      hack. (func could be copied but it's a big drag on perf).
 
-     Two subtle but important points about this design. FutureObject has no
+     Two subtle but important points about this design. detail::State has no
      back pointers to Future or Promise, so if Future or Promise get moved
      (and they will be moved in performant code) we don't have to do
      anything fancy. And because we store the continuation in the
-     FutureObject, not in the Future, we can execute the continuation even
+     detail::State, not in the Future, we can execute the continuation even
      after the Future has gone out of scope. This is an intentional design
      decision. It is likely we will want to be able to cancel a continuation
      in some circumstances, but I think it should be explicit not implicit
@@ -164,21 +164,21 @@ template <class T>
 typename std::add_lvalue_reference<T>::type Future<T>::value() {
   throwIfInvalid();
 
-  return obj_->value();
+  return state_->value();
 }
 
 template <class T>
 typename std::add_lvalue_reference<const T>::type Future<T>::value() const {
   throwIfInvalid();
 
-  return obj_->value();
+  return state_->value();
 }
 
 template <class T>
 Try<T>& Future<T>::getTry() {
   throwIfInvalid();
 
-  return obj_->getTry();
+  return state_->getTry();
 }
 
 template <class T>
@@ -191,7 +191,7 @@ inline Later<T> Future<T>::via(Executor* executor) {
 template <class T>
 bool Future<T>::isReady() const {
   throwIfInvalid();
-  return obj_->ready();
+  return state_->ready();
 }
 
 // makeFuture
index 6a75f829daef0932bfea942958ef48647b2ff023..fcec435380a8ad49f010411e6ae12fe95eff50a6 100644 (file)
@@ -181,13 +181,13 @@ class Future {
   void setCallback_(F&& func);
 
  private:
-  typedef detail::FutureObject<T>* objPtr;
+  typedef detail::State<T>* statePtr;
 
   // shared state object
-  objPtr obj_;
+  statePtr state_;
 
   explicit
-  Future(objPtr obj) : obj_(obj) {}
+  Future(statePtr obj) : state_(obj) {}
 
   void throwIfInvalid() const;
 
index 490602702eec74686ede50ee993e10433aa74267..190d9cd04168725b71146239a11c30157ac239e0 100644 (file)
 #include <thread>
 
 #include "WangleException.h"
-#include "detail.h"
+#include "detail/State.h"
 
 namespace folly { namespace wangle {
 
 template <class T>
-Promise<T>::Promise() : retrieved_(false), obj_(new detail::FutureObject<T>())
+Promise<T>::Promise() : retrieved_(false), state_(new detail::State<T>())
 {}
 
 template <class T>
 Promise<T>::Promise(Promise<T>&& other) :
-retrieved_(other.retrieved_), obj_(other.obj_) {
-  other.obj_ = nullptr;
+retrieved_(other.retrieved_), state_(other.state_) {
+  other.state_ = nullptr;
 }
 
 template <class T>
 Promise<T>& Promise<T>::operator=(Promise<T>&& other) {
-  std::swap(obj_, other.obj_);
+  std::swap(state_, other.state_);
   std::swap(retrieved_, other.retrieved_);
   return *this;
 }
 
 template <class T>
 void Promise<T>::throwIfFulfilled() {
-  if (!obj_)
+  if (!state_)
     throw PromiseAlreadySatisfied();
 }
 
@@ -55,7 +55,7 @@ void Promise<T>::throwIfRetrieved() {
 
 template <class T>
 Promise<T>::~Promise() {
-  if (obj_) {
+  if (state_) {
     setException(BrokenPromise());
   }
 }
@@ -65,7 +65,7 @@ Future<T> Promise<T>::getFuture() {
   throwIfRetrieved();
   throwIfFulfilled();
   retrieved_ = true;
-  return Future<T>(obj_);
+  return Future<T>(state_);
 }
 
 template <class T>
@@ -78,21 +78,21 @@ void Promise<T>::setException(E const& e) {
 template <class T>
 void Promise<T>::setException(std::exception_ptr const& e) {
   throwIfFulfilled();
-  obj_->setException(e);
+  state_->setException(e);
   if (!retrieved_) {
-    delete obj_;
+    delete state_;
   }
-  obj_ = nullptr;
+  state_ = nullptr;
 }
 
 template <class T>
 void Promise<T>::fulfilTry(Try<T>&& t) {
   throwIfFulfilled();
-  obj_->fulfil(std::move(t));
+  state_->fulfil(std::move(t));
   if (!retrieved_) {
-    delete obj_;
+    delete state_;
   }
-  obj_ = nullptr;
+  state_ = nullptr;
 }
 
 template <class T>
@@ -102,11 +102,11 @@ void Promise<T>::setValue(M&& v) {
                 "Use setValue() instead");
 
   throwIfFulfilled();
-  obj_->fulfil(Try<T>(std::forward<M>(v)));
+  state_->fulfil(Try<T>(std::forward<M>(v)));
   if (!retrieved_) {
-    delete obj_;
+    delete state_;
   }
-  obj_ = nullptr;
+  state_ = nullptr;
 }
 
 template <class T>
@@ -115,11 +115,11 @@ void Promise<T>::setValue() {
                 "Use setValue(value) instead");
 
   throwIfFulfilled();
-  obj_->fulfil(Try<void>());
+  state_->fulfil(Try<void>());
   if (!retrieved_) {
-    delete obj_;
+    delete state_;
   }
-  obj_ = nullptr;
+  state_ = nullptr;
 }
 
 template <class T>
index aae306c0dd7c46f5b82137fd3b4f0cad2477cb46..c47cc98e95693a55ba89284d3e2185180a767321 100644 (file)
@@ -76,13 +76,13 @@ public:
   void fulfil(F&& func);
 
 private:
-  typedef typename Future<T>::objPtr objPtr;
+  typedef typename Future<T>::statePtr statePtr;
 
   // Whether the Future has been retrieved (a one-time operation).
   bool retrieved_;
 
   // shared state object
-  objPtr obj_;
+  statePtr state_;
 
   void throwIfFulfilled();
   void throwIfRetrieved();
diff --git a/folly/wangle/detail.h b/folly/wangle/detail.h
deleted file mode 100644 (file)
index 105ebc3..0000000
+++ /dev/null
@@ -1,159 +0,0 @@
-/*
- * Copyright 2014 Facebook, Inc.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#pragma once
-
-#include <atomic>
-#include <folly/Optional.h>
-#include <stdexcept>
-#include <vector>
-
-#include "Try.h"
-#include "Promise.h"
-#include "Future.h"
-
-namespace folly { namespace wangle { namespace detail {
-
-/** The shared state object for Future and Promise. */
-template<typename T>
-class FutureObject {
- public:
-  FutureObject() = default;
-
-  // not copyable
-  FutureObject(FutureObject const&) = delete;
-  FutureObject& operator=(FutureObject const&) = delete;
-
-  // not movable (see comment in the implementation of Future::then)
-  FutureObject(FutureObject&&) noexcept = delete;
-  FutureObject& operator=(FutureObject&&) = delete;
-
-  Try<T>& getTry() {
-    return *value_;
-  }
-
-  template <typename F>
-  void setCallback_(F func) {
-    if (continuation_) {
-      throw std::logic_error("setCallback_ called twice");
-    }
-
-    continuation_ = std::move(func);
-
-    if (shouldContinue_.test_and_set()) {
-      continuation_(std::move(*value_));
-      delete this;
-    }
-  }
-
-  void fulfil(Try<T>&& t) {
-    if (value_.hasValue()) {
-      throw std::logic_error("fulfil called twice");
-    }
-
-    value_ = std::move(t);
-
-    if (shouldContinue_.test_and_set()) {
-      continuation_(std::move(*value_));
-      delete this;
-    }
-  }
-
-  void setException(std::exception_ptr const& e) {
-    fulfil(Try<T>(e));
-  }
-
-  template <class E> void setException(E const& e) {
-    fulfil(Try<T>(std::make_exception_ptr<E>(e)));
-  }
-
-  bool ready() const {
-    return value_.hasValue();
-  }
-
-  typename std::add_lvalue_reference<T>::type value() {
-    if (ready()) {
-      return value_->value();
-    } else {
-      throw FutureNotReady();
-    }
-  }
-
- private:
-  std::atomic_flag shouldContinue_ = ATOMIC_FLAG_INIT;
-  folly::Optional<Try<T>> value_;
-  std::function<void(Try<T>&&)> continuation_;
-};
-
-template <typename... Ts>
-struct VariadicContext {
-  VariadicContext() : total(0), count(0) {}
-  Promise<std::tuple<Try<Ts>... > > p;
-  std::tuple<Try<Ts>... > results;
-  size_t total;
-  std::atomic<size_t> count;
-  typedef Future<std::tuple<Try<Ts>...>> type;
-};
-
-template <typename... Ts, typename THead, typename... Fs>
-typename std::enable_if<sizeof...(Fs) == 0, void>::type
-whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead&& head, Fs&&... tail) {
-  head.setCallback_([ctx](Try<typename THead::value_type>&& t) {
-    std::get<sizeof...(Ts) - sizeof...(Fs) - 1>(ctx->results) = std::move(t);
-    if (++ctx->count == ctx->total) {
-      ctx->p.setValue(std::move(ctx->results));
-      delete ctx;
-    }
-  });
-}
-
-template <typename... Ts, typename THead, typename... Fs>
-typename std::enable_if<sizeof...(Fs) != 0, void>::type
-whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead&& head, Fs&&... tail) {
-  head.setCallback_([ctx](Try<typename THead::value_type>&& t) {
-    std::get<sizeof...(Ts) - sizeof...(Fs) - 1>(ctx->results) = std::move(t);
-    if (++ctx->count == ctx->total) {
-      ctx->p.setValue(std::move(ctx->results));
-      delete ctx;
-    }
-  });
-  // template tail-recursion
-  whenAllVariadicHelper(ctx, std::forward<Fs>(tail)...);
-}
-
-template <typename T>
-struct WhenAllContext {
-  explicit WhenAllContext() : count(0), total(0) {}
-  Promise<std::vector<Try<T> > > p;
-  std::vector<Try<T> > results;
-  std::atomic<size_t> count;
-  size_t total;
-};
-
-template <typename T>
-struct WhenAnyContext {
-  explicit WhenAnyContext(size_t n) : done(false), ref_count(n) {};
-  Promise<std::pair<size_t, Try<T>>> p;
-  std::atomic<bool> done;
-  std::atomic<size_t> ref_count;
-  void decref() {
-    if (--ref_count == 0) {
-      delete this;
-    }
-  }
-};
-
-}}} // namespace
diff --git a/folly/wangle/detail/State.h b/folly/wangle/detail/State.h
new file mode 100644 (file)
index 0000000..ccba9ac
--- /dev/null
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2014 Facebook, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <atomic>
+#include <stdexcept>
+#include <vector>
+
+#include <folly/Optional.h>
+
+#include <folly/wangle/Try.h>
+#include <folly/wangle/Promise.h>
+#include <folly/wangle/Future.h>
+
+namespace folly { namespace wangle { namespace detail {
+
+/** The shared state object for Future and Promise. */
+template<typename T>
+class State {
+ public:
+  State() = default;
+
+  // not copyable
+  State(State const&) = delete;
+  State& operator=(State const&) = delete;
+
+  // not movable (see comment in the implementation of Future::then)
+  State(State&&) noexcept = delete;
+  State& operator=(State&&) = delete;
+
+  Try<T>& getTry() {
+    return *value_;
+  }
+
+  template <typename F>
+  void setCallback_(F func) {
+    if (continuation_) {
+      throw std::logic_error("setCallback_ called twice");
+    }
+
+    continuation_ = std::move(func);
+
+    if (shouldContinue_.test_and_set()) {
+      continuation_(std::move(*value_));
+      delete this;
+    }
+  }
+
+  void fulfil(Try<T>&& t) {
+    if (value_.hasValue()) {
+      throw std::logic_error("fulfil called twice");
+    }
+
+    value_ = std::move(t);
+
+    if (shouldContinue_.test_and_set()) {
+      continuation_(std::move(*value_));
+      delete this;
+    }
+  }
+
+  void setException(std::exception_ptr const& e) {
+    fulfil(Try<T>(e));
+  }
+
+  template <class E> void setException(E const& e) {
+    fulfil(Try<T>(std::make_exception_ptr<E>(e)));
+  }
+
+  bool ready() const {
+    return value_.hasValue();
+  }
+
+  typename std::add_lvalue_reference<T>::type value() {
+    if (ready()) {
+      return value_->value();
+    } else {
+      throw FutureNotReady();
+    }
+  }
+
+ private:
+  std::atomic_flag shouldContinue_ = ATOMIC_FLAG_INIT;
+  folly::Optional<Try<T>> value_;
+  std::function<void(Try<T>&&)> continuation_;
+};
+
+template <typename... Ts>
+struct VariadicContext {
+  VariadicContext() : total(0), count(0) {}
+  Promise<std::tuple<Try<Ts>... > > p;
+  std::tuple<Try<Ts>... > results;
+  size_t total;
+  std::atomic<size_t> count;
+  typedef Future<std::tuple<Try<Ts>...>> type;
+};
+
+template <typename... Ts, typename THead, typename... Fs>
+typename std::enable_if<sizeof...(Fs) == 0, void>::type
+whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead&& head, Fs&&... tail) {
+  head.setCallback_([ctx](Try<typename THead::value_type>&& t) {
+    std::get<sizeof...(Ts) - sizeof...(Fs) - 1>(ctx->results) = std::move(t);
+    if (++ctx->count == ctx->total) {
+      ctx->p.setValue(std::move(ctx->results));
+      delete ctx;
+    }
+  });
+}
+
+template <typename... Ts, typename THead, typename... Fs>
+typename std::enable_if<sizeof...(Fs) != 0, void>::type
+whenAllVariadicHelper(VariadicContext<Ts...> *ctx, THead&& head, Fs&&... tail) {
+  head.setCallback_([ctx](Try<typename THead::value_type>&& t) {
+    std::get<sizeof...(Ts) - sizeof...(Fs) - 1>(ctx->results) = std::move(t);
+    if (++ctx->count == ctx->total) {
+      ctx->p.setValue(std::move(ctx->results));
+      delete ctx;
+    }
+  });
+  // template tail-recursion
+  whenAllVariadicHelper(ctx, std::forward<Fs>(tail)...);
+}
+
+template <typename T>
+struct WhenAllContext {
+  explicit WhenAllContext() : count(0), total(0) {}
+  Promise<std::vector<Try<T> > > p;
+  std::vector<Try<T> > results;
+  std::atomic<size_t> count;
+  size_t total;
+};
+
+template <typename T>
+struct WhenAnyContext {
+  explicit WhenAnyContext(size_t n) : done(false), ref_count(n) {};
+  Promise<std::pair<size_t, Try<T>>> p;
+  std::atomic<bool> done;
+  std::atomic<size_t> ref_count;
+  void decref() {
+    if (--ref_count == 0) {
+      delete this;
+    }
+  }
+};
+
+}}} // namespace