system_executor.hpp 5.6 KB

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