system_executor.hpp 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. //
  2. // impl/system_executor.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2022 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) ASIO_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 ASIO_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. ASIO_MOVE_ARG(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. asio_handler_invoke_helpers::invoke(f2.value, 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. ASIO_MOVE_ARG(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. asio_handler_invoke_helpers::invoke(f2.value, 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. ASIO_MOVE_ARG(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 typename decay<Function>::type function_type;
  87. typedef detail::executor_op<function_type, Allocator> op;
  88. typename op::ptr p = { detail::addressof(allocator_),
  89. op::ptr::allocate(allocator_), 0 };
  90. p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), allocator_);
  91. if (is_same<Relationship, execution::relationship_t::continuation_t>::value)
  92. {
  93. ASIO_HANDLER_CREATION((ctx, *p.p,
  94. "system_executor", &ctx, 0, "execute(blk=never,rel=cont)"));
  95. }
  96. else
  97. {
  98. 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(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 ASIO_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. ASIO_MOVE_ARG(Function) f, const OtherAllocator&) const
  116. {
  117. typename decay<Function>::type tmp(ASIO_MOVE_CAST(Function)(f));
  118. asio_handler_invoke_helpers::invoke(tmp, tmp);
  119. }
  120. template <typename Blocking, typename Relationship, typename Allocator>
  121. template <typename Function, typename OtherAllocator>
  122. void basic_system_executor<Blocking, Relationship, Allocator>::post(
  123. ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
  124. {
  125. typedef typename decay<Function>::type function_type;
  126. system_context& ctx = detail::global<system_context>();
  127. // Allocate and construct an operation to wrap the function.
  128. typedef detail::executor_op<function_type, OtherAllocator> op;
  129. typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
  130. p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);
  131. ASIO_HANDLER_CREATION((ctx, *p.p,
  132. "system_executor", &this->context(), 0, "post"));
  133. ctx.scheduler_.post_immediate_completion(p.p, false);
  134. p.v = p.p = 0;
  135. }
  136. template <typename Blocking, typename Relationship, typename Allocator>
  137. template <typename Function, typename OtherAllocator>
  138. void basic_system_executor<Blocking, Relationship, Allocator>::defer(
  139. ASIO_MOVE_ARG(Function) f, const OtherAllocator& a) const
  140. {
  141. typedef typename decay<Function>::type function_type;
  142. system_context& ctx = detail::global<system_context>();
  143. // Allocate and construct an operation to wrap the function.
  144. typedef detail::executor_op<function_type, OtherAllocator> op;
  145. typename op::ptr p = { detail::addressof(a), op::ptr::allocate(a), 0 };
  146. p.p = new (p.v) op(ASIO_MOVE_CAST(Function)(f), a);
  147. ASIO_HANDLER_CREATION((ctx, *p.p,
  148. "system_executor", &this->context(), 0, "defer"));
  149. ctx.scheduler_.post_immediate_completion(p.p, true);
  150. p.v = p.p = 0;
  151. }
  152. #endif // !defined(ASIO_NO_TS_EXECUTORS)
  153. } // namespace asio
  154. #include "asio/detail/pop_options.hpp"
  155. #endif // ASIO_IMPL_SYSTEM_EXECUTOR_HPP