Commit 30ba5616 authored by Yedidya Feldblum's avatar Yedidya Feldblum Committed by Facebook GitHub Bot

let blocking_wait be insusceptible to ADL

Summary: As a standing rule, let us not have our things be susceptible to ADL except when we very consciously and very specifically want an extension point.

Reviewed By: aary

Differential Revision: D26678138

fbshipit-source-id: 9f845dbc5ed95aaecf4d6cd256aedd0b240e00d3
parent 02177495
......@@ -365,72 +365,77 @@ class BlockingWaitExecutor final : public folly::DrivableExecutor {
} // namespace detail
/// blockingWait(Awaitable&&) -> await_result_t<Awaitable>
/// blocking_wait_fn
///
/// This function co_awaits the passed awaitable object and blocks the current
/// thread until the operation completes.
/// Awaits co_awaits the passed awaitable and blocks the current thread until
/// the await operation completes.
///
/// This is useful for launching an asynchronous operation from the top-level
/// main() function or from unit-tests.
/// Useful for launching an asynchronous operation from the top-level main()
/// function or from unit-tests.
///
/// WARNING:
/// Avoid using this function within any code that might run on the thread
/// of an executor as this can potentially lead to deadlock if the operation
/// you are waiting on needs to do some work on that executor in order to
/// complete.
template <typename Awaitable>
auto blockingWait(Awaitable&& awaitable)
-> detail::decay_rvalue_reference_t<await_result_t<Awaitable>> {
folly::AsyncStackFrame frame;
frame.setReturnAddress();
folly::AsyncStackRoot stackRoot;
stackRoot.setNextRoot(folly::tryGetCurrentAsyncStackRoot());
stackRoot.setStackFrameContext();
stackRoot.setTopFrame(frame);
return static_cast<std::add_rvalue_reference_t<await_result_t<Awaitable>>>(
detail::makeRefBlockingWaitTask(static_cast<Awaitable&&>(awaitable))
.get(frame));
}
struct blocking_wait_fn {
template <typename Awaitable>
FOLLY_NOINLINE auto operator()(Awaitable&& awaitable) const
-> detail::decay_rvalue_reference_t<await_result_t<Awaitable>> {
folly::AsyncStackFrame frame;
frame.setReturnAddress();
folly::AsyncStackRoot stackRoot;
stackRoot.setNextRoot(folly::tryGetCurrentAsyncStackRoot());
stackRoot.setStackFrameContext();
stackRoot.setTopFrame(frame);
return static_cast<std::add_rvalue_reference_t<await_result_t<Awaitable>>>(
detail::makeRefBlockingWaitTask(static_cast<Awaitable&&>(awaitable))
.get(frame));
}
template <typename SemiAwaitable>
FOLLY_NOINLINE auto blockingWait(
SemiAwaitable&& awaitable, folly::DrivableExecutor* executor)
-> detail::decay_rvalue_reference_t<semi_await_result_t<SemiAwaitable>> {
folly::AsyncStackFrame frame;
frame.setReturnAddress();
folly::AsyncStackRoot stackRoot;
stackRoot.setNextRoot(folly::tryGetCurrentAsyncStackRoot());
stackRoot.setStackFrameContext();
stackRoot.setTopFrame(frame);
return static_cast<
std::add_rvalue_reference_t<semi_await_result_t<SemiAwaitable>>>(
detail::makeRefBlockingWaitTask(
folly::coro::co_viaIfAsync(
folly::getKeepAliveToken(executor),
static_cast<SemiAwaitable&&>(awaitable)))
.getVia(executor, frame));
}
template <typename SemiAwaitable>
FOLLY_NOINLINE auto operator()(
SemiAwaitable&& awaitable, folly::DrivableExecutor* executor) const
-> detail::decay_rvalue_reference_t<semi_await_result_t<SemiAwaitable>> {
folly::AsyncStackFrame frame;
frame.setReturnAddress();
folly::AsyncStackRoot stackRoot;
stackRoot.setNextRoot(folly::tryGetCurrentAsyncStackRoot());
stackRoot.setStackFrameContext();
stackRoot.setTopFrame(frame);
return static_cast<
std::add_rvalue_reference_t<semi_await_result_t<SemiAwaitable>>>(
detail::makeRefBlockingWaitTask(
folly::coro::co_viaIfAsync(
folly::getKeepAliveToken(executor),
static_cast<SemiAwaitable&&>(awaitable)))
.getVia(executor, frame));
}
template <
typename SemiAwaitable,
std::enable_if_t<!is_awaitable_v<SemiAwaitable>, int> = 0>
auto blockingWait(SemiAwaitable&& awaitable)
-> detail::decay_rvalue_reference_t<semi_await_result_t<SemiAwaitable>> {
std::exception_ptr eptr;
{
detail::BlockingWaitExecutor executor;
try {
return blockingWait(static_cast<SemiAwaitable&&>(awaitable), &executor);
} catch (...) {
eptr = std::current_exception();
template <
typename SemiAwaitable,
std::enable_if_t<!is_awaitable_v<SemiAwaitable>, int> = 0>
auto operator()(SemiAwaitable&& awaitable) const
-> detail::decay_rvalue_reference_t<semi_await_result_t<SemiAwaitable>> {
std::exception_ptr eptr;
{
detail::BlockingWaitExecutor executor;
try {
return operator()(static_cast<SemiAwaitable&&>(awaitable), &executor);
} catch (...) {
eptr = std::current_exception();
}
}
std::rethrow_exception(eptr);
}
std::rethrow_exception(eptr);
}
};
inline constexpr blocking_wait_fn blocking_wait{};
static constexpr blocking_wait_fn const& blockingWait =
blocking_wait; // backcompat
} // namespace coro
} // namespace folly
......
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