work_dispatcher.hpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. //
  2. // detail/work_dispatcher.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2024 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_WORK_DISPATCHER_HPP
  11. #define BOOST_ASIO_DETAIL_WORK_DISPATCHER_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/detail/bind_handler.hpp>
  17. #include <boost/asio/detail/type_traits.hpp>
  18. #include <boost/asio/associated_executor.hpp>
  19. #include <boost/asio/associated_allocator.hpp>
  20. #include <boost/asio/executor_work_guard.hpp>
  21. #include <boost/asio/execution/executor.hpp>
  22. #include <boost/asio/execution/allocator.hpp>
  23. #include <boost/asio/execution/blocking.hpp>
  24. #include <boost/asio/execution/outstanding_work.hpp>
  25. #include <boost/asio/prefer.hpp>
  26. #include <boost/asio/detail/push_options.hpp>
  27. namespace boost {
  28. namespace asio {
  29. namespace detail {
  30. template <typename Handler, typename Executor, typename = void>
  31. struct is_work_dispatcher_required : true_type
  32. {
  33. };
  34. template <typename Handler, typename Executor>
  35. struct is_work_dispatcher_required<Handler, Executor,
  36. enable_if_t<
  37. is_same<
  38. typename associated_executor<Handler,
  39. Executor>::asio_associated_executor_is_unspecialised,
  40. void
  41. >::value
  42. >> : false_type
  43. {
  44. };
  45. template <typename Handler, typename Executor, typename = void>
  46. class work_dispatcher
  47. {
  48. public:
  49. template <typename CompletionHandler>
  50. work_dispatcher(CompletionHandler&& handler,
  51. const Executor& handler_ex)
  52. : handler_(static_cast<CompletionHandler&&>(handler)),
  53. executor_(boost::asio::prefer(handler_ex,
  54. execution::outstanding_work.tracked))
  55. {
  56. }
  57. work_dispatcher(const work_dispatcher& other)
  58. : handler_(other.handler_),
  59. executor_(other.executor_)
  60. {
  61. }
  62. work_dispatcher(work_dispatcher&& other)
  63. : handler_(static_cast<Handler&&>(other.handler_)),
  64. executor_(static_cast<work_executor_type&&>(other.executor_))
  65. {
  66. }
  67. void operator()()
  68. {
  69. associated_allocator_t<Handler> alloc((get_associated_allocator)(handler_));
  70. boost::asio::prefer(executor_, execution::allocator(alloc)).execute(
  71. boost::asio::detail::bind_handler(
  72. static_cast<Handler&&>(handler_)));
  73. }
  74. private:
  75. typedef decay_t<
  76. prefer_result_t<const Executor&,
  77. execution::outstanding_work_t::tracked_t
  78. >
  79. > work_executor_type;
  80. Handler handler_;
  81. work_executor_type executor_;
  82. };
  83. #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  84. template <typename Handler, typename Executor>
  85. class work_dispatcher<Handler, Executor,
  86. enable_if_t<!execution::is_executor<Executor>::value>>
  87. {
  88. public:
  89. template <typename CompletionHandler>
  90. work_dispatcher(CompletionHandler&& handler, const Executor& handler_ex)
  91. : work_(handler_ex),
  92. handler_(static_cast<CompletionHandler&&>(handler))
  93. {
  94. }
  95. work_dispatcher(const work_dispatcher& other)
  96. : work_(other.work_),
  97. handler_(other.handler_)
  98. {
  99. }
  100. work_dispatcher(work_dispatcher&& other)
  101. : work_(static_cast<executor_work_guard<Executor>&&>(other.work_)),
  102. handler_(static_cast<Handler&&>(other.handler_))
  103. {
  104. }
  105. void operator()()
  106. {
  107. associated_allocator_t<Handler> alloc((get_associated_allocator)(handler_));
  108. work_.get_executor().dispatch(
  109. boost::asio::detail::bind_handler(
  110. static_cast<Handler&&>(handler_)), alloc);
  111. work_.reset();
  112. }
  113. private:
  114. executor_work_guard<Executor> work_;
  115. Handler handler_;
  116. };
  117. #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  118. } // namespace detail
  119. } // namespace asio
  120. } // namespace boost
  121. #include <boost/asio/detail/pop_options.hpp>
  122. #endif // BOOST_ASIO_DETAIL_WORK_DISPATCHER_HPP