Commit cdcefc75 authored by Lee Howes's avatar Lee Howes Committed by Facebook GitHub Bot

Add explicit future detach operations

Summary: Detach by destruction is common, and for SemiFutures drops the continuation. We can instead make detach an explicit operation, parameterised optionally by an executor, and phase out implicit detach on destruction of SemiFuture.

Reviewed By: yfeldblum, andriigrynenko

Differential Revision: D20683652

fbshipit-source-id: 909d2ffcadbe71501edcddbf0847a9cb12aa3cce
parent d0df6d1f
......@@ -27,6 +27,7 @@
#include <folly/Traits.h>
#include <folly/detail/AsyncTrace.h>
#include <folly/executors/ExecutorWithPriority.h>
#include <folly/executors/GlobalExecutor.h>
#include <folly/executors/InlineExecutor.h>
#include <folly/executors/QueuedImmediateExecutor.h>
#include <folly/futures/detail/Core.h>
......@@ -2581,6 +2582,16 @@ auto ensure(F&& f, Ensure&& ensure) {
});
}
template <class T>
void detachOn(folly::Executor::KeepAlive<> exec, folly::SemiFuture<T>&& fut) {
std::move(fut).via(exec).detach();
}
template <class T>
void detachOnGlobalCPUExecutor(folly::SemiFuture<T>&& fut) {
detachOn(folly::getGlobalCPUExecutor(), std::move(fut));
}
} // namespace futures
template <class Clock>
......
......@@ -452,6 +452,12 @@ DeferredExecutor* getDeferredExecutor(SemiFuture<T>& future);
template <typename T>
futures::detail::DeferredWrapper stealDeferredExecutor(SemiFuture<T>& future);
} // namespace detail
template <class T>
void detachOn(folly::Executor::KeepAlive<> exec, folly::SemiFuture<T>&& fut);
template <class T>
void detachOnGlobalCPUExecutor(folly::SemiFuture<T>&& fut);
} // namespace futures
/// The interface (along with Future) for the consumer-side of a
......@@ -1923,6 +1929,12 @@ class Future : private futures::detail::FutureBase<T> {
friend Future<FT> futures::detail::convertFuture(
SemiFuture<FT>&& sf,
const Future<FT>& f);
using Base::detach;
template <class T2>
friend void futures::detachOn(
folly::Executor::KeepAlive<> exec,
folly::SemiFuture<T2>&& fut);
};
/// A Timekeeper handles the details of keeping time and fulfilling delay
......
......@@ -1440,6 +1440,28 @@ TEST(Future, NoThrow) {
}
}
TEST(Future, DetachTest) {
folly::Baton<> b1, b2;
folly::ManualExecutor exec;
std::atomic<int> result(0);
folly::futures::detachOn(&exec, makeSemiFuture().deferValue([&](auto&&) {
result++;
b1.post();
}));
folly::futures::detachOnGlobalCPUExecutor(
makeSemiFuture().deferValue([&](auto&&) {
result++;
b2.post();
}));
exec.drain();
b1.wait();
b2.wait();
EXPECT_TRUE(result == 2);
}
#if FOLLY_FUTURE_USING_FIBER
TEST(Future, BatonWait) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment