basic_deadline_timer.hpp 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447
  1. //
  2. // basic_deadline_timer.hpp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2003-2008 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_BASIC_DEADLINE_TIMER_HPP
  11. #define BOOST_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 <boost/asio/detail/push_options.hpp>
  16. #include <boost/asio/detail/push_options.hpp>
  17. #include <cstddef>
  18. #include <boost/config.hpp>
  19. #include <boost/asio/detail/pop_options.hpp>
  20. #include <boost/asio/basic_io_object.hpp>
  21. #include <boost/asio/deadline_timer_service.hpp>
  22. #include <boost/asio/error.hpp>
  23. #include <boost/asio/detail/throw_error.hpp>
  24. namespace boost {
  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 boost::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. * boost::asio::deadline_timer timer(io_service);
  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 boost::system::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. * boost::asio::deadline_timer timer(io_service,
  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 boost::system::error_code& e)
  97. * {
  98. * if (e != boost::asio::error::operation_aborted)
  99. * {
  100. * // Timer was not cancelled, take necessary action.
  101. * }
  102. * }
  103. * @endcode
  104. *
  105. * @li The boost::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 boost::system::error_code passed to
  112. * it contains the value boost::asio::error::operation_aborted.
  113. */
  114. template <typename Time,
  115. typename TimeTraits = boost::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_service The io_service object that the timer will use to dispatch
  134. * handlers for any asynchronous operations performed on the timer.
  135. */
  136. explicit basic_deadline_timer(boost::asio::io_service& io_service)
  137. : basic_io_object<TimerService>(io_service)
  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_service The io_service 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(boost::asio::io_service& io_service,
  151. const time_type& expiry_time)
  152. : basic_io_object<TimerService>(io_service)
  153. {
  154. boost::system::error_code ec;
  155. this->service.expires_at(this->implementation, expiry_time, ec);
  156. boost::asio::detail::throw_error(ec);
  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_service The io_service 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(boost::asio::io_service& io_service,
  169. const duration_type& expiry_time)
  170. : basic_io_object<TimerService>(io_service)
  171. {
  172. boost::system::error_code ec;
  173. this->service.expires_from_now(this->implementation, expiry_time, ec);
  174. boost::asio::detail::throw_error(ec);
  175. }
  176. /// Cancel any asynchronous operations that are waiting on the timer.
  177. /**
  178. * This function forces the completion of any pending asynchronous wait
  179. * operations against the timer. The handler for each cancelled operation will
  180. * be invoked with the boost::asio::error::operation_aborted error code.
  181. *
  182. * Cancelling the timer does not change the expiry time.
  183. *
  184. * @return The number of asynchronous operations that were cancelled.
  185. *
  186. * @throws boost::system::system_error Thrown on failure.
  187. *
  188. * @note If the timer has already expired when cancel() is called, then the
  189. * handlers for asynchronous wait operations will:
  190. *
  191. * @li have already been invoked; or
  192. *
  193. * @li have been queued for invocation in the near future.
  194. *
  195. * These handlers can no longer be cancelled, and therefore are passed an
  196. * error code that indicates the successful completion of the wait operation.
  197. */
  198. std::size_t cancel()
  199. {
  200. boost::system::error_code ec;
  201. std::size_t s = this->service.cancel(this->implementation, ec);
  202. boost::asio::detail::throw_error(ec);
  203. return s;
  204. }
  205. /// Cancel any asynchronous operations that are waiting on the timer.
  206. /**
  207. * This function forces the completion of any pending asynchronous wait
  208. * operations against the timer. The handler for each cancelled operation will
  209. * be invoked with the boost::asio::error::operation_aborted error code.
  210. *
  211. * Cancelling the timer does not change the expiry time.
  212. *
  213. * @param ec Set to indicate what error occurred, if any.
  214. *
  215. * @return The number of asynchronous operations that were cancelled.
  216. *
  217. * @note If the timer has already expired when cancel() is called, then the
  218. * handlers for asynchronous wait operations will:
  219. *
  220. * @li have already been invoked; or
  221. *
  222. * @li have been queued for invocation in the near future.
  223. *
  224. * These handlers can no longer be cancelled, and therefore are passed an
  225. * error code that indicates the successful completion of the wait operation.
  226. */
  227. std::size_t cancel(boost::system::error_code& ec)
  228. {
  229. return this->service.cancel(this->implementation, ec);
  230. }
  231. /// Get the timer's expiry time as an absolute time.
  232. /**
  233. * This function may be used to obtain the timer's current expiry time.
  234. * Whether the timer has expired or not does not affect this value.
  235. */
  236. time_type expires_at() const
  237. {
  238. return this->service.expires_at(this->implementation);
  239. }
  240. /// Set the timer's expiry time as an absolute time.
  241. /**
  242. * This function sets the expiry time. Any pending asynchronous wait
  243. * operations will be cancelled. The handler for each cancelled operation will
  244. * be invoked with the boost::asio::error::operation_aborted error code.
  245. *
  246. * @param expiry_time The expiry time to be used for the timer.
  247. *
  248. * @return The number of asynchronous operations that were cancelled.
  249. *
  250. * @throws boost::system::system_error Thrown on failure.
  251. *
  252. * @note If the timer has already expired when expires_at() is called, then
  253. * the handlers for asynchronous wait operations will:
  254. *
  255. * @li have already been invoked; or
  256. *
  257. * @li have been queued for invocation in the near future.
  258. *
  259. * These handlers can no longer be cancelled, and therefore are passed an
  260. * error code that indicates the successful completion of the wait operation.
  261. */
  262. std::size_t expires_at(const time_type& expiry_time)
  263. {
  264. boost::system::error_code ec;
  265. std::size_t s = this->service.expires_at(
  266. this->implementation, expiry_time, ec);
  267. boost::asio::detail::throw_error(ec);
  268. return s;
  269. }
  270. /// Set the timer's expiry time as an absolute time.
  271. /**
  272. * This function sets the expiry time. Any pending asynchronous wait
  273. * operations will be cancelled. The handler for each cancelled operation will
  274. * be invoked with the boost::asio::error::operation_aborted error code.
  275. *
  276. * @param expiry_time The expiry time to be used for the timer.
  277. *
  278. * @param ec Set to indicate what error occurred, if any.
  279. *
  280. * @return The number of asynchronous operations that were cancelled.
  281. *
  282. * @note If the timer has already expired when expires_at() is called, then
  283. * the handlers for asynchronous wait operations will:
  284. *
  285. * @li have already been invoked; or
  286. *
  287. * @li have been queued for invocation in the near future.
  288. *
  289. * These handlers can no longer be cancelled, and therefore are passed an
  290. * error code that indicates the successful completion of the wait operation.
  291. */
  292. std::size_t expires_at(const time_type& expiry_time,
  293. boost::system::error_code& ec)
  294. {
  295. return this->service.expires_at(this->implementation, expiry_time, ec);
  296. }
  297. /// Get the timer's expiry time relative to now.
  298. /**
  299. * This function may be used to obtain the timer's current expiry time.
  300. * Whether the timer has expired or not does not affect this value.
  301. */
  302. duration_type expires_from_now() const
  303. {
  304. return this->service.expires_from_now(this->implementation);
  305. }
  306. /// Set the timer's expiry time relative to now.
  307. /**
  308. * This function sets the expiry time. Any pending asynchronous wait
  309. * operations will be cancelled. The handler for each cancelled operation will
  310. * be invoked with the boost::asio::error::operation_aborted error code.
  311. *
  312. * @param expiry_time The expiry time to be used for the timer.
  313. *
  314. * @return The number of asynchronous operations that were cancelled.
  315. *
  316. * @throws boost::system::system_error Thrown on failure.
  317. *
  318. * @note If the timer has already expired when expires_from_now() is called,
  319. * then the handlers for asynchronous wait operations will:
  320. *
  321. * @li have already been invoked; or
  322. *
  323. * @li have been queued for invocation in the near future.
  324. *
  325. * These handlers can no longer be cancelled, and therefore are passed an
  326. * error code that indicates the successful completion of the wait operation.
  327. */
  328. std::size_t expires_from_now(const duration_type& expiry_time)
  329. {
  330. boost::system::error_code ec;
  331. std::size_t s = this->service.expires_from_now(
  332. this->implementation, expiry_time, ec);
  333. boost::asio::detail::throw_error(ec);
  334. return s;
  335. }
  336. /// Set the timer's expiry time relative to now.
  337. /**
  338. * This function sets the expiry time. Any pending asynchronous wait
  339. * operations will be cancelled. The handler for each cancelled operation will
  340. * be invoked with the boost::asio::error::operation_aborted error code.
  341. *
  342. * @param expiry_time The expiry time to be used for the timer.
  343. *
  344. * @param ec Set to indicate what error occurred, if any.
  345. *
  346. * @return The number of asynchronous operations that were cancelled.
  347. *
  348. * @note If the timer has already expired when expires_from_now() is called,
  349. * then the handlers for asynchronous wait operations will:
  350. *
  351. * @li have already been invoked; or
  352. *
  353. * @li have been queued for invocation in the near future.
  354. *
  355. * These handlers can no longer be cancelled, and therefore are passed an
  356. * error code that indicates the successful completion of the wait operation.
  357. */
  358. std::size_t expires_from_now(const duration_type& expiry_time,
  359. boost::system::error_code& ec)
  360. {
  361. return this->service.expires_from_now(
  362. this->implementation, expiry_time, ec);
  363. }
  364. /// Perform a blocking wait on the timer.
  365. /**
  366. * This function is used to wait for the timer to expire. This function
  367. * blocks and does not return until the timer has expired.
  368. *
  369. * @throws boost::system::system_error Thrown on failure.
  370. */
  371. void wait()
  372. {
  373. boost::system::error_code ec;
  374. this->service.wait(this->implementation, ec);
  375. boost::asio::detail::throw_error(ec);
  376. }
  377. /// Perform a blocking wait on the timer.
  378. /**
  379. * This function is used to wait for the timer to expire. This function
  380. * blocks and does not return until the timer has expired.
  381. *
  382. * @param ec Set to indicate what error occurred, if any.
  383. */
  384. void wait(boost::system::error_code& ec)
  385. {
  386. this->service.wait(this->implementation, ec);
  387. }
  388. /// Start an asynchronous wait on the timer.
  389. /**
  390. * This function may be used to initiate an asynchronous wait against the
  391. * timer. It always returns immediately.
  392. *
  393. * For each call to async_wait(), the supplied handler will be called exactly
  394. * once. The handler will be called when:
  395. *
  396. * @li The timer has expired.
  397. *
  398. * @li The timer was cancelled, in which case the handler is passed the error
  399. * code boost::asio::error::operation_aborted.
  400. *
  401. * @param handler The handler to be called when the timer expires. Copies
  402. * will be made of the handler as required. The function signature of the
  403. * handler must be:
  404. * @code void handler(
  405. * const boost::system::error_code& error // Result of operation.
  406. * ); @endcode
  407. * Regardless of whether the asynchronous operation completes immediately or
  408. * not, the handler will not be invoked from within this function. Invocation
  409. * of the handler will be performed in a manner equivalent to using
  410. * boost::asio::io_service::post().
  411. */
  412. template <typename WaitHandler>
  413. void async_wait(WaitHandler handler)
  414. {
  415. this->service.async_wait(this->implementation, handler);
  416. }
  417. };
  418. } // namespace asio
  419. } // namespace boost
  420. #include <boost/asio/detail/pop_options.hpp>
  421. #endif // BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP