You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by be...@apache.org on 2012/05/14 20:45:58 UTC

svn commit: r1338339 - in /incubator/mesos/trunk/third_party/libprocess: include/process/future.hpp src/tests.cpp

Author: benh
Date: Mon May 14 18:45:58 2012
New Revision: 1338339

URL: http://svn.apache.org/viewvc?rev=1338339&view=rev
Log:
Added Future::then (https://reviews.apache.org/r/4980).

Modified:
    incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp
    incubator/mesos/trunk/third_party/libprocess/src/tests.cpp

Modified: incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp?rev=1338339&r1=1338338&r2=1338339&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/include/process/future.hpp Mon May 14 18:45:58 2012
@@ -80,6 +80,25 @@ public:
   const Future<T>& onDiscarded(const DiscardedCallback& callback) const;
   const Future<T>& onAny(const AnyCallback& callback) const;
 
+  // Installs callbacks that get executed when this future is ready
+  // and associates the result of the callback with the future that is
+  // returned to the caller (which may be of a different type).
+  template <typename X>
+  Future<X> then(
+      const std::tr1::_Bind<
+      Future<X>(*(std::tr1::_Placeholder<1>))(const T&)>& b) const;
+
+  template <typename X>
+  Future<X> then(
+      const std::tr1::_Bind<
+      X(*(std::tr1::_Placeholder<1>))(const T&)>& b) const;
+
+  template <typename X>
+  Future<X> then(const std::tr1::function<Future<X>(const T&)>& f) const;
+
+  template <typename X>
+  Future<X> then(const std::tr1::function<X(const T&)>& f) const;
+
 private:
   friend class Promise<T>;
 
@@ -566,6 +585,120 @@ const Future<T>& Future<T>::onAny(const 
 }
 
 
+namespace internal {
+
+template <typename T, typename X>
+void thenf(const std::tr1::shared_ptr<Promise<X> >& promise,
+          const std::tr1::function<Future<X>(const T&)>& callback,
+          const Future<T>& future)
+{
+  if (future.isReady()) {
+    promise->associate(callback(future.get()));
+  } else if (future.isFailed()) {
+    promise->fail(future.failure());
+  } else if (future.isDiscarded()) {
+    promise->future().discard();
+  }
+}
+
+template <typename T, typename X>
+void then(const std::tr1::shared_ptr<Promise<X> >& promise,
+          const std::tr1::function<X(const T&)>& callback,
+          const Future<T>& future)
+{
+  if (future.isReady()) {
+    promise->set(callback(future.get()));
+  } else if (future.isFailed()) {
+    promise->fail(future.failure());
+  } else if (future.isDiscarded()) {
+    promise->future().discard();
+  }
+}
+
+
+} // namespace internal {
+
+
+template <typename T>
+template <typename X>
+Future<X> Future<T>::then(const std::tr1::function<Future<X>(const T&)>& f) const
+{
+  std::tr1::shared_ptr<Promise<X> > promise(new Promise<X>());
+
+  std::tr1::function<void(void)> thenf =
+    std::tr1::bind(&internal::thenf<T, X>,
+                   promise,
+                   f,
+                   *this);
+
+  onAny(thenf);
+
+  return promise->future();
+}
+
+
+template <typename T>
+template <typename X>
+Future<X> Future<T>::then(const std::tr1::function<X(const T&)>& f) const
+{
+  std::tr1::shared_ptr<Promise<X> > promise(new Promise<X>());
+
+  std::tr1::function<void(void)> then =
+    std::tr1::bind(&internal::then<T, X>,
+                   promise,
+                   f,
+                   *this);
+
+  onAny(then);
+
+  return promise->future();
+}
+
+
+template <typename T>
+template <typename X>
+Future<X> Future<T>::then(
+    const std::tr1::_Bind<
+    Future<X>(*(std::tr1::_Placeholder<1>))(const T&)>& b) const
+{
+  std::tr1::shared_ptr<Promise<X> > promise(new Promise<X>());
+
+  std::tr1::function<Future<X>(const T&)> callback = b;
+
+  std::tr1::function<void(void)> thenf =
+    std::tr1::bind(&internal::thenf<T, X>,
+                   promise,
+                   callback,
+                   *this);
+
+  onAny(thenf);
+
+  return promise->future();
+}
+
+
+template <typename T>
+template <typename X>
+Future<X> Future<T>::then(
+    const std::tr1::_Bind<
+    X(*(std::tr1::_Placeholder<1>))(const T&)>& b) const
+{
+  std::tr1::shared_ptr<Promise<X> > promise(new Promise<X>());
+
+  std::tr1::function<X(const T&)> callback = b;
+
+  std::tr1::function<void(void)> then =
+    std::tr1::bind(&internal::then<T, X>,
+                   promise,
+                   callback,
+                   *this);
+
+  onAny(then);
+
+  return promise->future();
+}
+
+
 template <typename T>
 bool Future<T>::set(const T& _t)
 {

Modified: incubator/mesos/trunk/third_party/libprocess/src/tests.cpp
URL: http://svn.apache.org/viewvc/incubator/mesos/trunk/third_party/libprocess/src/tests.cpp?rev=1338339&r1=1338338&r2=1338339&view=diff
==============================================================================
--- incubator/mesos/trunk/third_party/libprocess/src/tests.cpp (original)
+++ incubator/mesos/trunk/third_party/libprocess/src/tests.cpp Mon May 14 18:45:58 2012
@@ -102,6 +102,44 @@ TEST(libprocess, associate)
 }
 
 
+Future<std::string> itoa1(int* const& i)
+{
+  std::ostringstream out;
+  out << *i;
+  return out.str();
+}
+
+
+std::string itoa2(int* const& i)
+{
+  std::ostringstream out;
+  out << *i;
+  return out.str();
+}
+
+
+TEST(libprocess, then)
+{
+  Promise<int*> promise;
+
+  int i = 42;
+
+  promise.set(&i);
+
+  Future<std::string> future = promise.future()
+    .then(std::tr1::bind(&itoa1, std::tr1::placeholders::_1));
+
+  ASSERT_TRUE(future.isReady());
+  EXPECT_EQ("42", future.get());
+
+  future = promise.future()
+    .then(std::tr1::bind(&itoa2, std::tr1::placeholders::_1));
+
+  ASSERT_TRUE(future.isReady());
+  EXPECT_EQ("42", future.get());
+}
+
+
 class SpawnProcess : public Process<SpawnProcess>
 {
 public: