Revert my change (which broke down the cont build)
authorAlexander Shaposhnikov <alexshap@fb.com>
Wed, 11 Nov 2015 03:11:56 +0000 (19:11 -0800)
committerfacebook-github-bot-9 <folly-bot@fb.com>
Wed, 11 Nov 2015 03:20:21 +0000 (19:20 -0800)
Summary: hg backout -r c9f7b5f3185a
Revert my change (which broke down the cont build t9048692)

Reviewed By: djwatson

Differential Revision: D2640797

fb-gh-sync-id: 51f196ac5a3560fde4dc8fe7bb6ef278d74136e5

folly/futures/Future-inl.h

index 5979d183c35622bf079ea35762ae957cea1dc851..eeb0e2e56e759308d0862afab33ce0a42ee11b41 100644 (file)
@@ -936,8 +936,18 @@ void waitImpl(Future<T>& f) {
   if (f.isReady()) return;
 
   folly::fibers::Baton baton;
-  f.setCallback_([&](const Try<T>& t) { baton.post(); });
+  f = f.then([&](Try<T> t) {
+    baton.post();
+    return makeFuture(std::move(t));
+  });
   baton.wait();
+
+  // There's a race here between the return here and the actual finishing of
+  // the future. f is completed, but the setup may not have finished on done
+  // after the baton has posted.
+  while (!f.isReady()) {
+    std::this_thread::yield();
+  }
 }
 
 template <class T>
@@ -946,10 +956,19 @@ void waitImpl(Future<T>& f, Duration dur) {
   if (f.isReady()) return;
 
   auto baton = std::make_shared<folly::fibers::Baton>();
-  f.setCallback_([baton](const Try<T>& t) {
+  f = f.then([baton](Try<T> t) {
     baton->post();
+    return makeFuture(std::move(t));
   });
-  baton->timed_wait(dur);
+
+  // Let's preserve the invariant that if we did not timeout (timed_wait returns
+  // true), then the returned Future is complete when it is returned to the
+  // caller. We need to wait out the race for that Future to complete.
+  if (baton->timed_wait(dur)) {
+    while (!f.isReady()) {
+      std::this_thread::yield();
+    }
+  }
 }
 
 template <class T>