system_executor.hpp 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. //
  2. // impl/system_executor.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_IMPL_SYSTEM_EXECUTOR_HPP
  11. #define BOOST_ASIO_IMPL_SYSTEM_EXECUTOR_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/executor_op.hpp>
  16. #include <boost/asio/detail/global.hpp>
  17. #include <boost/asio/detail/type_traits.hpp>
  18. #include <boost/asio/system_context.hpp>
  19. #include <boost/asio/detail/push_options.hpp>
  20. namespace boost {
  21. namespace asio {
  22. template <typename Blocking, typename Relationship, typename Allocator>
  23. inline system_context&
  24. basic_system_executor<Blocking, Relationship, Allocator>::query(
  25. execution::context_t) noexcept
  26. {
  27. return detail::global<system_context>();
  28. }
  29. template <typename Blocking, typename Relationship, typename Allocator>
  30. inline std::size_t
  31. basic_system_executor<Blocking, Relationship, Allocator>::query(
  32. execution::occupancy_t) const noexcept
  33. {
  34. return detail::global<system_context>().num_threads_;
  35. }
  36. template <typename Blocking, typename Relationship, typename Allocator>
  37. template <typename Function>
  38. inline void
  39. basic_system_executor<Blocking, Relationship, Allocator>::do_execute(
  40. Function&& f, execution::blocking_t::possibly_t) const
  41. {
  42. // Obtain a non-const instance of the function.
  43. detail::non_const_lvalue<Function> f2(f);
  44. #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
  45. try
  46. {
  47. #endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
  48. detail::fenced_block b(detail::fenced_block::full);
  49. static_cast<decay_t<Function>&&>(f2.value)();
  50. #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
  51. }
  52. catch (...)
  53. {
  54. std::terminate();
  55. }
  56. #endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
  57. }
  58. template <typename Blocking, typename Relationship, typename Allocator>
  59. template <typename Function>
  60. inline void
  61. basic_system_executor<Blocking, Relationship, Allocator>::do_execute(
  62. Function&& f, execution::blocking_t::always_t) const
  63. {
  64. // Obtain a non-const instance of the function.
  65. detail::non_const_lvalue<Function> f2(f);
  66. #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
  67. try
  68. {
  69. #endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
  70. detail::fenced_block b(detail::fenced_block::full);
  71. static_cast<decay_t<Function>&&>(f2.value)();
  72. #if !defined(BOOST_ASIO_NO_EXCEPTIONS)
  73. }
  74. catch (...)
  75. {
  76. std::terminate();
  77. }
  78. #endif// !defined(BOOST_ASIO_NO_EXCEPTIONS)
  79. }
  80. template <typename Blocking, typename Relationship, typename Allocator>
  81. template <typename Function>
  82. void basic_system_executor<Blocking, Relationship, Allocator>::do_execute(
  83. Function&& f, execution::blocking_t::never_t) const
  84. {
  85. system_context& ctx = detail::global<system_context>();
  86. // Allocate and construct an operation to wrap the function.
  87. typedef detail::executor_op<decay_t<Function>, Allocator> op;
  88. typename op::ptr p = { detail::addressof(allocator_),
  89. op::ptr::allocate(allocator_), 0 };
  90. p.p = new (p.v) op(static_cast<Function&&>(f), allocator_);
  91. if (is_same<Relationship, execution::relationship_t::continuation_t>::value)
  92. {
  93. BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
  94. "system_executor", &ctx, 0, "execute(blk=never,rel=cont)"));
  95. }
  96. else
  97. {
  98. BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
  99. "system_executor", &ctx, 0, "execute(blk=never,rel=fork)"));
  100. }
  101. ctx.scheduler_.post_immediate_completion(p.p,
  102. is_same<Relationship, execution::relationship_t::continuation_t>::value);
  103. p.v = p.p = 0;
  104. }
  105. #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  106. template <typename Blocking, typename Relationship, typename Allocator>
  107. inline system_context& basic_system_executor<
  108. Blocking, Relationship, Allocator>::context() const noexcept
  109. {
  110. return detail::global<system_context>();
  111. }
  112. template <typename Blocking, typename Relationship, typename Allocator>
  113. template <typename Function, typename OtherAllocator>
  114. void basic_system_executor<Blocking, Relationship, Allocator>::dispatch(
  115. Function&& f, const OtherAllocator&) const
  116. {
  117. decay_t<Function>(static_cast<Function&&>(f))();
  118. }
  119. template <typename Blocking, typename Relationship, typename Allocator>
  120. template <typename Function, typename OtherAllocator>
  121. void basic_system_executor<Blocking, Relationship, Allocator>::post(
  122. Function&& f, const OtherAllocator& a) const
  123. {
  124. system_context& ctx = detail::global<system_context>();
  125. // Allocate and construct an operation to wrap the function.
  126. typedef detail::executor_op<decay_t<Function>, OtherAllocator> op;
  127. typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
  128. p.p = new (p.v) op(static_cast<Function&&>(f), a);
  129. BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
  130. "system_executor", &this->context(), 0, "post"));
  131. ctx.scheduler_.post_immediate_completion(p.p, false);
  132. p.v = p.p = 0;
  133. }
  134. template <typename Blocking, typename Relationship, typename Allocator>
  135. template <typename Function, typename OtherAllocator>
  136. void basic_system_executor<Blocking, Relationship, Allocator>::defer(
  137. Function&& f, const OtherAllocator& a) const
  138. {
  139. system_context& ctx = detail::global<system_context>();
  140. // Allocate and construct an operation to wrap the function.
  141. typedef detail::executor_op<decay_t<Function>, OtherAllocator> op;
  142. typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
  143. p.p = new (p.v) op(static_cast<Function&&>(f), a);
  144. BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
  145. "system_executor", &this->context(), 0, "defer"));
  146. ctx.scheduler_.post_immediate_completion(p.p, true);
  147. p.v = p.p = 0;
  148. }
  149. #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  150. } // namespace asio
  151. } // namespace boost
  152. #include <boost/asio/detail/pop_options.hpp>
  153. #endif // BOOST_ASIO_IMPL_SYSTEM_EXECUTOR_HPP