system_executor.hpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. //
  2. // impl/system_executor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2021 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) BOOST_ASIO_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 BOOST_ASIO_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. BOOST_ASIO_MOVE_ARG(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. boost_asio_handler_invoke_helpers::invoke(f2.value, 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. BOOST_ASIO_MOVE_ARG(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. boost_asio_handler_invoke_helpers::invoke(f2.value, 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. BOOST_ASIO_MOVE_ARG(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 typename decay<Function>::type function_type;
  88. typedef detail::executor_op<function_type, Allocator> op;
  89. typename op::ptr p = { detail::addressof(allocator_),
  90. op::ptr::allocate(allocator_), 0 };
  91. p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), allocator_);
  92. if (is_same<Relationship, execution::relationship_t::continuation_t>::value)
  93. {
  94. BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
  95. "system_executor", &ctx, 0, "execute(blk=never,rel=cont)"));
  96. }
  97. else
  98. {
  99. BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
  100. "system_executor", &ctx, 0, "execute(blk=never,rel=fork)"));
  101. }
  102. ctx.scheduler_.post_immediate_completion(p.p,
  103. is_same<Relationship, execution::relationship_t::continuation_t>::value);
  104. p.v = p.p = 0;
  105. }
  106. #if !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  107. template <typename Blocking, typename Relationship, typename Allocator>
  108. inline system_context& basic_system_executor<
  109. Blocking, Relationship, Allocator>::context() const BOOST_ASIO_NOEXCEPT
  110. {
  111. return detail::global<system_context>();
  112. }
  113. template <typename Blocking, typename Relationship, typename Allocator>
  114. template <typename Function, typename OtherAllocator>
  115. void basic_system_executor<Blocking, Relationship, Allocator>::dispatch(
  116. BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator&) const
  117. {
  118. typename decay<Function>::type tmp(BOOST_ASIO_MOVE_CAST(Function)(f));
  119. boost_asio_handler_invoke_helpers::invoke(tmp, tmp);
  120. }
  121. template <typename Blocking, typename Relationship, typename Allocator>
  122. template <typename Function, typename OtherAllocator>
  123. void basic_system_executor<Blocking, Relationship, Allocator>::post(
  124. BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
  125. {
  126. typedef typename decay<Function>::type function_type;
  127. system_context& ctx = detail::global<system_context>();
  128. // Allocate and construct an operation to wrap the function.
  129. typedef detail::executor_op<function_type, OtherAllocator> op;
  130. typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
  131. p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
  132. BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
  133. "system_executor", &this->context(), 0, "post"));
  134. ctx.scheduler_.post_immediate_completion(p.p, false);
  135. p.v = p.p = 0;
  136. }
  137. template <typename Blocking, typename Relationship, typename Allocator>
  138. template <typename Function, typename OtherAllocator>
  139. void basic_system_executor<Blocking, Relationship, Allocator>::defer(
  140. BOOST_ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
  141. {
  142. typedef typename decay<Function>::type function_type;
  143. system_context& ctx = detail::global<system_context>();
  144. // Allocate and construct an operation to wrap the function.
  145. typedef detail::executor_op<function_type, OtherAllocator> op;
  146. typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
  147. p.p = new (p.v) op(BOOST_ASIO_MOVE_CAST(Function)(f), a);
  148. BOOST_ASIO_HANDLER_CREATION((ctx, *p.p,
  149. "system_executor", &this->context(), 0, "defer"));
  150. ctx.scheduler_.post_immediate_completion(p.p, true);
  151. p.v = p.p = 0;
  152. }
  153. #endif // !defined(BOOST_ASIO_NO_TS_EXECUTORS)
  154. } // namespace asio
  155. } // namespace boost
  156. #include <boost/asio/detail/pop_options.hpp>
  157. #endif // BOOST_ASIO_IMPL_SYSTEM_EXECUTOR_HPP