initiate_dispatch.hpp 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. //
  2. // detail/initiate_dispatch.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_ASIO_DETAIL_INITIATE_DISPATCH_HPP
  11. #define BOOST_ASIO_DETAIL_INITIATE_DISPATCH_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include <boost/asio/detail/config.hpp>
  16. #include <boost/asio/associated_allocator.hpp>
  17. #include <boost/asio/associated_executor.hpp>
  18. #include <boost/asio/detail/work_dispatcher.hpp>
  19. #include <boost/asio/execution/allocator.hpp>
  20. #include <boost/asio/execution/blocking.hpp>
  21. #include <boost/asio/prefer.hpp>
  22. #include <boost/asio/detail/push_options.hpp>
  23. namespace boost {
  24. namespace asio {
  25. namespace detail {
  26. class initiate_dispatch
  27. {
  28. public:
  29. template <typename CompletionHandler>
  30. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  31. typename enable_if<
  32. execution::is_executor<
  33. typename associated_executor<
  34. typename decay<CompletionHandler>::type
  35. >::type
  36. >::value
  37. >::type* = 0) const
  38. {
  39. typedef typename decay<CompletionHandler>::type handler_t;
  40. typename associated_executor<handler_t>::type ex(
  41. (get_associated_executor)(handler));
  42. typename associated_allocator<handler_t>::type alloc(
  43. (get_associated_allocator)(handler));
  44. #if defined(BOOST_ASIO_NO_DEPRECATED)
  45. boost::asio::prefer(ex, execution::allocator(alloc)).execute(
  46. boost::asio::detail::bind_handler(
  47. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)));
  48. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  49. execution::execute(
  50. boost::asio::prefer(ex, execution::allocator(alloc)),
  51. boost::asio::detail::bind_handler(
  52. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)));
  53. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  54. }
  55. template <typename CompletionHandler>
  56. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  57. typename enable_if<
  58. !execution::is_executor<
  59. typename associated_executor<
  60. typename decay<CompletionHandler>::type
  61. >::type
  62. >::value
  63. >::type* = 0) const
  64. {
  65. typedef typename decay<CompletionHandler>::type handler_t;
  66. typename associated_executor<handler_t>::type ex(
  67. (get_associated_executor)(handler));
  68. typename associated_allocator<handler_t>::type alloc(
  69. (get_associated_allocator)(handler));
  70. ex.dispatch(boost::asio::detail::bind_handler(
  71. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
  72. }
  73. };
  74. template <typename Executor>
  75. class initiate_dispatch_with_executor
  76. {
  77. public:
  78. typedef Executor executor_type;
  79. explicit initiate_dispatch_with_executor(const Executor& ex)
  80. : ex_(ex)
  81. {
  82. }
  83. executor_type get_executor() const BOOST_ASIO_NOEXCEPT
  84. {
  85. return ex_;
  86. }
  87. template <typename CompletionHandler>
  88. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  89. typename enable_if<
  90. execution::is_executor<
  91. typename conditional<true, executor_type, CompletionHandler>::type
  92. >::value
  93. >::type* = 0,
  94. typename enable_if<
  95. !detail::is_work_dispatcher_required<
  96. typename decay<CompletionHandler>::type,
  97. Executor
  98. >::value
  99. >::type* = 0) const
  100. {
  101. typedef typename decay<CompletionHandler>::type handler_t;
  102. typename associated_allocator<handler_t>::type alloc(
  103. (get_associated_allocator)(handler));
  104. #if defined(BOOST_ASIO_NO_DEPRECATED)
  105. boost::asio::prefer(ex_, execution::allocator(alloc)).execute(
  106. boost::asio::detail::bind_handler(
  107. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)));
  108. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  109. execution::execute(
  110. boost::asio::prefer(ex_, execution::allocator(alloc)),
  111. boost::asio::detail::bind_handler(
  112. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)));
  113. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  114. }
  115. template <typename CompletionHandler>
  116. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  117. typename enable_if<
  118. execution::is_executor<
  119. typename conditional<true, executor_type, CompletionHandler>::type
  120. >::value
  121. >::type* = 0,
  122. typename enable_if<
  123. detail::is_work_dispatcher_required<
  124. typename decay<CompletionHandler>::type,
  125. Executor
  126. >::value
  127. >::type* = 0) const
  128. {
  129. typedef typename decay<CompletionHandler>::type handler_t;
  130. typedef typename associated_executor<
  131. handler_t, Executor>::type handler_ex_t;
  132. handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
  133. typename associated_allocator<handler_t>::type alloc(
  134. (get_associated_allocator)(handler));
  135. #if defined(BOOST_ASIO_NO_DEPRECATED)
  136. boost::asio::prefer(ex_, execution::allocator(alloc)).execute(
  137. detail::work_dispatcher<handler_t, handler_ex_t>(
  138. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));
  139. #else // defined(BOOST_ASIO_NO_DEPRECATED)
  140. execution::execute(
  141. boost::asio::prefer(ex_, execution::allocator(alloc)),
  142. detail::work_dispatcher<handler_t, handler_ex_t>(
  143. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler), handler_ex));
  144. #endif // defined(BOOST_ASIO_NO_DEPRECATED)
  145. }
  146. template <typename CompletionHandler>
  147. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  148. typename enable_if<
  149. !execution::is_executor<
  150. typename conditional<true, executor_type, CompletionHandler>::type
  151. >::value
  152. >::type* = 0,
  153. typename enable_if<
  154. !detail::is_work_dispatcher_required<
  155. typename decay<CompletionHandler>::type,
  156. Executor
  157. >::value
  158. >::type* = 0) const
  159. {
  160. typedef typename decay<CompletionHandler>::type handler_t;
  161. typename associated_allocator<handler_t>::type alloc(
  162. (get_associated_allocator)(handler));
  163. ex_.dispatch(boost::asio::detail::bind_handler(
  164. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler)), alloc);
  165. }
  166. template <typename CompletionHandler>
  167. void operator()(BOOST_ASIO_MOVE_ARG(CompletionHandler) handler,
  168. typename enable_if<
  169. !execution::is_executor<
  170. typename conditional<true, executor_type, CompletionHandler>::type
  171. >::value
  172. >::type* = 0,
  173. typename enable_if<
  174. detail::is_work_dispatcher_required<
  175. typename decay<CompletionHandler>::type,
  176. Executor
  177. >::value
  178. >::type* = 0) const
  179. {
  180. typedef typename decay<CompletionHandler>::type handler_t;
  181. typedef typename associated_executor<
  182. handler_t, Executor>::type handler_ex_t;
  183. handler_ex_t handler_ex((get_associated_executor)(handler, ex_));
  184. typename associated_allocator<handler_t>::type alloc(
  185. (get_associated_allocator)(handler));
  186. ex_.dispatch(detail::work_dispatcher<handler_t, handler_ex_t>(
  187. BOOST_ASIO_MOVE_CAST(CompletionHandler)(handler),
  188. handler_ex), alloc);
  189. }
  190. private:
  191. Executor ex_;
  192. };
  193. } // namespace detail
  194. } // namespace asio
  195. } // namespace boost
  196. #include <boost/asio/detail/pop_options.hpp>
  197. #endif // BOOST_ASIO_DETAIL_INITIATE_DISPATCH_HPP