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,21 +365,22 @@ class BlockingWaitExecutor final : public folly::DrivableExecutor { ...@@ -365,21 +365,22 @@ 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>
FOLLY_NOINLINE auto operator()(Awaitable&& awaitable) const
-> detail::decay_rvalue_reference_t<await_result_t<Awaitable>> { -> detail::decay_rvalue_reference_t<await_result_t<Awaitable>> {
folly::AsyncStackFrame frame; folly::AsyncStackFrame frame;
frame.setReturnAddress(); frame.setReturnAddress();
...@@ -392,11 +393,11 @@ auto blockingWait(Awaitable&& awaitable) ...@@ -392,11 +393,11 @@ auto blockingWait(Awaitable&& awaitable)
return static_cast<std::add_rvalue_reference_t<await_result_t<Awaitable>>>( return static_cast<std::add_rvalue_reference_t<await_result_t<Awaitable>>>(
detail::makeRefBlockingWaitTask(static_cast<Awaitable&&>(awaitable)) detail::makeRefBlockingWaitTask(static_cast<Awaitable&&>(awaitable))
.get(frame)); .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();
...@@ -413,24 +414,28 @@ FOLLY_NOINLINE auto blockingWait( ...@@ -413,24 +414,28 @@ FOLLY_NOINLINE auto blockingWait(
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