|
||||
File indexing completed on 2025-01-18 09:29:07
0001 // 0002 // basic_waitable_timer.hpp 0003 // ~~~~~~~~~~~~~~~~~~~~~~~~ 0004 // 0005 // Copyright (c) 2003-2023 Christopher M. Kohlhoff (chris at kohlhoff dot com) 0006 // 0007 // Distributed under the Boost Software License, Version 1.0. (See accompanying 0008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 0009 // 0010 0011 #ifndef BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP 0012 #define BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP 0013 0014 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 0015 # pragma once 0016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 0017 0018 #include <boost/asio/detail/config.hpp> 0019 #include <cstddef> 0020 #include <utility> 0021 #include <boost/asio/any_io_executor.hpp> 0022 #include <boost/asio/detail/chrono_time_traits.hpp> 0023 #include <boost/asio/detail/deadline_timer_service.hpp> 0024 #include <boost/asio/detail/handler_type_requirements.hpp> 0025 #include <boost/asio/detail/io_object_impl.hpp> 0026 #include <boost/asio/detail/non_const_lvalue.hpp> 0027 #include <boost/asio/detail/throw_error.hpp> 0028 #include <boost/asio/error.hpp> 0029 #include <boost/asio/wait_traits.hpp> 0030 0031 #include <boost/asio/detail/push_options.hpp> 0032 0033 namespace boost { 0034 namespace asio { 0035 0036 #if !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) 0037 #define BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL 0038 0039 // Forward declaration with defaulted arguments. 0040 template <typename Clock, 0041 typename WaitTraits = boost::asio::wait_traits<Clock>, 0042 typename Executor = any_io_executor> 0043 class basic_waitable_timer; 0044 0045 #endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) 0046 0047 /// Provides waitable timer functionality. 0048 /** 0049 * The basic_waitable_timer class template provides the ability to perform a 0050 * blocking or asynchronous wait for a timer to expire. 0051 * 0052 * A waitable timer is always in one of two states: "expired" or "not expired". 0053 * If the wait() or async_wait() function is called on an expired timer, the 0054 * wait operation will complete immediately. 0055 * 0056 * Most applications will use one of the boost::asio::steady_timer, 0057 * boost::asio::system_timer or boost::asio::high_resolution_timer typedefs. 0058 * 0059 * @note This waitable timer functionality is for use with the C++11 standard 0060 * library's @c <chrono> facility, or with the Boost.Chrono library. 0061 * 0062 * @par Thread Safety 0063 * @e Distinct @e objects: Safe.@n 0064 * @e Shared @e objects: Unsafe. 0065 * 0066 * @par Examples 0067 * Performing a blocking wait (C++11): 0068 * @code 0069 * // Construct a timer without setting an expiry time. 0070 * boost::asio::steady_timer timer(my_context); 0071 * 0072 * // Set an expiry time relative to now. 0073 * timer.expires_after(std::chrono::seconds(5)); 0074 * 0075 * // Wait for the timer to expire. 0076 * timer.wait(); 0077 * @endcode 0078 * 0079 * @par 0080 * Performing an asynchronous wait (C++11): 0081 * @code 0082 * void handler(const boost::system::error_code& error) 0083 * { 0084 * if (!error) 0085 * { 0086 * // Timer expired. 0087 * } 0088 * } 0089 * 0090 * ... 0091 * 0092 * // Construct a timer with an absolute expiry time. 0093 * boost::asio::steady_timer timer(my_context, 0094 * std::chrono::steady_clock::now() + std::chrono::seconds(60)); 0095 * 0096 * // Start an asynchronous wait. 0097 * timer.async_wait(handler); 0098 * @endcode 0099 * 0100 * @par Changing an active waitable timer's expiry time 0101 * 0102 * Changing the expiry time of a timer while there are pending asynchronous 0103 * waits causes those wait operations to be cancelled. To ensure that the action 0104 * associated with the timer is performed only once, use something like this: 0105 * used: 0106 * 0107 * @code 0108 * void on_some_event() 0109 * { 0110 * if (my_timer.expires_after(seconds(5)) > 0) 0111 * { 0112 * // We managed to cancel the timer. Start new asynchronous wait. 0113 * my_timer.async_wait(on_timeout); 0114 * } 0115 * else 0116 * { 0117 * // Too late, timer has already expired! 0118 * } 0119 * } 0120 * 0121 * void on_timeout(const boost::system::error_code& e) 0122 * { 0123 * if (e != boost::asio::error::operation_aborted) 0124 * { 0125 * // Timer was not cancelled, take necessary action. 0126 * } 0127 * } 0128 * @endcode 0129 * 0130 * @li The boost::asio::basic_waitable_timer::expires_after() function 0131 * cancels any pending asynchronous waits, and returns the number of 0132 * asynchronous waits that were cancelled. If it returns 0 then you were too 0133 * late and the wait handler has already been executed, or will soon be 0134 * executed. If it returns 1 then the wait handler was successfully cancelled. 0135 * 0136 * @li If a wait handler is cancelled, the boost::system::error_code passed to 0137 * it contains the value boost::asio::error::operation_aborted. 0138 */ 0139 template <typename Clock, typename WaitTraits, typename Executor> 0140 class basic_waitable_timer 0141 { 0142 private: 0143 class initiate_async_wait; 0144 0145 public: 0146 /// The type of the executor associated with the object. 0147 typedef Executor executor_type; 0148 0149 /// Rebinds the timer type to another executor. 0150 template <typename Executor1> 0151 struct rebind_executor 0152 { 0153 /// The timer type when rebound to the specified executor. 0154 typedef basic_waitable_timer<Clock, WaitTraits, Executor1> other; 0155 }; 0156 0157 /// The clock type. 0158 typedef Clock clock_type; 0159 0160 /// The duration type of the clock. 0161 typedef typename clock_type::duration duration; 0162 0163 /// The time point type of the clock. 0164 typedef typename clock_type::time_point time_point; 0165 0166 /// The wait traits type. 0167 typedef WaitTraits traits_type; 0168 0169 /// Constructor. 0170 /** 0171 * This constructor creates a timer without setting an expiry time. The 0172 * expires_at() or expires_after() functions must be called to set an expiry 0173 * time before the timer can be waited on. 0174 * 0175 * @param ex The I/O executor that the timer will use, by default, to 0176 * dispatch handlers for any asynchronous operations performed on the timer. 0177 */ 0178 explicit basic_waitable_timer(const executor_type& ex) 0179 : impl_(0, ex) 0180 { 0181 } 0182 0183 /// Constructor. 0184 /** 0185 * This constructor creates a timer without setting an expiry time. The 0186 * expires_at() or expires_after() functions must be called to set an expiry 0187 * time before the timer can be waited on. 0188 * 0189 * @param context An execution context which provides the I/O executor that 0190 * the timer will use, by default, to dispatch handlers for any asynchronous 0191 * operations performed on the timer. 0192 */ 0193 template <typename ExecutionContext> 0194 explicit basic_waitable_timer(ExecutionContext& context, 0195 constraint_t< 0196 is_convertible<ExecutionContext&, execution_context&>::value 0197 > = 0) 0198 : impl_(0, 0, context) 0199 { 0200 } 0201 0202 /// Constructor to set a particular expiry time as an absolute time. 0203 /** 0204 * This constructor creates a timer and sets the expiry time. 0205 * 0206 * @param ex The I/O executor object that the timer will use, by default, to 0207 * dispatch handlers for any asynchronous operations performed on the timer. 0208 * 0209 * @param expiry_time The expiry time to be used for the timer, expressed 0210 * as an absolute time. 0211 */ 0212 basic_waitable_timer(const executor_type& ex, const time_point& expiry_time) 0213 : impl_(0, ex) 0214 { 0215 boost::system::error_code ec; 0216 impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); 0217 boost::asio::detail::throw_error(ec, "expires_at"); 0218 } 0219 0220 /// Constructor to set a particular expiry time as an absolute time. 0221 /** 0222 * This constructor creates a timer and sets the expiry time. 0223 * 0224 * @param context An execution context which provides the I/O executor that 0225 * the timer will use, by default, to dispatch handlers for any asynchronous 0226 * operations performed on the timer. 0227 * 0228 * @param expiry_time The expiry time to be used for the timer, expressed 0229 * as an absolute time. 0230 */ 0231 template <typename ExecutionContext> 0232 explicit basic_waitable_timer(ExecutionContext& context, 0233 const time_point& expiry_time, 0234 constraint_t< 0235 is_convertible<ExecutionContext&, execution_context&>::value 0236 > = 0) 0237 : impl_(0, 0, context) 0238 { 0239 boost::system::error_code ec; 0240 impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); 0241 boost::asio::detail::throw_error(ec, "expires_at"); 0242 } 0243 0244 /// Constructor to set a particular expiry time relative to now. 0245 /** 0246 * This constructor creates a timer and sets the expiry time. 0247 * 0248 * @param ex The I/O executor that the timer will use, by default, to 0249 * dispatch handlers for any asynchronous operations performed on the timer. 0250 * 0251 * @param expiry_time The expiry time to be used for the timer, relative to 0252 * now. 0253 */ 0254 basic_waitable_timer(const executor_type& ex, const duration& expiry_time) 0255 : impl_(0, ex) 0256 { 0257 boost::system::error_code ec; 0258 impl_.get_service().expires_after( 0259 impl_.get_implementation(), expiry_time, ec); 0260 boost::asio::detail::throw_error(ec, "expires_after"); 0261 } 0262 0263 /// Constructor to set a particular expiry time relative to now. 0264 /** 0265 * This constructor creates a timer and sets the expiry time. 0266 * 0267 * @param context An execution context which provides the I/O executor that 0268 * the timer will use, by default, to dispatch handlers for any asynchronous 0269 * operations performed on the timer. 0270 * 0271 * @param expiry_time The expiry time to be used for the timer, relative to 0272 * now. 0273 */ 0274 template <typename ExecutionContext> 0275 explicit basic_waitable_timer(ExecutionContext& context, 0276 const duration& expiry_time, 0277 constraint_t< 0278 is_convertible<ExecutionContext&, execution_context&>::value 0279 > = 0) 0280 : impl_(0, 0, context) 0281 { 0282 boost::system::error_code ec; 0283 impl_.get_service().expires_after( 0284 impl_.get_implementation(), expiry_time, ec); 0285 boost::asio::detail::throw_error(ec, "expires_after"); 0286 } 0287 0288 /// Move-construct a basic_waitable_timer from another. 0289 /** 0290 * This constructor moves a timer from one object to another. 0291 * 0292 * @param other The other basic_waitable_timer object from which the move will 0293 * occur. 0294 * 0295 * @note Following the move, the moved-from object is in the same state as if 0296 * constructed using the @c basic_waitable_timer(const executor_type&) 0297 * constructor. 0298 */ 0299 basic_waitable_timer(basic_waitable_timer&& other) 0300 : impl_(std::move(other.impl_)) 0301 { 0302 } 0303 0304 /// Move-assign a basic_waitable_timer from another. 0305 /** 0306 * This assignment operator moves a timer from one object to another. Cancels 0307 * any outstanding asynchronous operations associated with the target object. 0308 * 0309 * @param other The other basic_waitable_timer object from which the move will 0310 * occur. 0311 * 0312 * @note Following the move, the moved-from object is in the same state as if 0313 * constructed using the @c basic_waitable_timer(const executor_type&) 0314 * constructor. 0315 */ 0316 basic_waitable_timer& operator=(basic_waitable_timer&& other) 0317 { 0318 impl_ = std::move(other.impl_); 0319 return *this; 0320 } 0321 0322 // All timers have access to each other's implementations. 0323 template <typename Clock1, typename WaitTraits1, typename Executor1> 0324 friend class basic_waitable_timer; 0325 0326 /// Move-construct a basic_waitable_timer from another. 0327 /** 0328 * This constructor moves a timer from one object to another. 0329 * 0330 * @param other The other basic_waitable_timer object from which the move will 0331 * occur. 0332 * 0333 * @note Following the move, the moved-from object is in the same state as if 0334 * constructed using the @c basic_waitable_timer(const executor_type&) 0335 * constructor. 0336 */ 0337 template <typename Executor1> 0338 basic_waitable_timer( 0339 basic_waitable_timer<Clock, WaitTraits, Executor1>&& other, 0340 constraint_t< 0341 is_convertible<Executor1, Executor>::value 0342 > = 0) 0343 : impl_(std::move(other.impl_)) 0344 { 0345 } 0346 0347 /// Move-assign a basic_waitable_timer from another. 0348 /** 0349 * This assignment operator moves a timer from one object to another. Cancels 0350 * any outstanding asynchronous operations associated with the target object. 0351 * 0352 * @param other The other basic_waitable_timer object from which the move will 0353 * occur. 0354 * 0355 * @note Following the move, the moved-from object is in the same state as if 0356 * constructed using the @c basic_waitable_timer(const executor_type&) 0357 * constructor. 0358 */ 0359 template <typename Executor1> 0360 constraint_t< 0361 is_convertible<Executor1, Executor>::value, 0362 basic_waitable_timer& 0363 > operator=(basic_waitable_timer<Clock, WaitTraits, Executor1>&& other) 0364 { 0365 basic_waitable_timer tmp(std::move(other)); 0366 impl_ = std::move(tmp.impl_); 0367 return *this; 0368 } 0369 0370 /// Destroys the timer. 0371 /** 0372 * This function destroys the timer, cancelling any outstanding asynchronous 0373 * wait operations associated with the timer as if by calling @c cancel. 0374 */ 0375 ~basic_waitable_timer() 0376 { 0377 } 0378 0379 /// Get the executor associated with the object. 0380 const executor_type& get_executor() noexcept 0381 { 0382 return impl_.get_executor(); 0383 } 0384 0385 /// Cancel any asynchronous operations that are waiting on the timer. 0386 /** 0387 * This function forces the completion of any pending asynchronous wait 0388 * operations against the timer. The handler for each cancelled operation will 0389 * be invoked with the boost::asio::error::operation_aborted error code. 0390 * 0391 * Cancelling the timer does not change the expiry time. 0392 * 0393 * @return The number of asynchronous operations that were cancelled. 0394 * 0395 * @throws boost::system::system_error Thrown on failure. 0396 * 0397 * @note If the timer has already expired when cancel() is called, then the 0398 * handlers for asynchronous wait operations will: 0399 * 0400 * @li have already been invoked; or 0401 * 0402 * @li have been queued for invocation in the near future. 0403 * 0404 * These handlers can no longer be cancelled, and therefore are passed an 0405 * error code that indicates the successful completion of the wait operation. 0406 */ 0407 std::size_t cancel() 0408 { 0409 boost::system::error_code ec; 0410 std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec); 0411 boost::asio::detail::throw_error(ec, "cancel"); 0412 return s; 0413 } 0414 0415 #if !defined(BOOST_ASIO_NO_DEPRECATED) 0416 /// (Deprecated: Use non-error_code overload.) Cancel any asynchronous 0417 /// operations that are waiting on the timer. 0418 /** 0419 * This function forces the completion of any pending asynchronous wait 0420 * operations against the timer. The handler for each cancelled operation will 0421 * be invoked with the boost::asio::error::operation_aborted error code. 0422 * 0423 * Cancelling the timer does not change the expiry time. 0424 * 0425 * @param ec Set to indicate what error occurred, if any. 0426 * 0427 * @return The number of asynchronous operations that were cancelled. 0428 * 0429 * @note If the timer has already expired when cancel() is called, then the 0430 * handlers for asynchronous wait operations will: 0431 * 0432 * @li have already been invoked; or 0433 * 0434 * @li have been queued for invocation in the near future. 0435 * 0436 * These handlers can no longer be cancelled, and therefore are passed an 0437 * error code that indicates the successful completion of the wait operation. 0438 */ 0439 std::size_t cancel(boost::system::error_code& ec) 0440 { 0441 return impl_.get_service().cancel(impl_.get_implementation(), ec); 0442 } 0443 #endif // !defined(BOOST_ASIO_NO_DEPRECATED) 0444 0445 /// Cancels one asynchronous operation that is waiting on the timer. 0446 /** 0447 * This function forces the completion of one pending asynchronous wait 0448 * operation against the timer. Handlers are cancelled in FIFO order. The 0449 * handler for the cancelled operation will be invoked with the 0450 * boost::asio::error::operation_aborted error code. 0451 * 0452 * Cancelling the timer does not change the expiry time. 0453 * 0454 * @return The number of asynchronous operations that were cancelled. That is, 0455 * either 0 or 1. 0456 * 0457 * @throws boost::system::system_error Thrown on failure. 0458 * 0459 * @note If the timer has already expired when cancel_one() is called, then 0460 * the handlers for asynchronous wait operations will: 0461 * 0462 * @li have already been invoked; or 0463 * 0464 * @li have been queued for invocation in the near future. 0465 * 0466 * These handlers can no longer be cancelled, and therefore are passed an 0467 * error code that indicates the successful completion of the wait operation. 0468 */ 0469 std::size_t cancel_one() 0470 { 0471 boost::system::error_code ec; 0472 std::size_t s = impl_.get_service().cancel_one( 0473 impl_.get_implementation(), ec); 0474 boost::asio::detail::throw_error(ec, "cancel_one"); 0475 return s; 0476 } 0477 0478 #if !defined(BOOST_ASIO_NO_DEPRECATED) 0479 /// (Deprecated: Use non-error_code overload.) Cancels one asynchronous 0480 /// operation that is waiting on the timer. 0481 /** 0482 * This function forces the completion of one pending asynchronous wait 0483 * operation against the timer. Handlers are cancelled in FIFO order. The 0484 * handler for the cancelled operation will be invoked with the 0485 * boost::asio::error::operation_aborted error code. 0486 * 0487 * Cancelling the timer does not change the expiry time. 0488 * 0489 * @param ec Set to indicate what error occurred, if any. 0490 * 0491 * @return The number of asynchronous operations that were cancelled. That is, 0492 * either 0 or 1. 0493 * 0494 * @note If the timer has already expired when cancel_one() is called, then 0495 * the handlers for asynchronous wait operations will: 0496 * 0497 * @li have already been invoked; or 0498 * 0499 * @li have been queued for invocation in the near future. 0500 * 0501 * These handlers can no longer be cancelled, and therefore are passed an 0502 * error code that indicates the successful completion of the wait operation. 0503 */ 0504 std::size_t cancel_one(boost::system::error_code& ec) 0505 { 0506 return impl_.get_service().cancel_one(impl_.get_implementation(), ec); 0507 } 0508 0509 /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute 0510 /// time. 0511 /** 0512 * This function may be used to obtain the timer's current expiry time. 0513 * Whether the timer has expired or not does not affect this value. 0514 */ 0515 time_point expires_at() const 0516 { 0517 return impl_.get_service().expires_at(impl_.get_implementation()); 0518 } 0519 #endif // !defined(BOOST_ASIO_NO_DEPRECATED) 0520 0521 /// Get the timer's expiry time as an absolute time. 0522 /** 0523 * This function may be used to obtain the timer's current expiry time. 0524 * Whether the timer has expired or not does not affect this value. 0525 */ 0526 time_point expiry() const 0527 { 0528 return impl_.get_service().expiry(impl_.get_implementation()); 0529 } 0530 0531 /// Set the timer's expiry time as an absolute time. 0532 /** 0533 * This function sets the expiry time. Any pending asynchronous wait 0534 * operations will be cancelled. The handler for each cancelled operation will 0535 * be invoked with the boost::asio::error::operation_aborted error code. 0536 * 0537 * @param expiry_time The expiry time to be used for the timer. 0538 * 0539 * @return The number of asynchronous operations that were cancelled. 0540 * 0541 * @throws boost::system::system_error Thrown on failure. 0542 * 0543 * @note If the timer has already expired when expires_at() is called, then 0544 * the handlers for asynchronous wait operations will: 0545 * 0546 * @li have already been invoked; or 0547 * 0548 * @li have been queued for invocation in the near future. 0549 * 0550 * These handlers can no longer be cancelled, and therefore are passed an 0551 * error code that indicates the successful completion of the wait operation. 0552 */ 0553 std::size_t expires_at(const time_point& expiry_time) 0554 { 0555 boost::system::error_code ec; 0556 std::size_t s = impl_.get_service().expires_at( 0557 impl_.get_implementation(), expiry_time, ec); 0558 boost::asio::detail::throw_error(ec, "expires_at"); 0559 return s; 0560 } 0561 0562 #if !defined(BOOST_ASIO_NO_DEPRECATED) 0563 /// (Deprecated: Use non-error_code overload.) Set the timer's expiry time as 0564 /// an absolute time. 0565 /** 0566 * This function sets the expiry time. Any pending asynchronous wait 0567 * operations will be cancelled. The handler for each cancelled operation will 0568 * be invoked with the boost::asio::error::operation_aborted error code. 0569 * 0570 * @param expiry_time The expiry time to be used for the timer. 0571 * 0572 * @param ec Set to indicate what error occurred, if any. 0573 * 0574 * @return The number of asynchronous operations that were cancelled. 0575 * 0576 * @note If the timer has already expired when expires_at() is called, then 0577 * the handlers for asynchronous wait operations will: 0578 * 0579 * @li have already been invoked; or 0580 * 0581 * @li have been queued for invocation in the near future. 0582 * 0583 * These handlers can no longer be cancelled, and therefore are passed an 0584 * error code that indicates the successful completion of the wait operation. 0585 */ 0586 std::size_t expires_at(const time_point& expiry_time, 0587 boost::system::error_code& ec) 0588 { 0589 return impl_.get_service().expires_at( 0590 impl_.get_implementation(), expiry_time, ec); 0591 } 0592 #endif // !defined(BOOST_ASIO_NO_DEPRECATED) 0593 0594 /// Set the timer's expiry time relative to now. 0595 /** 0596 * This function sets the expiry time. Any pending asynchronous wait 0597 * operations will be cancelled. The handler for each cancelled operation will 0598 * be invoked with the boost::asio::error::operation_aborted error code. 0599 * 0600 * @param expiry_time The expiry time to be used for the timer. 0601 * 0602 * @return The number of asynchronous operations that were cancelled. 0603 * 0604 * @throws boost::system::system_error Thrown on failure. 0605 * 0606 * @note If the timer has already expired when expires_after() is called, 0607 * then the handlers for asynchronous wait operations will: 0608 * 0609 * @li have already been invoked; or 0610 * 0611 * @li have been queued for invocation in the near future. 0612 * 0613 * These handlers can no longer be cancelled, and therefore are passed an 0614 * error code that indicates the successful completion of the wait operation. 0615 */ 0616 std::size_t expires_after(const duration& expiry_time) 0617 { 0618 boost::system::error_code ec; 0619 std::size_t s = impl_.get_service().expires_after( 0620 impl_.get_implementation(), expiry_time, ec); 0621 boost::asio::detail::throw_error(ec, "expires_after"); 0622 return s; 0623 } 0624 0625 #if !defined(BOOST_ASIO_NO_DEPRECATED) 0626 /// (Deprecated: Use expiry().) Get the timer's expiry time relative to now. 0627 /** 0628 * This function may be used to obtain the timer's current expiry time. 0629 * Whether the timer has expired or not does not affect this value. 0630 */ 0631 duration expires_from_now() const 0632 { 0633 return impl_.get_service().expires_from_now(impl_.get_implementation()); 0634 } 0635 0636 /// (Deprecated: Use expires_after().) Set the timer's expiry time relative 0637 /// to now. 0638 /** 0639 * This function sets the expiry time. Any pending asynchronous wait 0640 * operations will be cancelled. The handler for each cancelled operation will 0641 * be invoked with the boost::asio::error::operation_aborted error code. 0642 * 0643 * @param expiry_time The expiry time to be used for the timer. 0644 * 0645 * @return The number of asynchronous operations that were cancelled. 0646 * 0647 * @throws boost::system::system_error Thrown on failure. 0648 * 0649 * @note If the timer has already expired when expires_from_now() is called, 0650 * then the handlers for asynchronous wait operations will: 0651 * 0652 * @li have already been invoked; or 0653 * 0654 * @li have been queued for invocation in the near future. 0655 * 0656 * These handlers can no longer be cancelled, and therefore are passed an 0657 * error code that indicates the successful completion of the wait operation. 0658 */ 0659 std::size_t expires_from_now(const duration& expiry_time) 0660 { 0661 boost::system::error_code ec; 0662 std::size_t s = impl_.get_service().expires_from_now( 0663 impl_.get_implementation(), expiry_time, ec); 0664 boost::asio::detail::throw_error(ec, "expires_from_now"); 0665 return s; 0666 } 0667 0668 /// (Deprecated: Use expires_after().) Set the timer's expiry time relative 0669 /// to now. 0670 /** 0671 * This function sets the expiry time. Any pending asynchronous wait 0672 * operations will be cancelled. The handler for each cancelled operation will 0673 * be invoked with the boost::asio::error::operation_aborted error code. 0674 * 0675 * @param expiry_time The expiry time to be used for the timer. 0676 * 0677 * @param ec Set to indicate what error occurred, if any. 0678 * 0679 * @return The number of asynchronous operations that were cancelled. 0680 * 0681 * @note If the timer has already expired when expires_from_now() is called, 0682 * then the handlers for asynchronous wait operations will: 0683 * 0684 * @li have already been invoked; or 0685 * 0686 * @li have been queued for invocation in the near future. 0687 * 0688 * These handlers can no longer be cancelled, and therefore are passed an 0689 * error code that indicates the successful completion of the wait operation. 0690 */ 0691 std::size_t expires_from_now(const duration& expiry_time, 0692 boost::system::error_code& ec) 0693 { 0694 return impl_.get_service().expires_from_now( 0695 impl_.get_implementation(), expiry_time, ec); 0696 } 0697 #endif // !defined(BOOST_ASIO_NO_DEPRECATED) 0698 0699 /// Perform a blocking wait on the timer. 0700 /** 0701 * This function is used to wait for the timer to expire. This function 0702 * blocks and does not return until the timer has expired. 0703 * 0704 * @throws boost::system::system_error Thrown on failure. 0705 */ 0706 void wait() 0707 { 0708 boost::system::error_code ec; 0709 impl_.get_service().wait(impl_.get_implementation(), ec); 0710 boost::asio::detail::throw_error(ec, "wait"); 0711 } 0712 0713 /// Perform a blocking wait on the timer. 0714 /** 0715 * This function is used to wait for the timer to expire. This function 0716 * blocks and does not return until the timer has expired. 0717 * 0718 * @param ec Set to indicate what error occurred, if any. 0719 */ 0720 void wait(boost::system::error_code& ec) 0721 { 0722 impl_.get_service().wait(impl_.get_implementation(), ec); 0723 } 0724 0725 /// Start an asynchronous wait on the timer. 0726 /** 0727 * This function may be used to initiate an asynchronous wait against the 0728 * timer. It is an initiating function for an @ref asynchronous_operation, 0729 * and always returns immediately. 0730 * 0731 * For each call to async_wait(), the completion handler will be called 0732 * exactly once. The completion handler will be called when: 0733 * 0734 * @li The timer has expired. 0735 * 0736 * @li The timer was cancelled, in which case the handler is passed the error 0737 * code boost::asio::error::operation_aborted. 0738 * 0739 * @param token The @ref completion_token that will be used to produce a 0740 * completion handler, which will be called when the timer expires. Potential 0741 * completion tokens include @ref use_future, @ref use_awaitable, @ref 0742 * yield_context, or a function object with the correct completion signature. 0743 * The function signature of the completion handler must be: 0744 * @code void handler( 0745 * const boost::system::error_code& error // Result of operation. 0746 * ); @endcode 0747 * Regardless of whether the asynchronous operation completes immediately or 0748 * not, the completion handler will not be invoked from within this function. 0749 * On immediate completion, invocation of the handler will be performed in a 0750 * manner equivalent to using boost::asio::post(). 0751 * 0752 * @par Completion Signature 0753 * @code void(boost::system::error_code) @endcode 0754 * 0755 * @par Per-Operation Cancellation 0756 * This asynchronous operation supports cancellation for the following 0757 * boost::asio::cancellation_type values: 0758 * 0759 * @li @c cancellation_type::terminal 0760 * 0761 * @li @c cancellation_type::partial 0762 * 0763 * @li @c cancellation_type::total 0764 */ 0765 template < 0766 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 0767 WaitToken = default_completion_token_t<executor_type>> 0768 auto async_wait( 0769 WaitToken&& token = default_completion_token_t<executor_type>()) 0770 -> decltype( 0771 async_initiate<WaitToken, void (boost::system::error_code)>( 0772 declval<initiate_async_wait>(), token)) 0773 { 0774 return async_initiate<WaitToken, void (boost::system::error_code)>( 0775 initiate_async_wait(this), token); 0776 } 0777 0778 private: 0779 // Disallow copying and assignment. 0780 basic_waitable_timer(const basic_waitable_timer&) = delete; 0781 basic_waitable_timer& operator=(const basic_waitable_timer&) = delete; 0782 0783 class initiate_async_wait 0784 { 0785 public: 0786 typedef Executor executor_type; 0787 0788 explicit initiate_async_wait(basic_waitable_timer* self) 0789 : self_(self) 0790 { 0791 } 0792 0793 const executor_type& get_executor() const noexcept 0794 { 0795 return self_->get_executor(); 0796 } 0797 0798 template <typename WaitHandler> 0799 void operator()(WaitHandler&& handler) const 0800 { 0801 // If you get an error on the following line it means that your handler 0802 // does not meet the documented type requirements for a WaitHandler. 0803 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; 0804 0805 detail::non_const_lvalue<WaitHandler> handler2(handler); 0806 self_->impl_.get_service().async_wait( 0807 self_->impl_.get_implementation(), 0808 handler2.value, self_->impl_.get_executor()); 0809 } 0810 0811 private: 0812 basic_waitable_timer* self_; 0813 }; 0814 0815 detail::io_object_impl< 0816 detail::deadline_timer_service< 0817 detail::chrono_time_traits<Clock, WaitTraits>>, 0818 executor_type > impl_; 0819 }; 0820 0821 } // namespace asio 0822 } // namespace boost 0823 0824 #include <boost/asio/detail/pop_options.hpp> 0825 0826 #endif // BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |