From: Alexander Shaposhnikov Date: Wed, 11 Nov 2015 03:11:56 +0000 (-0800) Subject: Revert my change (which broke down the cont build) X-Git-Tag: deprecate-dynamic-initializer~264 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7ab42fa8f1e672d9c96e9516d84b1c1fb3f0546f;p=folly.git Revert my change (which broke down the cont build) 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 --- diff --git a/folly/futures/Future-inl.h b/folly/futures/Future-inl.h index 5979d183..eeb0e2e5 100644 --- a/folly/futures/Future-inl.h +++ b/folly/futures/Future-inl.h @@ -936,8 +936,18 @@ void waitImpl(Future& f) { if (f.isReady()) return; folly::fibers::Baton baton; - f.setCallback_([&](const Try& t) { baton.post(); }); + f = f.then([&](Try 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 @@ -946,10 +956,19 @@ void waitImpl(Future& f, Duration dur) { if (f.isReady()) return; auto baton = std::make_shared(); - f.setCallback_([baton](const Try& t) { + f = f.then([baton](Try 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