Chris@16: // Chris@16: // basic_deadline_timer.hpp Chris@16: // ~~~~~~~~~~~~~~~~~~~~~~~~ Chris@16: // Chris@101: // Copyright (c) 2003-2015 Christopher M. Kohlhoff (chris at kohlhoff dot com) Chris@16: // Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@16: // Chris@16: Chris@16: #ifndef BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP Chris@16: #define BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: # pragma once Chris@16: #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) Chris@16: Chris@16: #include Chris@16: Chris@16: #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \ Chris@16: || defined(GENERATING_DOCUMENTATION) Chris@16: Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: #include Chris@16: Chris@16: namespace boost { Chris@16: namespace asio { Chris@16: Chris@16: /// Provides waitable timer functionality. Chris@16: /** Chris@16: * The basic_deadline_timer class template provides the ability to perform a Chris@16: * blocking or asynchronous wait for a timer to expire. Chris@16: * Chris@16: * A deadline timer is always in one of two states: "expired" or "not expired". Chris@16: * If the wait() or async_wait() function is called on an expired timer, the Chris@16: * wait operation will complete immediately. Chris@16: * Chris@16: * Most applications will use the boost::asio::deadline_timer typedef. Chris@16: * Chris@16: * @par Thread Safety Chris@16: * @e Distinct @e objects: Safe.@n Chris@16: * @e Shared @e objects: Unsafe. Chris@16: * Chris@16: * @par Examples Chris@16: * Performing a blocking wait: Chris@16: * @code Chris@16: * // Construct a timer without setting an expiry time. Chris@16: * boost::asio::deadline_timer timer(io_service); Chris@16: * Chris@16: * // Set an expiry time relative to now. Chris@16: * timer.expires_from_now(boost::posix_time::seconds(5)); Chris@16: * Chris@16: * // Wait for the timer to expire. Chris@16: * timer.wait(); Chris@16: * @endcode Chris@16: * Chris@16: * @par Chris@16: * Performing an asynchronous wait: Chris@16: * @code Chris@16: * void handler(const boost::system::error_code& error) Chris@16: * { Chris@16: * if (!error) Chris@16: * { Chris@16: * // Timer expired. Chris@16: * } Chris@16: * } Chris@16: * Chris@16: * ... Chris@16: * Chris@16: * // Construct a timer with an absolute expiry time. Chris@16: * boost::asio::deadline_timer timer(io_service, Chris@16: * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); Chris@16: * Chris@16: * // Start an asynchronous wait. Chris@16: * timer.async_wait(handler); Chris@16: * @endcode Chris@16: * Chris@16: * @par Changing an active deadline_timer's expiry time Chris@16: * Chris@16: * Changing the expiry time of a timer while there are pending asynchronous Chris@16: * waits causes those wait operations to be cancelled. To ensure that the action Chris@16: * associated with the timer is performed only once, use something like this: Chris@16: * used: Chris@16: * Chris@16: * @code Chris@16: * void on_some_event() Chris@16: * { Chris@16: * if (my_timer.expires_from_now(seconds(5)) > 0) Chris@16: * { Chris@16: * // We managed to cancel the timer. Start new asynchronous wait. Chris@16: * my_timer.async_wait(on_timeout); Chris@16: * } Chris@16: * else Chris@16: * { Chris@16: * // Too late, timer has already expired! Chris@16: * } Chris@16: * } Chris@16: * Chris@16: * void on_timeout(const boost::system::error_code& e) Chris@16: * { Chris@16: * if (e != boost::asio::error::operation_aborted) Chris@16: * { Chris@16: * // Timer was not cancelled, take necessary action. Chris@16: * } Chris@16: * } Chris@16: * @endcode Chris@16: * Chris@16: * @li The boost::asio::basic_deadline_timer::expires_from_now() function Chris@16: * cancels any pending asynchronous waits, and returns the number of Chris@16: * asynchronous waits that were cancelled. If it returns 0 then you were too Chris@16: * late and the wait handler has already been executed, or will soon be Chris@16: * executed. If it returns 1 then the wait handler was successfully cancelled. Chris@16: * Chris@16: * @li If a wait handler is cancelled, the boost::system::error_code passed to Chris@16: * it contains the value boost::asio::error::operation_aborted. Chris@16: */ Chris@16: template , Chris@16: typename TimerService = deadline_timer_service > Chris@16: class basic_deadline_timer Chris@16: : public basic_io_object Chris@16: { Chris@16: public: Chris@16: /// The time traits type. Chris@16: typedef TimeTraits traits_type; Chris@16: Chris@16: /// The time type. Chris@16: typedef typename traits_type::time_type time_type; Chris@16: Chris@16: /// The duration type. Chris@16: typedef typename traits_type::duration_type duration_type; Chris@16: Chris@16: /// Constructor. Chris@16: /** Chris@16: * This constructor creates a timer without setting an expiry time. The Chris@16: * expires_at() or expires_from_now() functions must be called to set an Chris@16: * expiry time before the timer can be waited on. Chris@16: * Chris@16: * @param io_service The io_service object that the timer will use to dispatch Chris@16: * handlers for any asynchronous operations performed on the timer. Chris@16: */ Chris@16: explicit basic_deadline_timer(boost::asio::io_service& io_service) Chris@16: : basic_io_object(io_service) Chris@16: { Chris@16: } Chris@16: Chris@16: /// Constructor to set a particular expiry time as an absolute time. Chris@16: /** Chris@16: * This constructor creates a timer and sets the expiry time. Chris@16: * Chris@16: * @param io_service The io_service object that the timer will use to dispatch Chris@16: * handlers for any asynchronous operations performed on the timer. Chris@16: * Chris@16: * @param expiry_time The expiry time to be used for the timer, expressed Chris@16: * as an absolute time. Chris@16: */ Chris@16: basic_deadline_timer(boost::asio::io_service& io_service, Chris@16: const time_type& expiry_time) Chris@16: : basic_io_object(io_service) Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: this->service.expires_at(this->implementation, expiry_time, ec); Chris@16: boost::asio::detail::throw_error(ec, "expires_at"); Chris@16: } Chris@16: Chris@16: /// Constructor to set a particular expiry time relative to now. Chris@16: /** Chris@16: * This constructor creates a timer and sets the expiry time. Chris@16: * Chris@16: * @param io_service The io_service object that the timer will use to dispatch Chris@16: * handlers for any asynchronous operations performed on the timer. Chris@16: * Chris@16: * @param expiry_time The expiry time to be used for the timer, relative to Chris@16: * now. Chris@16: */ Chris@16: basic_deadline_timer(boost::asio::io_service& io_service, Chris@16: const duration_type& expiry_time) Chris@16: : basic_io_object(io_service) Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: this->service.expires_from_now(this->implementation, expiry_time, ec); Chris@16: boost::asio::detail::throw_error(ec, "expires_from_now"); Chris@16: } Chris@16: Chris@16: /// Cancel any asynchronous operations that are waiting on the timer. Chris@16: /** Chris@16: * This function forces the completion of any pending asynchronous wait Chris@16: * operations against the timer. The handler for each cancelled operation will Chris@16: * be invoked with the boost::asio::error::operation_aborted error code. Chris@16: * Chris@16: * Cancelling the timer does not change the expiry time. Chris@16: * Chris@16: * @return The number of asynchronous operations that were cancelled. Chris@16: * Chris@16: * @throws boost::system::system_error Thrown on failure. Chris@16: * Chris@16: * @note If the timer has already expired when cancel() is called, then the Chris@16: * handlers for asynchronous wait operations will: Chris@16: * Chris@16: * @li have already been invoked; or Chris@16: * Chris@16: * @li have been queued for invocation in the near future. Chris@16: * Chris@16: * These handlers can no longer be cancelled, and therefore are passed an Chris@16: * error code that indicates the successful completion of the wait operation. Chris@16: */ Chris@16: std::size_t cancel() Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: std::size_t s = this->service.cancel(this->implementation, ec); Chris@16: boost::asio::detail::throw_error(ec, "cancel"); Chris@16: return s; Chris@16: } Chris@16: Chris@16: /// Cancel any asynchronous operations that are waiting on the timer. Chris@16: /** Chris@16: * This function forces the completion of any pending asynchronous wait Chris@16: * operations against the timer. The handler for each cancelled operation will Chris@16: * be invoked with the boost::asio::error::operation_aborted error code. Chris@16: * Chris@16: * Cancelling the timer does not change the expiry time. Chris@16: * Chris@16: * @param ec Set to indicate what error occurred, if any. Chris@16: * Chris@16: * @return The number of asynchronous operations that were cancelled. Chris@16: * Chris@16: * @note If the timer has already expired when cancel() is called, then the Chris@16: * handlers for asynchronous wait operations will: Chris@16: * Chris@16: * @li have already been invoked; or Chris@16: * Chris@16: * @li have been queued for invocation in the near future. Chris@16: * Chris@16: * These handlers can no longer be cancelled, and therefore are passed an Chris@16: * error code that indicates the successful completion of the wait operation. Chris@16: */ Chris@16: std::size_t cancel(boost::system::error_code& ec) Chris@16: { Chris@16: return this->service.cancel(this->implementation, ec); Chris@16: } Chris@16: Chris@16: /// Cancels one asynchronous operation that is waiting on the timer. Chris@16: /** Chris@16: * This function forces the completion of one pending asynchronous wait Chris@16: * operation against the timer. Handlers are cancelled in FIFO order. The Chris@16: * handler for the cancelled operation will be invoked with the Chris@16: * boost::asio::error::operation_aborted error code. Chris@16: * Chris@16: * Cancelling the timer does not change the expiry time. Chris@16: * Chris@16: * @return The number of asynchronous operations that were cancelled. That is, Chris@16: * either 0 or 1. Chris@16: * Chris@16: * @throws boost::system::system_error Thrown on failure. Chris@16: * Chris@16: * @note If the timer has already expired when cancel_one() is called, then Chris@16: * the handlers for asynchronous wait operations will: Chris@16: * Chris@16: * @li have already been invoked; or Chris@16: * Chris@16: * @li have been queued for invocation in the near future. Chris@16: * Chris@16: * These handlers can no longer be cancelled, and therefore are passed an Chris@16: * error code that indicates the successful completion of the wait operation. Chris@16: */ Chris@16: std::size_t cancel_one() Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: std::size_t s = this->service.cancel_one(this->implementation, ec); Chris@16: boost::asio::detail::throw_error(ec, "cancel_one"); Chris@16: return s; Chris@16: } Chris@16: Chris@16: /// Cancels one asynchronous operation that is waiting on the timer. Chris@16: /** Chris@16: * This function forces the completion of one pending asynchronous wait Chris@16: * operation against the timer. Handlers are cancelled in FIFO order. The Chris@16: * handler for the cancelled operation will be invoked with the Chris@16: * boost::asio::error::operation_aborted error code. Chris@16: * Chris@16: * Cancelling the timer does not change the expiry time. Chris@16: * Chris@16: * @param ec Set to indicate what error occurred, if any. Chris@16: * Chris@16: * @return The number of asynchronous operations that were cancelled. That is, Chris@16: * either 0 or 1. Chris@16: * Chris@16: * @note If the timer has already expired when cancel_one() is called, then Chris@16: * the handlers for asynchronous wait operations will: Chris@16: * Chris@16: * @li have already been invoked; or Chris@16: * Chris@16: * @li have been queued for invocation in the near future. Chris@16: * Chris@16: * These handlers can no longer be cancelled, and therefore are passed an Chris@16: * error code that indicates the successful completion of the wait operation. Chris@16: */ Chris@16: std::size_t cancel_one(boost::system::error_code& ec) Chris@16: { Chris@16: return this->service.cancel_one(this->implementation, ec); Chris@16: } Chris@16: Chris@16: /// Get the timer's expiry time as an absolute time. Chris@16: /** Chris@16: * This function may be used to obtain the timer's current expiry time. Chris@16: * Whether the timer has expired or not does not affect this value. Chris@16: */ Chris@16: time_type expires_at() const Chris@16: { Chris@16: return this->service.expires_at(this->implementation); Chris@16: } Chris@16: Chris@16: /// Set the timer's expiry time as an absolute time. Chris@16: /** Chris@16: * This function sets the expiry time. Any pending asynchronous wait Chris@16: * operations will be cancelled. The handler for each cancelled operation will Chris@16: * be invoked with the boost::asio::error::operation_aborted error code. Chris@16: * Chris@16: * @param expiry_time The expiry time to be used for the timer. Chris@16: * Chris@16: * @return The number of asynchronous operations that were cancelled. Chris@16: * Chris@16: * @throws boost::system::system_error Thrown on failure. Chris@16: * Chris@16: * @note If the timer has already expired when expires_at() is called, then Chris@16: * the handlers for asynchronous wait operations will: Chris@16: * Chris@16: * @li have already been invoked; or Chris@16: * Chris@16: * @li have been queued for invocation in the near future. Chris@16: * Chris@16: * These handlers can no longer be cancelled, and therefore are passed an Chris@16: * error code that indicates the successful completion of the wait operation. Chris@16: */ Chris@16: std::size_t expires_at(const time_type& expiry_time) Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: std::size_t s = this->service.expires_at( Chris@16: this->implementation, expiry_time, ec); Chris@16: boost::asio::detail::throw_error(ec, "expires_at"); Chris@16: return s; Chris@16: } Chris@16: Chris@16: /// Set the timer's expiry time as an absolute time. Chris@16: /** Chris@16: * This function sets the expiry time. Any pending asynchronous wait Chris@16: * operations will be cancelled. The handler for each cancelled operation will Chris@16: * be invoked with the boost::asio::error::operation_aborted error code. Chris@16: * Chris@16: * @param expiry_time The expiry time to be used for the timer. Chris@16: * Chris@16: * @param ec Set to indicate what error occurred, if any. Chris@16: * Chris@16: * @return The number of asynchronous operations that were cancelled. Chris@16: * Chris@16: * @note If the timer has already expired when expires_at() is called, then Chris@16: * the handlers for asynchronous wait operations will: Chris@16: * Chris@16: * @li have already been invoked; or Chris@16: * Chris@16: * @li have been queued for invocation in the near future. Chris@16: * Chris@16: * These handlers can no longer be cancelled, and therefore are passed an Chris@16: * error code that indicates the successful completion of the wait operation. Chris@16: */ Chris@16: std::size_t expires_at(const time_type& expiry_time, Chris@16: boost::system::error_code& ec) Chris@16: { Chris@16: return this->service.expires_at(this->implementation, expiry_time, ec); Chris@16: } Chris@16: Chris@16: /// Get the timer's expiry time relative to now. Chris@16: /** Chris@16: * This function may be used to obtain the timer's current expiry time. Chris@16: * Whether the timer has expired or not does not affect this value. Chris@16: */ Chris@16: duration_type expires_from_now() const Chris@16: { Chris@16: return this->service.expires_from_now(this->implementation); Chris@16: } Chris@16: Chris@16: /// Set the timer's expiry time relative to now. Chris@16: /** Chris@16: * This function sets the expiry time. Any pending asynchronous wait Chris@16: * operations will be cancelled. The handler for each cancelled operation will Chris@16: * be invoked with the boost::asio::error::operation_aborted error code. Chris@16: * Chris@16: * @param expiry_time The expiry time to be used for the timer. Chris@16: * Chris@16: * @return The number of asynchronous operations that were cancelled. Chris@16: * Chris@16: * @throws boost::system::system_error Thrown on failure. Chris@16: * Chris@16: * @note If the timer has already expired when expires_from_now() is called, Chris@16: * then the handlers for asynchronous wait operations will: Chris@16: * Chris@16: * @li have already been invoked; or Chris@16: * Chris@16: * @li have been queued for invocation in the near future. Chris@16: * Chris@16: * These handlers can no longer be cancelled, and therefore are passed an Chris@16: * error code that indicates the successful completion of the wait operation. Chris@16: */ Chris@16: std::size_t expires_from_now(const duration_type& expiry_time) Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: std::size_t s = this->service.expires_from_now( Chris@16: this->implementation, expiry_time, ec); Chris@16: boost::asio::detail::throw_error(ec, "expires_from_now"); Chris@16: return s; Chris@16: } Chris@16: Chris@16: /// Set the timer's expiry time relative to now. Chris@16: /** Chris@16: * This function sets the expiry time. Any pending asynchronous wait Chris@16: * operations will be cancelled. The handler for each cancelled operation will Chris@16: * be invoked with the boost::asio::error::operation_aborted error code. Chris@16: * Chris@16: * @param expiry_time The expiry time to be used for the timer. Chris@16: * Chris@16: * @param ec Set to indicate what error occurred, if any. Chris@16: * Chris@16: * @return The number of asynchronous operations that were cancelled. Chris@16: * Chris@16: * @note If the timer has already expired when expires_from_now() is called, Chris@16: * then the handlers for asynchronous wait operations will: Chris@16: * Chris@16: * @li have already been invoked; or Chris@16: * Chris@16: * @li have been queued for invocation in the near future. Chris@16: * Chris@16: * These handlers can no longer be cancelled, and therefore are passed an Chris@16: * error code that indicates the successful completion of the wait operation. Chris@16: */ Chris@16: std::size_t expires_from_now(const duration_type& expiry_time, Chris@16: boost::system::error_code& ec) Chris@16: { Chris@16: return this->service.expires_from_now( Chris@16: this->implementation, expiry_time, ec); Chris@16: } Chris@16: Chris@16: /// Perform a blocking wait on the timer. Chris@16: /** Chris@16: * This function is used to wait for the timer to expire. This function Chris@16: * blocks and does not return until the timer has expired. Chris@16: * Chris@16: * @throws boost::system::system_error Thrown on failure. Chris@16: */ Chris@16: void wait() Chris@16: { Chris@16: boost::system::error_code ec; Chris@16: this->service.wait(this->implementation, ec); Chris@16: boost::asio::detail::throw_error(ec, "wait"); Chris@16: } Chris@16: Chris@16: /// Perform a blocking wait on the timer. Chris@16: /** Chris@16: * This function is used to wait for the timer to expire. This function Chris@16: * blocks and does not return until the timer has expired. Chris@16: * Chris@16: * @param ec Set to indicate what error occurred, if any. Chris@16: */ Chris@16: void wait(boost::system::error_code& ec) Chris@16: { Chris@16: this->service.wait(this->implementation, ec); Chris@16: } Chris@16: Chris@16: /// Start an asynchronous wait on the timer. Chris@16: /** Chris@16: * This function may be used to initiate an asynchronous wait against the Chris@16: * timer. It always returns immediately. Chris@16: * Chris@16: * For each call to async_wait(), the supplied handler will be called exactly Chris@16: * once. The handler will be called when: Chris@16: * Chris@16: * @li The timer has expired. Chris@16: * Chris@16: * @li The timer was cancelled, in which case the handler is passed the error Chris@16: * code boost::asio::error::operation_aborted. Chris@16: * Chris@16: * @param handler The handler to be called when the timer expires. Copies Chris@16: * will be made of the handler as required. The function signature of the Chris@16: * handler must be: Chris@16: * @code void handler( Chris@16: * const boost::system::error_code& error // Result of operation. Chris@16: * ); @endcode Chris@16: * Regardless of whether the asynchronous operation completes immediately or Chris@16: * not, the handler will not be invoked from within this function. Invocation Chris@16: * of the handler will be performed in a manner equivalent to using Chris@16: * boost::asio::io_service::post(). Chris@16: */ Chris@16: template Chris@16: BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, Chris@16: void (boost::system::error_code)) Chris@16: async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) Chris@16: { Chris@16: // If you get an error on the following line it means that your handler does Chris@16: // not meet the documented type requirements for a WaitHandler. Chris@16: BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; Chris@16: Chris@16: return this->service.async_wait(this->implementation, Chris@16: BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); Chris@16: } Chris@16: }; Chris@16: Chris@16: } // namespace asio Chris@16: } // namespace boost Chris@16: Chris@16: #include Chris@16: Chris@16: #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) Chris@16: // || defined(GENERATING_DOCUMENTATION) Chris@16: Chris@16: #endif // BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP