From: Phil Willoughby Date: Mon, 26 Sep 2016 11:59:05 +0000 (-0700) Subject: Make a SharedPromise from a Future X-Git-Tag: v2016.10.03.00~16 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8bed062637f2af0e85fb5fd4365476e28e18d078;p=folly.git Make a SharedPromise from a Future Summary: Makes it easy to split a Future into multiple Futures Reviewed By: rongrong Differential Revision: D3885897 fbshipit-source-id: 6ac9fb22444dd828fbdebb44b06bf3d93d0f7583 --- diff --git a/folly/futures/SharedPromise-inl.h b/folly/futures/SharedPromise-inl.h index 90d0dd3d..490e0864 100644 --- a/folly/futures/SharedPromise-inl.h +++ b/folly/futures/SharedPromise-inl.h @@ -47,6 +47,11 @@ SharedPromise& SharedPromise::operator=( return *this; } +template +SharedPromise::SharedPromise(Future future) { + future.then(&SharedPromise::setTry, this); +} + template size_t SharedPromise::size() { std::lock_guard g(mutex_); diff --git a/folly/futures/SharedPromise.h b/folly/futures/SharedPromise.h index cdc284dd..d1f8a949 100644 --- a/folly/futures/SharedPromise.h +++ b/folly/futures/SharedPromise.h @@ -46,6 +46,13 @@ public: SharedPromise(SharedPromise&&) noexcept; SharedPromise& operator=(SharedPromise&&) noexcept; + /** + * Provide a way to split a Future. Note that while the Futures from + * `getFuture()' depend on the completion of the parameter Future they do not + * inherit any other properties such as Executor's passed to `via' etc. + */ + explicit SharedPromise(Future); + /** * Return a Future tied to the shared core state. Unlike Promise::getFuture, * this can be called an unlimited number of times per SharedPromise. diff --git a/folly/futures/test/SharedPromiseTest.cpp b/folly/futures/test/SharedPromiseTest.cpp index 36b5169b..b7245cc0 100644 --- a/folly/futures/test/SharedPromiseTest.cpp +++ b/folly/futures/test/SharedPromiseTest.cpp @@ -125,3 +125,33 @@ TEST(SharedPromise, interruptHandler) { f.cancel(); EXPECT_TRUE(flag); } + +TEST(SharedPromise, splitFutureSuccess) { + Promise p; + SharedPromise sp(p.getFuture()); + auto f1 = sp.getFuture(); + EXPECT_FALSE(f1.isReady()); + p.setValue(1); + EXPECT_TRUE(f1.isReady()); + EXPECT_TRUE(f1.hasValue()); + auto f2 = sp.getFuture(); + EXPECT_TRUE(f2.isReady()); + EXPECT_TRUE(f2.hasValue()); +} + +TEST(SharedPromise, splitFutureFailure) { + Promise p; + SharedPromise sp(p.getFuture()); + auto f1 = sp.getFuture(); + EXPECT_FALSE(f1.isReady()); + try { + throw std::runtime_error("Oops"); + } catch (...) { + p.setException(exception_wrapper(std::current_exception())); + } + EXPECT_TRUE(f1.isReady()); + EXPECT_TRUE(f1.hasException()); + auto f2 = sp.getFuture(); + EXPECT_TRUE(f2.isReady()); + EXPECT_TRUE(f2.hasException()); +}