summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/asio/include/asio/impl/dispatch.hpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/asio/include/asio/impl/dispatch.hpp')
-rw-r--r--3rdparty/asio/include/asio/impl/dispatch.hpp247
1 files changed, 209 insertions, 38 deletions
diff --git a/3rdparty/asio/include/asio/impl/dispatch.hpp b/3rdparty/asio/include/asio/impl/dispatch.hpp
index cfebc5cfde0..b602f6fcf41 100644
--- a/3rdparty/asio/include/asio/impl/dispatch.hpp
+++ b/3rdparty/asio/include/asio/impl/dispatch.hpp
@@ -2,7 +2,7 @@
// impl/dispatch.hpp
// ~~~~~~~~~~~~~~~~~
//
-// Copyright (c) 2003-2016 Christopher M. Kohlhoff (chris at kohlhoff dot com)
+// Copyright (c) 2003-2021 Christopher M. Kohlhoff (chris at kohlhoff dot com)
//
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
@@ -19,58 +19,229 @@
#include "asio/associated_allocator.hpp"
#include "asio/associated_executor.hpp"
#include "asio/detail/work_dispatcher.hpp"
+#include "asio/execution/allocator.hpp"
+#include "asio/execution/blocking.hpp"
+#include "asio/prefer.hpp"
#include "asio/detail/push_options.hpp"
namespace asio {
+namespace detail {
-template <typename CompletionToken>
-ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
+class initiate_dispatch
+{
+public:
+ template <typename CompletionHandler>
+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
+ typename enable_if<
+ execution::is_executor<
+ typename associated_executor<
+ typename decay<CompletionHandler>::type
+ >::type
+ >::value
+ >::type* = 0) const
+ {
+ typedef typename decay<CompletionHandler>::type handler_t;
+
+ typename associated_executor<handler_t>::type ex(
+ (get_associated_executor)(handler));
+
+ typename associated_allocator<handler_t>::type alloc(
+ (get_associated_allocator)(handler));
+
+ execution::execute(
+ asio::prefer(ex,
+ execution::blocking.possibly,
+ execution::allocator(alloc)),
+ asio::detail::bind_handler(
+ ASIO_MOVE_CAST(CompletionHandler)(handler)));
+ }
+
+ template <typename CompletionHandler>
+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
+ typename enable_if<
+ !execution::is_executor<
+ typename associated_executor<
+ typename decay<CompletionHandler>::type
+ >::type
+ >::value
+ >::type* = 0) const
+ {
+ typedef typename decay<CompletionHandler>::type handler_t;
+
+ typename associated_executor<handler_t>::type ex(
+ (get_associated_executor)(handler));
+
+ typename associated_allocator<handler_t>::type alloc(
+ (get_associated_allocator)(handler));
+
+ ex.dispatch(asio::detail::bind_handler(
+ ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ }
+};
+
+template <typename Executor>
+class initiate_dispatch_with_executor
+{
+public:
+ typedef Executor executor_type;
+
+ explicit initiate_dispatch_with_executor(const Executor& ex)
+ : ex_(ex)
+ {
+ }
+
+ executor_type get_executor() const ASIO_NOEXCEPT
+ {
+ return ex_;
+ }
+
+ template <typename CompletionHandler>
+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
+ typename enable_if<
+ execution::is_executor<
+ typename conditional<true, executor_type, CompletionHandler>::type
+ >::value
+ >::type* = 0,
+ typename enable_if<
+ !detail::is_work_dispatcher_required<
+ typename decay<CompletionHandler>::type,
+ Executor
+ >::value
+ >::type* = 0) const
+ {
+ typedef typename decay<CompletionHandler>::type handler_t;
+
+ typename associated_allocator<handler_t>::type alloc(
+ (get_associated_allocator)(handler));
+
+ execution::execute(
+ asio::prefer(ex_,
+ execution::blocking.possibly,
+ execution::allocator(alloc)),
+ asio::detail::bind_handler(
+ ASIO_MOVE_CAST(CompletionHandler)(handler)));
+ }
+
+ template <typename CompletionHandler>
+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
+ typename enable_if<
+ execution::is_executor<
+ typename conditional<true, executor_type, CompletionHandler>::type
+ >::value
+ >::type* = 0,
+ typename enable_if<
+ detail::is_work_dispatcher_required<
+ typename decay<CompletionHandler>::type,
+ Executor
+ >::value
+ >::type* = 0) const
+ {
+ typedef typename decay<CompletionHandler>::type handler_t;
+
+ typedef typename associated_executor<
+ handler_t, Executor>::type handler_ex_t;
+ handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
+
+ typename associated_allocator<handler_t>::type alloc(
+ (get_associated_allocator)(handler));
+
+ execution::execute(
+ asio::prefer(ex_,
+ execution::blocking.possibly,
+ execution::allocator(alloc)),
+ detail::work_dispatcher<handler_t, handler_ex_t>(
+ ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));
+ }
+
+ template <typename CompletionHandler>
+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
+ typename enable_if<
+ !execution::is_executor<
+ typename conditional<true, executor_type, CompletionHandler>::type
+ >::value
+ >::type* = 0,
+ typename enable_if<
+ !detail::is_work_dispatcher_required<
+ typename decay<CompletionHandler>::type,
+ Executor
+ >::value
+ >::type* = 0) const
+ {
+ typedef typename decay<CompletionHandler>::type handler_t;
+
+ typename associated_allocator<handler_t>::type alloc(
+ (get_associated_allocator)(handler));
+
+ ex_.dispatch(asio::detail::bind_handler(
+ ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
+ }
+
+ template <typename CompletionHandler>
+ void operator()(ASIO_MOVE_ARG(CompletionHandler) handler,
+ typename enable_if<
+ !execution::is_executor<
+ typename conditional<true, executor_type, CompletionHandler>::type
+ >::value
+ >::type* = 0,
+ typename enable_if<
+ detail::is_work_dispatcher_required<
+ typename decay<CompletionHandler>::type,
+ Executor
+ >::value
+ >::type* = 0) const
+ {
+ typedef typename decay<CompletionHandler>::type handler_t;
+
+ typedef typename associated_executor<
+ handler_t, Executor>::type handler_ex_t;
+ handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
+
+ typename associated_allocator<handler_t>::type alloc(
+ (get_associated_allocator)(handler));
+
+ ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(
+ ASIO_MOVE_CAST(CompletionHandler)(handler),
+ handler_ex), alloc);
+ }
+
+private:
+ Executor ex_;
+};
+
+} // namespace detail
+
+template <ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
+ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
ASIO_MOVE_ARG(CompletionToken) token)
{
- typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
-
- async_completion<CompletionToken, void()> init(token);
-
- typename associated_executor<handler>::type ex(
- (get_associated_executor)(init.completion_handler));
-
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
-
- ex.dispatch(ASIO_MOVE_CAST(handler)(init.completion_handler), alloc);
-
- return init.result.get();
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_dispatch(), token);
}
-template <typename Executor, typename CompletionToken>
-ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
+template <typename Executor,
+ ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
+ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
const Executor& ex, ASIO_MOVE_ARG(CompletionToken) token,
- typename enable_if<is_executor<Executor>::value>::type*)
+ typename constraint<
+ execution::is_executor<Executor>::value || is_executor<Executor>::value
+ >::type)
{
- typedef ASIO_HANDLER_TYPE(CompletionToken, void()) handler;
-
- async_completion<CompletionToken, void()> init(token);
-
- Executor ex1(ex);
-
- typename associated_allocator<handler>::type alloc(
- (get_associated_allocator)(init.completion_handler));
-
- ex1.dispatch(detail::work_dispatcher<handler>(
- init.completion_handler), alloc);
-
- return init.result.get();
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_dispatch_with_executor<Executor>(ex), token);
}
-template <typename ExecutionContext, typename CompletionToken>
-inline ASIO_INITFN_RESULT_TYPE(CompletionToken, void()) dispatch(
+template <typename ExecutionContext,
+ ASIO_COMPLETION_TOKEN_FOR(void()) CompletionToken>
+inline ASIO_INITFN_AUTO_RESULT_TYPE(CompletionToken, void()) dispatch(
ExecutionContext& ctx, ASIO_MOVE_ARG(CompletionToken) token,
- typename enable_if<is_convertible<
- ExecutionContext&, execution_context&>::value>::type*)
+ typename constraint<is_convertible<
+ ExecutionContext&, execution_context&>::value>::type)
{
- return (dispatch)(ctx.get_executor(),
- ASIO_MOVE_CAST(CompletionToken)(token));
+ return async_initiate<CompletionToken, void()>(
+ detail::initiate_dispatch_with_executor<
+ typename ExecutionContext::executor_type>(
+ ctx.get_executor()), token);
}
} // namespace asio