cancel_after.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. //
  2. // 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_CANCEL_AFTER_HPP
  11. #define BOOST_ASIO_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/basic_waitable_timer.hpp>
  17. #include <boost/asio/cancellation_type.hpp>
  18. #include <boost/asio/detail/chrono.hpp>
  19. #include <boost/asio/detail/type_traits.hpp>
  20. #include <boost/asio/wait_traits.hpp>
  21. #include <boost/asio/detail/push_options.hpp>
  22. namespace boost {
  23. namespace asio {
  24. /// A @ref completion_token adapter that cancels an operation after a timeout.
  25. /**
  26. * The cancel_after_t class is used to indicate that an asynchronous operation
  27. * should be cancelled if not complete before the specified duration has
  28. * elapsed.
  29. */
  30. template <typename CompletionToken, typename Clock,
  31. typename WaitTraits = boost::asio::wait_traits<Clock>>
  32. class cancel_after_t
  33. {
  34. public:
  35. /// Constructor.
  36. template <typename T>
  37. cancel_after_t(T&& completion_token, const typename Clock::duration& timeout,
  38. cancellation_type_t cancel_type = cancellation_type::terminal)
  39. : token_(static_cast<T&&>(completion_token)),
  40. timeout_(timeout),
  41. cancel_type_(cancel_type)
  42. {
  43. }
  44. //private:
  45. CompletionToken token_;
  46. typename Clock::duration timeout_;
  47. cancellation_type_t cancel_type_;
  48. };
  49. /// A @ref completion_token adapter that cancels an operation after a timeout.
  50. /**
  51. * The cancel_after_timer class is used to indicate that an asynchronous
  52. * operation should be cancelled if not complete before the specified duration
  53. * has elapsed.
  54. */
  55. template <typename CompletionToken, typename Clock,
  56. typename WaitTraits = boost::asio::wait_traits<Clock>,
  57. typename Executor = any_io_executor>
  58. class cancel_after_timer
  59. {
  60. public:
  61. /// Constructor.
  62. template <typename T>
  63. cancel_after_timer(T&& completion_token,
  64. basic_waitable_timer<Clock, WaitTraits, Executor>& timer,
  65. const typename Clock::duration& timeout,
  66. cancellation_type_t cancel_type = cancellation_type::terminal)
  67. : token_(static_cast<T&&>(completion_token)),
  68. timer_(timer),
  69. timeout_(timeout),
  70. cancel_type_(cancel_type)
  71. {
  72. }
  73. //private:
  74. CompletionToken token_;
  75. basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;
  76. typename Clock::duration timeout_;
  77. cancellation_type_t cancel_type_;
  78. };
  79. /// A function object type that adapts a @ref completion_token to cancel an
  80. /// operation after a timeout.
  81. /**
  82. * May also be used directly as a completion token, in which case it adapts the
  83. * asynchronous operation's default completion token (or boost::asio::deferred
  84. * if no default is available).
  85. */
  86. template <typename Clock, typename WaitTraits = boost::asio::wait_traits<Clock>>
  87. class partial_cancel_after
  88. {
  89. public:
  90. /// Constructor that specifies the timeout duration and cancellation type.
  91. explicit partial_cancel_after(const typename Clock::duration& timeout,
  92. cancellation_type_t cancel_type = cancellation_type::terminal)
  93. : timeout_(timeout),
  94. cancel_type_(cancel_type)
  95. {
  96. }
  97. /// Adapt a @ref completion_token to specify that the completion handler
  98. /// arguments should be combined into a single tuple argument.
  99. template <typename CompletionToken>
  100. BOOST_ASIO_NODISCARD inline
  101. cancel_after_t<decay_t<CompletionToken>, Clock, WaitTraits>
  102. operator()(CompletionToken&& completion_token) const
  103. {
  104. return cancel_after_t<decay_t<CompletionToken>, Clock, WaitTraits>(
  105. static_cast<CompletionToken&&>(completion_token),
  106. timeout_, cancel_type_);
  107. }
  108. //private:
  109. typename Clock::duration timeout_;
  110. cancellation_type_t cancel_type_;
  111. };
  112. /// A function object type that adapts a @ref completion_token to cancel an
  113. /// operation after a timeout.
  114. /**
  115. * May also be used directly as a completion token, in which case it adapts the
  116. * asynchronous operation's default completion token (or boost::asio::deferred
  117. * if no default is available).
  118. */
  119. template <typename Clock, typename WaitTraits = boost::asio::wait_traits<Clock>,
  120. typename Executor = any_io_executor>
  121. class partial_cancel_after_timer
  122. {
  123. public:
  124. /// Constructor that specifies the timeout duration and cancellation type.
  125. explicit partial_cancel_after_timer(
  126. basic_waitable_timer<Clock, WaitTraits, Executor>& timer,
  127. const typename Clock::duration& timeout,
  128. cancellation_type_t cancel_type = cancellation_type::terminal)
  129. : timer_(timer),
  130. timeout_(timeout),
  131. cancel_type_(cancel_type)
  132. {
  133. }
  134. /// Adapt a @ref completion_token to specify that the completion handler
  135. /// arguments should be combined into a single tuple argument.
  136. template <typename CompletionToken>
  137. BOOST_ASIO_NODISCARD inline
  138. cancel_after_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>
  139. operator()(CompletionToken&& completion_token) const
  140. {
  141. return cancel_after_timer<decay_t<CompletionToken>,
  142. Clock, WaitTraits, Executor>(
  143. static_cast<CompletionToken&&>(completion_token),
  144. timeout_, cancel_type_);
  145. }
  146. //private:
  147. basic_waitable_timer<Clock, WaitTraits, Executor>& timer_;
  148. typename Clock::duration timeout_;
  149. cancellation_type_t cancel_type_;
  150. };
  151. /// Create a partial completion token adapter that cancels an operation if not
  152. /// complete before the specified relative timeout has elapsed.
  153. /**
  154. * @par Thread Safety
  155. * When an asynchronous operation is used with cancel_after, a timer async_wait
  156. * operation is performed in parallel to the main operation. If this parallel
  157. * async_wait completes first, a cancellation request is emitted to cancel the
  158. * main operation. Consequently, the application must ensure that the
  159. * asynchronous operation is performed within an implicit or explicit strand.
  160. */
  161. template <typename Rep, typename Period>
  162. BOOST_ASIO_NODISCARD inline partial_cancel_after<chrono::steady_clock>
  163. cancel_after(const chrono::duration<Rep, Period>& timeout,
  164. cancellation_type_t cancel_type = cancellation_type::terminal)
  165. {
  166. return partial_cancel_after<chrono::steady_clock>(timeout, cancel_type);
  167. }
  168. /// Create a partial completion token adapter that cancels an operation if not
  169. /// complete before the specified relative timeout has elapsed.
  170. /**
  171. * @par Thread Safety
  172. * When an asynchronous operation is used with cancel_after, a timer async_wait
  173. * operation is performed in parallel to the main operation. If this parallel
  174. * async_wait completes first, a cancellation request is emitted to cancel the
  175. * main operation. Consequently, the application must ensure that the
  176. * asynchronous operation is performed within an implicit or explicit strand.
  177. */
  178. template <typename Clock, typename WaitTraits,
  179. typename Executor, typename Rep, typename Period>
  180. BOOST_ASIO_NODISCARD inline
  181. partial_cancel_after_timer<Clock, WaitTraits, Executor>
  182. cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,
  183. const chrono::duration<Rep, Period>& timeout,
  184. cancellation_type_t cancel_type = cancellation_type::terminal)
  185. {
  186. return partial_cancel_after_timer<Clock, WaitTraits, Executor>(
  187. timer, timeout, cancel_type);
  188. }
  189. /// Adapt a @ref completion_token to cancel an operation if not complete before
  190. /// the specified relative timeout has elapsed.
  191. /**
  192. * @par Thread Safety
  193. * When an asynchronous operation is used with cancel_after, a timer async_wait
  194. * operation is performed in parallel to the main operation. If this parallel
  195. * async_wait completes first, a cancellation request is emitted to cancel the
  196. * main operation. Consequently, the application must ensure that the
  197. * asynchronous operation is performed within an implicit or explicit strand.
  198. */
  199. template <typename Rep, typename Period, typename CompletionToken>
  200. BOOST_ASIO_NODISCARD inline
  201. cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>
  202. cancel_after(const chrono::duration<Rep, Period>& timeout,
  203. CompletionToken&& completion_token)
  204. {
  205. return cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>(
  206. static_cast<CompletionToken&&>(completion_token),
  207. timeout, cancellation_type::terminal);
  208. }
  209. /// Adapt a @ref completion_token to cancel an operation if not complete before
  210. /// the specified relative timeout has elapsed.
  211. /**
  212. * @par Thread Safety
  213. * When an asynchronous operation is used with cancel_after, a timer async_wait
  214. * operation is performed in parallel to the main operation. If this parallel
  215. * async_wait completes first, a cancellation request is emitted to cancel the
  216. * main operation. Consequently, the application must ensure that the
  217. * asynchronous operation is performed within an implicit or explicit strand.
  218. */
  219. template <typename Rep, typename Period, typename CompletionToken>
  220. BOOST_ASIO_NODISCARD inline
  221. cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>
  222. cancel_after(const chrono::duration<Rep, Period>& timeout,
  223. cancellation_type_t cancel_type, CompletionToken&& completion_token)
  224. {
  225. return cancel_after_t<decay_t<CompletionToken>, chrono::steady_clock>(
  226. static_cast<CompletionToken&&>(completion_token), timeout, cancel_type);
  227. }
  228. /// Adapt a @ref completion_token to cancel an operation if not complete before
  229. /// the specified relative timeout has elapsed.
  230. /**
  231. * @par Thread Safety
  232. * When an asynchronous operation is used with cancel_after, a timer async_wait
  233. * operation is performed in parallel to the main operation. If this parallel
  234. * async_wait completes first, a cancellation request is emitted to cancel the
  235. * main operation. Consequently, the application must ensure that the
  236. * asynchronous operation is performed within an implicit or explicit strand.
  237. */
  238. template <typename Clock, typename WaitTraits, typename Executor,
  239. typename Rep, typename Period, typename CompletionToken>
  240. BOOST_ASIO_NODISCARD inline
  241. cancel_after_timer<decay_t<CompletionToken>, Clock, WaitTraits, Executor>
  242. cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,
  243. const chrono::duration<Rep, Period>& timeout,
  244. CompletionToken&& completion_token)
  245. {
  246. return cancel_after_timer<decay_t<CompletionToken>,
  247. Clock, WaitTraits, Executor>(
  248. static_cast<CompletionToken&&>(completion_token),
  249. timer, timeout, cancellation_type::terminal);
  250. }
  251. /// Adapt a @ref completion_token to cancel an operation if not complete before
  252. /// the specified relative timeout has elapsed.
  253. /**
  254. * @par Thread Safety
  255. * When an asynchronous operation is used with cancel_after, a timer async_wait
  256. * operation is performed in parallel to the main operation. If this parallel
  257. * async_wait completes first, a cancellation request is emitted to cancel the
  258. * main operation. Consequently, the application must ensure that the
  259. * asynchronous operation is performed within an implicit or explicit strand.
  260. */
  261. template <typename Clock, typename WaitTraits, typename Executor,
  262. typename Rep, typename Period, typename CompletionToken>
  263. BOOST_ASIO_NODISCARD inline
  264. cancel_after_timer<decay_t<CompletionToken>, chrono::steady_clock>
  265. cancel_after(basic_waitable_timer<Clock, WaitTraits, Executor>& timer,
  266. const chrono::duration<Rep, Period>& timeout,
  267. cancellation_type_t cancel_type, CompletionToken&& completion_token)
  268. {
  269. return cancel_after_timer<decay_t<CompletionToken>,
  270. Clock, WaitTraits, Executor>(
  271. static_cast<CompletionToken&&>(completion_token),
  272. timer, timeout, cancel_type);
  273. }
  274. } // namespace asio
  275. } // namespace boost
  276. #include <boost/asio/detail/pop_options.hpp>
  277. #include <boost/asio/impl/cancel_after.hpp>
  278. #endif // BOOST_ASIO_CANCEL_AFTER_HPP