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