add support for whenAll to waitWithSemaphore
authorMatt Dordal <mnd@fb.com>
Fri, 23 May 2014 16:19:20 +0000 (09:19 -0700)
committerAnton Likhtarov <alikhtarov@fb.com>
Mon, 9 Jun 2014 22:35:00 +0000 (15:35 -0700)
Summary:
waitWithSemaphore currently doesn't support vector<Try<T>>, unless T is void.
Fix that, and also add a now-required void specialization.

Test Plan:
Add a test that uses vector<Try<bool>>, ensure that the tests compile
(and pass).

Reviewed By: hans@fb.com

Subscribers: folly@lists, fugalh

FB internal diff: D1338528

Tasks: 4389473

folly/wangle/Future-inl.h
folly/wangle/Future.h
folly/wangle/test/FutureTest.cpp

index 940d869..df5831d 100644 (file)
@@ -420,18 +420,28 @@ whenN(InputIterator first, InputIterator last, size_t n) {
 }
 
 template <typename F>
-typename std::add_lvalue_reference<typename F::value_type>::type
+typename F::value_type
 waitWithSemaphore(F&& f) {
   LifoSem sem;
-  auto done = f.then([&](Try<typename F::value_type> &&t) {
+  Try<typename F::value_type> done;
+  f.then([&](Try<typename F::value_type> &&t) {
+    done = std::move(t);
     sem.post();
-    return t.value();
   });
   sem.wait();
-  while (!done.isReady()) {}
-  return done.value();
+  return std::move(done.value());
 }
 
+inline void waitWithSemaphore(Future<void>&& f) {
+  LifoSem sem;
+  Try<void> done;
+  f.then([&](Try<void> &&t) {
+    done = std::move(t);
+    sem.post();
+  });
+  sem.wait();
+  return done.value();
+}
 }}
 
 // I haven't included a Future<T&> specialization because I don't forsee us
index 20ecce1..e7d0f41 100644 (file)
@@ -320,7 +320,7 @@ whenN(InputIterator first, InputIterator last, size_t n);
  * you call this, it will deadlock.
  */
 template <class F>
-typename std::add_lvalue_reference<typename F::value_type>::type
+typename F::value_type
 waitWithSemaphore(F&& f);
 
 }} // folly::wangle
index a7a2fa1..84977c7 100644 (file)
@@ -645,6 +645,13 @@ TEST(Future, waitWithSemaphoreImmediate) {
   v_f.push_back(makeFuture());
   auto done_v_f = waitWithSemaphore(whenAll(v_f.begin(), v_f.end()));
   EXPECT_EQ(2, done_v_f.size());
+
+  vector<Future<bool>> v_fb;
+  v_fb.push_back(makeFuture(true));
+  v_fb.push_back(makeFuture(false));
+  auto fut = whenAll(v_fb.begin(), v_fb.end());
+  auto done_v_fb = waitWithSemaphore(std::move(fut));
+  EXPECT_EQ(2, done_v_fb.size());
 }
 
 TEST(Future, waitWithSemaphore) {