Audio plugin host https://kx.studio/carla
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

522 lines
18KB

  1. //
  2. // basic_deadline_timer.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2015 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_BASIC_DEADLINE_TIMER_HPP
  11. #define ASIO_BASIC_DEADLINE_TIMER_HPP
  12. #if defined(_MSC_VER) && (_MSC_VER >= 1200)
  13. # pragma once
  14. #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
  15. #include "asio/detail/config.hpp"
  16. #if defined(ASIO_HAS_BOOST_DATE_TIME) \
  17. || defined(GENERATING_DOCUMENTATION)
  18. #include <cstddef>
  19. #include "asio/basic_io_object.hpp"
  20. #include "asio/deadline_timer_service.hpp"
  21. #include "asio/detail/handler_type_requirements.hpp"
  22. #include "asio/detail/throw_error.hpp"
  23. #include "asio/error.hpp"
  24. #include "asio/detail/push_options.hpp"
  25. namespace asio {
  26. /// Provides waitable timer functionality.
  27. /**
  28. * The basic_deadline_timer class template provides the ability to perform a
  29. * blocking or asynchronous wait for a timer to expire.
  30. *
  31. * A deadline timer is always in one of two states: "expired" or "not expired".
  32. * If the wait() or async_wait() function is called on an expired timer, the
  33. * wait operation will complete immediately.
  34. *
  35. * Most applications will use the asio::deadline_timer typedef.
  36. *
  37. * @par Thread Safety
  38. * @e Distinct @e objects: Safe.@n
  39. * @e Shared @e objects: Unsafe.
  40. *
  41. * @par Examples
  42. * Performing a blocking wait:
  43. * @code
  44. * // Construct a timer without setting an expiry time.
  45. * asio::deadline_timer timer(io_context);
  46. *
  47. * // Set an expiry time relative to now.
  48. * timer.expires_from_now(boost::posix_time::seconds(5));
  49. *
  50. * // Wait for the timer to expire.
  51. * timer.wait();
  52. * @endcode
  53. *
  54. * @par
  55. * Performing an asynchronous wait:
  56. * @code
  57. * void handler(const asio::error_code& error)
  58. * {
  59. * if (!error)
  60. * {
  61. * // Timer expired.
  62. * }
  63. * }
  64. *
  65. * ...
  66. *
  67. * // Construct a timer with an absolute expiry time.
  68. * asio::deadline_timer timer(io_context,
  69. * boost::posix_time::time_from_string("2005-12-07 23:59:59.000"));
  70. *
  71. * // Start an asynchronous wait.
  72. * timer.async_wait(handler);
  73. * @endcode
  74. *
  75. * @par Changing an active deadline_timer's expiry time
  76. *
  77. * Changing the expiry time of a timer while there are pending asynchronous
  78. * waits causes those wait operations to be cancelled. To ensure that the action
  79. * associated with the timer is performed only once, use something like this:
  80. * used:
  81. *
  82. * @code
  83. * void on_some_event()
  84. * {
  85. * if (my_timer.expires_from_now(seconds(5)) > 0)
  86. * {
  87. * // We managed to cancel the timer. Start new asynchronous wait.
  88. * my_timer.async_wait(on_timeout);
  89. * }
  90. * else
  91. * {
  92. * // Too late, timer has already expired!
  93. * }
  94. * }
  95. *
  96. * void on_timeout(const asio::error_code& e)
  97. * {
  98. * if (e != asio::error::operation_aborted)
  99. * {
  100. * // Timer was not cancelled, take necessary action.
  101. * }
  102. * }
  103. * @endcode
  104. *
  105. * @li The asio::basic_deadline_timer::expires_from_now() function
  106. * cancels any pending asynchronous waits, and returns the number of
  107. * asynchronous waits that were cancelled. If it returns 0 then you were too
  108. * late and the wait handler has already been executed, or will soon be
  109. * executed. If it returns 1 then the wait handler was successfully cancelled.
  110. *
  111. * @li If a wait handler is cancelled, the asio::error_code passed to
  112. * it contains the value asio::error::operation_aborted.
  113. */
  114. template <typename Time,
  115. typename TimeTraits = asio::time_traits<Time>,
  116. typename TimerService = deadline_timer_service<Time, TimeTraits> >
  117. class basic_deadline_timer
  118. : public basic_io_object<TimerService>
  119. {
  120. public:
  121. /// The time traits type.
  122. typedef TimeTraits traits_type;
  123. /// The time type.
  124. typedef typename traits_type::time_type time_type;
  125. /// The duration type.
  126. typedef typename traits_type::duration_type duration_type;
  127. /// Constructor.
  128. /**
  129. * This constructor creates a timer without setting an expiry time. The
  130. * expires_at() or expires_from_now() functions must be called to set an
  131. * expiry time before the timer can be waited on.
  132. *
  133. * @param io_context The io_context object that the timer will use to dispatch
  134. * handlers for any asynchronous operations performed on the timer.
  135. */
  136. explicit basic_deadline_timer(asio::io_context& io_context)
  137. : basic_io_object<TimerService>(io_context)
  138. {
  139. }
  140. /// Constructor to set a particular expiry time as an absolute time.
  141. /**
  142. * This constructor creates a timer and sets the expiry time.
  143. *
  144. * @param io_context The io_context object that the timer will use to dispatch
  145. * handlers for any asynchronous operations performed on the timer.
  146. *
  147. * @param expiry_time The expiry time to be used for the timer, expressed
  148. * as an absolute time.
  149. */
  150. basic_deadline_timer(asio::io_context& io_context,
  151. const time_type& expiry_time)
  152. : basic_io_object<TimerService>(io_context)
  153. {
  154. asio::error_code ec;
  155. this->get_service().expires_at(this->get_implementation(), expiry_time, ec);
  156. asio::detail::throw_error(ec, "expires_at");
  157. }
  158. /// Constructor to set a particular expiry time relative to now.
  159. /**
  160. * This constructor creates a timer and sets the expiry time.
  161. *
  162. * @param io_context The io_context object that the timer will use to dispatch
  163. * handlers for any asynchronous operations performed on the timer.
  164. *
  165. * @param expiry_time The expiry time to be used for the timer, relative to
  166. * now.
  167. */
  168. basic_deadline_timer(asio::io_context& io_context,
  169. const duration_type& expiry_time)
  170. : basic_io_object<TimerService>(io_context)
  171. {
  172. asio::error_code ec;
  173. this->get_service().expires_from_now(
  174. this->get_implementation(), expiry_time, ec);
  175. asio::detail::throw_error(ec, "expires_from_now");
  176. }
  177. /// Cancel any asynchronous operations that are waiting on the timer.
  178. /**
  179. * This function forces the completion of any pending asynchronous wait
  180. * operations against the timer. The handler for each cancelled operation will
  181. * be invoked with the asio::error::operation_aborted error code.
  182. *
  183. * Cancelling the timer does not change the expiry time.
  184. *
  185. * @return The number of asynchronous operations that were cancelled.
  186. *
  187. * @throws asio::system_error Thrown on failure.
  188. *
  189. * @note If the timer has already expired when cancel() is called, then the
  190. * handlers for asynchronous wait operations will:
  191. *
  192. * @li have already been invoked; or
  193. *
  194. * @li have been queued for invocation in the near future.
  195. *
  196. * These handlers can no longer be cancelled, and therefore are passed an
  197. * error code that indicates the successful completion of the wait operation.
  198. */
  199. std::size_t cancel()
  200. {
  201. asio::error_code ec;
  202. std::size_t s = this->get_service().cancel(this->get_implementation(), ec);
  203. asio::detail::throw_error(ec, "cancel");
  204. return s;
  205. }
  206. /// Cancel any asynchronous operations that are waiting on the timer.
  207. /**
  208. * This function forces the completion of any pending asynchronous wait
  209. * operations against the timer. The handler for each cancelled operation will
  210. * be invoked with the asio::error::operation_aborted error code.
  211. *
  212. * Cancelling the timer does not change the expiry time.
  213. *
  214. * @param ec Set to indicate what error occurred, if any.
  215. *
  216. * @return The number of asynchronous operations that were cancelled.
  217. *
  218. * @note If the timer has already expired when cancel() is called, then the
  219. * handlers for asynchronous wait operations will:
  220. *
  221. * @li have already been invoked; or
  222. *
  223. * @li have been queued for invocation in the near future.
  224. *
  225. * These handlers can no longer be cancelled, and therefore are passed an
  226. * error code that indicates the successful completion of the wait operation.
  227. */
  228. std::size_t cancel(asio::error_code& ec)
  229. {
  230. return this->get_service().cancel(this->get_implementation(), ec);
  231. }
  232. /// Cancels one asynchronous operation that is waiting on the timer.
  233. /**
  234. * This function forces the completion of one pending asynchronous wait
  235. * operation against the timer. Handlers are cancelled in FIFO order. The
  236. * handler for the cancelled operation will be invoked with the
  237. * asio::error::operation_aborted error code.
  238. *
  239. * Cancelling the timer does not change the expiry time.
  240. *
  241. * @return The number of asynchronous operations that were cancelled. That is,
  242. * either 0 or 1.
  243. *
  244. * @throws asio::system_error Thrown on failure.
  245. *
  246. * @note If the timer has already expired when cancel_one() is called, then
  247. * the handlers for asynchronous wait operations will:
  248. *
  249. * @li have already been invoked; or
  250. *
  251. * @li have been queued for invocation in the near future.
  252. *
  253. * These handlers can no longer be cancelled, and therefore are passed an
  254. * error code that indicates the successful completion of the wait operation.
  255. */
  256. std::size_t cancel_one()
  257. {
  258. asio::error_code ec;
  259. std::size_t s = this->get_service().cancel_one(
  260. this->get_implementation(), ec);
  261. asio::detail::throw_error(ec, "cancel_one");
  262. return s;
  263. }
  264. /// Cancels one asynchronous operation that is waiting on the timer.
  265. /**
  266. * This function forces the completion of one pending asynchronous wait
  267. * operation against the timer. Handlers are cancelled in FIFO order. The
  268. * handler for the cancelled operation will be invoked with the
  269. * asio::error::operation_aborted error code.
  270. *
  271. * Cancelling the timer does not change the expiry time.
  272. *
  273. * @param ec Set to indicate what error occurred, if any.
  274. *
  275. * @return The number of asynchronous operations that were cancelled. That is,
  276. * either 0 or 1.
  277. *
  278. * @note If the timer has already expired when cancel_one() is called, then
  279. * the handlers for asynchronous wait operations will:
  280. *
  281. * @li have already been invoked; or
  282. *
  283. * @li have been queued for invocation in the near future.
  284. *
  285. * These handlers can no longer be cancelled, and therefore are passed an
  286. * error code that indicates the successful completion of the wait operation.
  287. */
  288. std::size_t cancel_one(asio::error_code& ec)
  289. {
  290. return this->get_service().cancel_one(this->get_implementation(), ec);
  291. }
  292. /// Get the timer's expiry time as an absolute time.
  293. /**
  294. * This function may be used to obtain the timer's current expiry time.
  295. * Whether the timer has expired or not does not affect this value.
  296. */
  297. time_type expires_at() const
  298. {
  299. return this->get_service().expires_at(this->get_implementation());
  300. }
  301. /// Set the timer's expiry time as an absolute time.
  302. /**
  303. * This function sets the expiry time. Any pending asynchronous wait
  304. * operations will be cancelled. The handler for each cancelled operation will
  305. * be invoked with the asio::error::operation_aborted error code.
  306. *
  307. * @param expiry_time The expiry time to be used for the timer.
  308. *
  309. * @return The number of asynchronous operations that were cancelled.
  310. *
  311. * @throws asio::system_error Thrown on failure.
  312. *
  313. * @note If the timer has already expired when expires_at() is called, then
  314. * the handlers for asynchronous wait operations will:
  315. *
  316. * @li have already been invoked; or
  317. *
  318. * @li have been queued for invocation in the near future.
  319. *
  320. * These handlers can no longer be cancelled, and therefore are passed an
  321. * error code that indicates the successful completion of the wait operation.
  322. */
  323. std::size_t expires_at(const time_type& expiry_time)
  324. {
  325. asio::error_code ec;
  326. std::size_t s = this->get_service().expires_at(
  327. this->get_implementation(), expiry_time, ec);
  328. asio::detail::throw_error(ec, "expires_at");
  329. return s;
  330. }
  331. /// Set the timer's expiry time as an absolute time.
  332. /**
  333. * This function sets the expiry time. Any pending asynchronous wait
  334. * operations will be cancelled. The handler for each cancelled operation will
  335. * be invoked with the asio::error::operation_aborted error code.
  336. *
  337. * @param expiry_time The expiry time to be used for the timer.
  338. *
  339. * @param ec Set to indicate what error occurred, if any.
  340. *
  341. * @return The number of asynchronous operations that were cancelled.
  342. *
  343. * @note If the timer has already expired when expires_at() is called, then
  344. * the handlers for asynchronous wait operations will:
  345. *
  346. * @li have already been invoked; or
  347. *
  348. * @li have been queued for invocation in the near future.
  349. *
  350. * These handlers can no longer be cancelled, and therefore are passed an
  351. * error code that indicates the successful completion of the wait operation.
  352. */
  353. std::size_t expires_at(const time_type& expiry_time,
  354. asio::error_code& ec)
  355. {
  356. return this->get_service().expires_at(
  357. this->get_implementation(), expiry_time, ec);
  358. }
  359. /// Get the timer's expiry time relative to now.
  360. /**
  361. * This function may be used to obtain the timer's current expiry time.
  362. * Whether the timer has expired or not does not affect this value.
  363. */
  364. duration_type expires_from_now() const
  365. {
  366. return this->get_service().expires_from_now(this->get_implementation());
  367. }
  368. /// Set the timer's expiry time relative to now.
  369. /**
  370. * This function sets the expiry time. Any pending asynchronous wait
  371. * operations will be cancelled. The handler for each cancelled operation will
  372. * be invoked with the asio::error::operation_aborted error code.
  373. *
  374. * @param expiry_time The expiry time to be used for the timer.
  375. *
  376. * @return The number of asynchronous operations that were cancelled.
  377. *
  378. * @throws asio::system_error Thrown on failure.
  379. *
  380. * @note If the timer has already expired when expires_from_now() is called,
  381. * then the handlers for asynchronous wait operations will:
  382. *
  383. * @li have already been invoked; or
  384. *
  385. * @li have been queued for invocation in the near future.
  386. *
  387. * These handlers can no longer be cancelled, and therefore are passed an
  388. * error code that indicates the successful completion of the wait operation.
  389. */
  390. std::size_t expires_from_now(const duration_type& expiry_time)
  391. {
  392. asio::error_code ec;
  393. std::size_t s = this->get_service().expires_from_now(
  394. this->get_implementation(), expiry_time, ec);
  395. asio::detail::throw_error(ec, "expires_from_now");
  396. return s;
  397. }
  398. /// Set the timer's expiry time relative to now.
  399. /**
  400. * This function sets the expiry time. Any pending asynchronous wait
  401. * operations will be cancelled. The handler for each cancelled operation will
  402. * be invoked with the asio::error::operation_aborted error code.
  403. *
  404. * @param expiry_time The expiry time to be used for the timer.
  405. *
  406. * @param ec Set to indicate what error occurred, if any.
  407. *
  408. * @return The number of asynchronous operations that were cancelled.
  409. *
  410. * @note If the timer has already expired when expires_from_now() is called,
  411. * then the handlers for asynchronous wait operations will:
  412. *
  413. * @li have already been invoked; or
  414. *
  415. * @li have been queued for invocation in the near future.
  416. *
  417. * These handlers can no longer be cancelled, and therefore are passed an
  418. * error code that indicates the successful completion of the wait operation.
  419. */
  420. std::size_t expires_from_now(const duration_type& expiry_time,
  421. asio::error_code& ec)
  422. {
  423. return this->get_service().expires_from_now(
  424. this->get_implementation(), expiry_time, ec);
  425. }
  426. /// Perform a blocking wait on the timer.
  427. /**
  428. * This function is used to wait for the timer to expire. This function
  429. * blocks and does not return until the timer has expired.
  430. *
  431. * @throws asio::system_error Thrown on failure.
  432. */
  433. void wait()
  434. {
  435. asio::error_code ec;
  436. this->get_service().wait(this->get_implementation(), ec);
  437. asio::detail::throw_error(ec, "wait");
  438. }
  439. /// Perform a blocking wait on the timer.
  440. /**
  441. * This function is used to wait for the timer to expire. This function
  442. * blocks and does not return until the timer has expired.
  443. *
  444. * @param ec Set to indicate what error occurred, if any.
  445. */
  446. void wait(asio::error_code& ec)
  447. {
  448. this->get_service().wait(this->get_implementation(), ec);
  449. }
  450. /// Start an asynchronous wait on the timer.
  451. /**
  452. * This function may be used to initiate an asynchronous wait against the
  453. * timer. It always returns immediately.
  454. *
  455. * For each call to async_wait(), the supplied handler will be called exactly
  456. * once. The handler will be called when:
  457. *
  458. * @li The timer has expired.
  459. *
  460. * @li The timer was cancelled, in which case the handler is passed the error
  461. * code asio::error::operation_aborted.
  462. *
  463. * @param handler The handler to be called when the timer expires. Copies
  464. * will be made of the handler as required. The function signature of the
  465. * handler must be:
  466. * @code void handler(
  467. * const asio::error_code& error // Result of operation.
  468. * ); @endcode
  469. * Regardless of whether the asynchronous operation completes immediately or
  470. * not, the handler will not be invoked from within this function. Invocation
  471. * of the handler will be performed in a manner equivalent to using
  472. * asio::io_context::post().
  473. */
  474. template <typename WaitHandler>
  475. ASIO_INITFN_RESULT_TYPE(WaitHandler,
  476. void (asio::error_code))
  477. async_wait(ASIO_MOVE_ARG(WaitHandler) handler)
  478. {
  479. // If you get an error on the following line it means that your handler does
  480. // not meet the documented type requirements for a WaitHandler.
  481. ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
  482. return this->get_service().async_wait(this->get_implementation(),
  483. ASIO_MOVE_CAST(WaitHandler)(handler));
  484. }
  485. };
  486. } // namespace asio
  487. #include "asio/detail/pop_options.hpp"
  488. #endif // defined(ASIO_HAS_BOOST_DATE_TIME)
  489. // || defined(GENERATING_DOCUMENTATION)
  490. #endif // ASIO_BASIC_DEADLINE_TIMER_HPP