cancel_after.hpp 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. //
  2. // impl/cancel_after.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_CANCEL_AFTER_HPP
  11. #define BOOST_ASIO_IMPL_CANCEL_AFTER_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/associated_executor.hpp>
  17. #include <boost/asio/async_result.hpp>
  18. #include <boost/asio/detail/initiation_base.hpp>
  19. #include <boost/asio/detail/timed_cancel_op.hpp>
  20. #include <boost/asio/detail/push_options.hpp>
  21. namespace boost {
  22. namespace asio {
  23. namespace detail {
  24. template <typename Initiation, typename Clock,
  25. typename WaitTraits, typename... Signatures>
  26. struct initiate_cancel_after : initiation_base<Initiation>
  27. {
  28. using initiation_base<Initiation>::initiation_base;
  29. template <typename Handler, typename Rep, typename Period, typename... Args>
  30. void operator()(Handler&& handler,
  31. const chrono::duration<Rep, Period>& timeout,
  32. cancellation_type_t cancel_type, Args&&... args) &&
  33. {
  34. using op = detail::timed_cancel_op<decay_t<Handler>,
  35. basic_waitable_timer<Clock, WaitTraits>, Signatures...>;
  36. non_const_lvalue<Handler> handler2(handler);
  37. typename op::ptr p = { boost::asio::detail::addressof(handler2.value),
  38. op::ptr::allocate(handler2.value), 0 };
  39. p.p = new (p.v) op(handler2.value,
  40. basic_waitable_timer<Clock, WaitTraits,
  41. typename Initiation::executor_type>(this->get_executor(), timeout),
  42. cancel_type);
  43. op* o = p.p;
  44. p.v = p.p = 0;
  45. o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);
  46. }
  47. template <typename Handler, typename Rep, typename Period, typename... Args>
  48. void operator()(Handler&& handler,
  49. const chrono::duration<Rep, Period>& timeout,
  50. cancellation_type_t cancel_type, Args&&... args) const &
  51. {
  52. using op = detail::timed_cancel_op<decay_t<Handler>,
  53. basic_waitable_timer<Clock, WaitTraits>, Signatures...>;
  54. non_const_lvalue<Handler> handler2(handler);
  55. typename op::ptr p = { boost::asio::detail::addressof(handler2.value),
  56. op::ptr::allocate(handler2.value), 0 };
  57. p.p = new (p.v) op(handler2.value,
  58. basic_waitable_timer<Clock, WaitTraits,
  59. typename Initiation::executor_type>(this->get_executor(), timeout),
  60. cancel_type);
  61. op* o = p.p;
  62. p.v = p.p = 0;
  63. o->start(static_cast<const Initiation&>(*this),
  64. static_cast<Args&&>(args)...);
  65. }
  66. };
  67. template <typename Initiation, typename Clock,
  68. typename WaitTraits, typename Executor, typename... Signatures>
  69. struct initiate_cancel_after_timer : initiation_base<Initiation>
  70. {
  71. using initiation_base<Initiation>::initiation_base;
  72. template <typename Handler, typename Rep, typename Period, typename... Args>
  73. void operator()(Handler&& handler,
  74. basic_waitable_timer<Clock, WaitTraits, Executor>* timer,
  75. const chrono::duration<Rep, Period>& timeout,
  76. cancellation_type_t cancel_type, Args&&... args) &&
  77. {
  78. using op = detail::timed_cancel_op<decay_t<Handler>,
  79. basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;
  80. non_const_lvalue<Handler> handler2(handler);
  81. typename op::ptr p = { boost::asio::detail::addressof(handler2.value),
  82. op::ptr::allocate(handler2.value), 0 };
  83. timer->expires_after(timeout);
  84. p.p = new (p.v) op(handler2.value, *timer, cancel_type);
  85. op* o = p.p;
  86. p.v = p.p = 0;
  87. o->start(static_cast<Initiation&&>(*this), static_cast<Args&&>(args)...);
  88. }
  89. template <typename Handler, typename Rep, typename Period, typename... Args>
  90. void operator()(Handler&& handler,
  91. basic_waitable_timer<Clock, WaitTraits, Executor>* timer,
  92. const chrono::duration<Rep, Period>& timeout,
  93. cancellation_type_t cancel_type, Args&&... args) const &
  94. {
  95. using op = detail::timed_cancel_op<decay_t<Handler>,
  96. basic_waitable_timer<Clock, WaitTraits, Executor>&, Signatures...>;
  97. non_const_lvalue<Handler> handler2(handler);
  98. typename op::ptr p = { boost::asio::detail::addressof(handler2.value),
  99. op::ptr::allocate(handler2.value), 0 };
  100. timer->expires_after(timeout);
  101. p.p = new (p.v) op(handler2.value, *timer, cancel_type);
  102. op* o = p.p;
  103. p.v = p.p = 0;
  104. o->start(static_cast<const Initiation&>(*this),
  105. static_cast<Args&&>(args)...);
  106. }
  107. };
  108. } // namespace detail
  109. #if !defined(GENERATING_DOCUMENTATION)
  110. template <typename CompletionToken, typename Clock,
  111. typename WaitTraits, typename... Signatures>
  112. struct async_result<
  113. cancel_after_t<CompletionToken, Clock, WaitTraits>, Signatures...>
  114. : async_result<CompletionToken, Signatures...>
  115. {
  116. template <typename Initiation, typename RawCompletionToken, typename... Args>
  117. static auto initiate(Initiation&& initiation,
  118. RawCompletionToken&& token, Args&&... args)
  119. -> decltype(
  120. async_initiate<
  121. conditional_t<
  122. is_const<remove_reference_t<RawCompletionToken>>::value,
  123. const CompletionToken, CompletionToken>,
  124. Signatures...>(
  125. declval<detail::initiate_cancel_after<
  126. decay_t<Initiation>, Clock, WaitTraits, Signatures...>>(),
  127. token.token_, token.timeout_, token.cancel_type_,
  128. static_cast<Args&&>(args)...))
  129. {
  130. return async_initiate<
  131. conditional_t<
  132. is_const<remove_reference_t<RawCompletionToken>>::value,
  133. const CompletionToken, CompletionToken>,
  134. Signatures...>(
  135. detail::initiate_cancel_after<
  136. decay_t<Initiation>, Clock, WaitTraits, Signatures...>(
  137. static_cast<Initiation&&>(initiation)),
  138. token.token_, token.timeout_, token.cancel_type_,
  139. static_cast<Args&&>(args)...);
  140. }
  141. };
  142. template <typename CompletionToken, typename Clock,
  143. typename WaitTraits, typename Executor, typename... Signatures>
  144. struct async_result<
  145. cancel_after_timer<CompletionToken, Clock, WaitTraits, Executor>,
  146. Signatures...>
  147. : async_result<CompletionToken, Signatures...>
  148. {
  149. template <typename Initiation, typename RawCompletionToken, typename... Args>
  150. static auto initiate(Initiation&& initiation,
  151. RawCompletionToken&& token, Args&&... args)
  152. -> decltype(
  153. async_initiate<
  154. conditional_t<
  155. is_const<remove_reference_t<RawCompletionToken>>::value,
  156. const CompletionToken, CompletionToken>,
  157. Signatures...>(
  158. declval<detail::initiate_cancel_after_timer<
  159. decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>>(),
  160. token.token_, &token.timer_, token.timeout_,
  161. token.cancel_type_, static_cast<Args&&>(args)...))
  162. {
  163. return async_initiate<
  164. conditional_t<
  165. is_const<remove_reference_t<RawCompletionToken>>::value,
  166. const CompletionToken, CompletionToken>,
  167. Signatures...>(
  168. detail::initiate_cancel_after_timer<
  169. decay_t<Initiation>, Clock, WaitTraits, Executor, Signatures...>(
  170. static_cast<Initiation&&>(initiation)),
  171. token.token_, &token.timer_, token.timeout_,
  172. token.cancel_type_, static_cast<Args&&>(args)...);
  173. }
  174. };
  175. template <typename Clock, typename WaitTraits, typename... Signatures>
  176. struct async_result<partial_cancel_after<Clock, WaitTraits>, Signatures...>
  177. {
  178. template <typename Initiation, typename RawCompletionToken, typename... Args>
  179. static auto initiate(Initiation&& initiation,
  180. RawCompletionToken&& token, Args&&... args)
  181. -> decltype(
  182. async_initiate<
  183. const cancel_after_t<
  184. default_completion_token_t<associated_executor_t<Initiation>>,
  185. Clock, WaitTraits>&,
  186. Signatures...>(
  187. static_cast<Initiation&&>(initiation),
  188. cancel_after_t<
  189. default_completion_token_t<associated_executor_t<Initiation>>,
  190. Clock, WaitTraits>(
  191. default_completion_token_t<associated_executor_t<Initiation>>{},
  192. token.timeout_, token.cancel_type_),
  193. static_cast<Args&&>(args)...))
  194. {
  195. return async_initiate<
  196. const cancel_after_t<
  197. default_completion_token_t<associated_executor_t<Initiation>>,
  198. Clock, WaitTraits>&,
  199. Signatures...>(
  200. static_cast<Initiation&&>(initiation),
  201. cancel_after_t<
  202. default_completion_token_t<associated_executor_t<Initiation>>,
  203. Clock, WaitTraits>(
  204. default_completion_token_t<associated_executor_t<Initiation>>{},
  205. token.timeout_, token.cancel_type_),
  206. static_cast<Args&&>(args)...);
  207. }
  208. };
  209. template <typename Clock, typename WaitTraits,
  210. typename Executor, typename... Signatures>
  211. struct async_result<
  212. partial_cancel_after_timer<Clock, WaitTraits, Executor>, Signatures...>
  213. {
  214. template <typename Initiation, typename RawCompletionToken, typename... Args>
  215. static auto initiate(Initiation&& initiation,
  216. RawCompletionToken&& token, Args&&... args)
  217. -> decltype(
  218. async_initiate<Signatures...>(
  219. static_cast<Initiation&&>(initiation),
  220. cancel_after_timer<
  221. default_completion_token_t<associated_executor_t<Initiation>>,
  222. Clock, WaitTraits, Executor>(
  223. default_completion_token_t<associated_executor_t<Initiation>>{},
  224. token.timer_, token.timeout_, token.cancel_type_),
  225. static_cast<Args&&>(args)...))
  226. {
  227. return async_initiate<Signatures...>(
  228. static_cast<Initiation&&>(initiation),
  229. cancel_after_timer<
  230. default_completion_token_t<associated_executor_t<Initiation>>,
  231. Clock, WaitTraits, Executor>(
  232. default_completion_token_t<associated_executor_t<Initiation>>{},
  233. token.timer_, token.timeout_, token.cancel_type_),
  234. static_cast<Args&&>(args)...);
  235. }
  236. };
  237. #endif // !defined(GENERATING_DOCUMENTATION)
  238. } // namespace asio
  239. } // namespace boost
  240. #include <boost/asio/detail/pop_options.hpp>
  241. #endif // BOOST_ASIO_IMPL_CANCEL_AFTER_HPP