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

Add detach helper to folly::SemiFuture for no executor detach

Summary: Adds a strongly discouraged discard helper for cases where we know there is no deferred work.

Reviewed By: yfeldblum

Differential Revision: D22248947

fbshipit-source-id: 26265c33d9cd10848ab730f9c5f0356eb843025b
parent b99077fa
......@@ -2559,6 +2559,16 @@ void detachOnGlobalCPUExecutor(folly::SemiFuture<T>&& fut) {
detachOn(folly::getGlobalCPUExecutor(), std::move(fut));
}
template <class T>
void detachWithoutExecutor(folly::SemiFuture<T>&& fut) {
auto executor = futures::detail::stealDeferredExecutor(fut);
// Fail if we try to detach a SemiFuture with deferred work
DCHECK(executor.get() == nullptr);
if (executor) {
executor.get()->detach();
}
}
} // namespace futures
template <class Clock>
......
......@@ -451,11 +451,20 @@ template <typename T>
futures::detail::DeferredWrapper stealDeferredExecutor(SemiFuture<T>& future);
} // namespace detail
// Detach the SemiFuture by scheduling work onto exec.
template <class T>
void detachOn(folly::Executor::KeepAlive<> exec, folly::SemiFuture<T>&& fut);
// Detach the SemiFuture by detaching work onto the global CPU executor.
template <class T>
void detachOnGlobalCPUExecutor(folly::SemiFuture<T>&& fut);
// Detach the SemiFuture with no executor.
// NOTE: If there is deferred work of any sort on this SemiFuture
// will leak and not be run.
// Use at your own risk.
template <class T>
void detachWithoutExecutor(folly::SemiFuture<T>&& fut);
} // namespace futures
/// The interface (along with Future) for the consumer-side of a
......
......@@ -1441,7 +1441,7 @@ TEST(Future, NoThrow) {
}
TEST(Future, DetachTest) {
folly::Baton<> b1, b2;
folly::Baton<> b1, b2, b3;
folly::ManualExecutor exec;
std::atomic<int> result(0);
......@@ -1456,10 +1456,22 @@ TEST(Future, DetachTest) {
b2.post();
}));
// This will run correctly, but cleanly detach because we know for sure
// this is safe
folly::futures::detachWithoutExecutor( //
makeSemiFuture()
.via(&exec)
.thenValue([&](auto&&) {
result++;
b3.post();
})
.semi());
exec.drain();
b1.wait();
b2.wait();
EXPECT_TRUE(result == 2);
b3.wait();
EXPECT_TRUE(result == 3);
}
#if FOLLY_FUTURE_USING_FIBER
......
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