1 // 2 // basic_deadline_timer.hpp 3 // ~~~~~~~~~~~~~~~~~~~~~~~~ 4 // 5 // Copyright (c) 2003-2021 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 11 #ifndef BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP 12 #define BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP 13 14 #if defined(_MSC_VER) && (_MSC_VER >= 1200) 15 # pragma once 16 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) 17 18 #include <boost/asio/detail/config.hpp> 19 20 #if defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) \ 21 || defined(GENERATING_DOCUMENTATION) 22 23 #include <cstddef> 24 #include <boost/asio/any_io_executor.hpp> 25 #include <boost/asio/detail/deadline_timer_service.hpp> 26 #include <boost/asio/detail/handler_type_requirements.hpp> 27 #include <boost/asio/detail/io_object_impl.hpp> 28 #include <boost/asio/detail/non_const_lvalue.hpp> 29 #include <boost/asio/detail/throw_error.hpp> 30 #include <boost/asio/error.hpp> 31 #include <boost/asio/execution_context.hpp> 32 #include <boost/asio/time_traits.hpp> 33 34 #include <boost/asio/detail/push_options.hpp> 35 36 namespace boost { 37 namespace asio { 38 39 /// Provides waitable timer functionality. 40 /** 41 * The basic_deadline_timer class template provides the ability to perform a 42 * blocking or asynchronous wait for a timer to expire. 43 * 44 * A deadline timer is always in one of two states: "expired" or "not expired". 45 * If the wait() or async_wait() function is called on an expired timer, the 46 * wait operation will complete immediately. 47 * 48 * Most applications will use the boost::asio::deadline_timer typedef. 49 * 50 * @par Thread Safety 51 * @e Distinct @e objects: Safe.@n 52 * @e Shared @e objects: Unsafe. 53 * 54 * @par Examples 55 * Performing a blocking wait: 56 * @code 57 * // Construct a timer without setting an expiry time. 58 * boost::asio::deadline_timer timer(my_context); 59 * 60 * // Set an expiry time relative to now. 61 * timer.expires_from_now(boost::posix_time::seconds(5)); 62 * 63 * // Wait for the timer to expire. 64 * timer.wait(); 65 * @endcode 66 * 67 * @par 68 * Performing an asynchronous wait: 69 * @code 70 * void handler(const boost::system::error_code& error) 71 * { 72 * if (!error) 73 * { 74 * // Timer expired. 75 * } 76 * } 77 * 78 * ... 79 * 80 * // Construct a timer with an absolute expiry time. 81 * boost::asio::deadline_timer timer(my_context, 82 * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); 83 * 84 * // Start an asynchronous wait. 85 * timer.async_wait(handler); 86 * @endcode 87 * 88 * @par Changing an active deadline_timer's expiry time 89 * 90 * Changing the expiry time of a timer while there are pending asynchronous 91 * waits causes those wait operations to be cancelled. To ensure that the action 92 * associated with the timer is performed only once, use something like this: 93 * used: 94 * 95 * @code 96 * void on_some_event() 97 * { 98 * if (my_timer.expires_from_now(seconds(5)) > 0) 99 * { 100 * // We managed to cancel the timer. Start new asynchronous wait. 101 * my_timer.async_wait(on_timeout); 102 * } 103 * else 104 * { 105 * // Too late, timer has already expired! 106 * } 107 * } 108 * 109 * void on_timeout(const boost::system::error_code& e) 110 * { 111 * if (e != boost::asio::error::operation_aborted) 112 * { 113 * // Timer was not cancelled, take necessary action. 114 * } 115 * } 116 * @endcode 117 * 118 * @li The boost::asio::basic_deadline_timer::expires_from_now() function 119 * cancels any pending asynchronous waits, and returns the number of 120 * asynchronous waits that were cancelled. If it returns 0 then you were too 121 * late and the wait handler has already been executed, or will soon be 122 * executed. If it returns 1 then the wait handler was successfully cancelled. 123 * 124 * @li If a wait handler is cancelled, the boost::system::error_code passed to 125 * it contains the value boost::asio::error::operation_aborted. 126 */ 127 template <typename Time, 128 typename TimeTraits = boost::asio::time_traits<Time>, 129 typename Executor = any_io_executor> 130 class basic_deadline_timer 131 { 132 public: 133 /// The type of the executor associated with the object. 134 typedef Executor executor_type; 135 136 /// Rebinds the timer type to another executor. 137 template <typename Executor1> 138 struct rebind_executor 139 { 140 /// The timer type when rebound to the specified executor. 141 typedef basic_deadline_timer<Time, TimeTraits, Executor1> other; 142 }; 143 144 /// The time traits type. 145 typedef TimeTraits traits_type; 146 147 /// The time type. 148 typedef typename traits_type::time_type time_type; 149 150 /// The duration type. 151 typedef typename traits_type::duration_type duration_type; 152 153 /// Constructor. 154 /** 155 * This constructor creates a timer without setting an expiry time. The 156 * expires_at() or expires_from_now() functions must be called to set an 157 * expiry time before the timer can be waited on. 158 * 159 * @param ex The I/O executor that the timer will use, by default, to 160 * dispatch handlers for any asynchronous operations performed on the timer. 161 */ basic_deadline_timer(const executor_type & ex)162 explicit basic_deadline_timer(const executor_type& ex) 163 : impl_(0, ex) 164 { 165 } 166 167 /// Constructor. 168 /** 169 * This constructor creates a timer without setting an expiry time. The 170 * expires_at() or expires_from_now() functions must be called to set an 171 * expiry time before the timer can be waited on. 172 * 173 * @param context An execution context which provides the I/O executor that 174 * the timer will use, by default, to dispatch handlers for any asynchronous 175 * operations performed on the timer. 176 */ 177 template <typename ExecutionContext> basic_deadline_timer(ExecutionContext & context,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)178 explicit basic_deadline_timer(ExecutionContext& context, 179 typename constraint< 180 is_convertible<ExecutionContext&, execution_context&>::value 181 >::type = 0) 182 : impl_(0, 0, context) 183 { 184 } 185 186 /// Constructor to set a particular expiry time as an absolute time. 187 /** 188 * This constructor creates a timer and sets the expiry time. 189 * 190 * @param ex The I/O executor that the timer will use, by default, to 191 * dispatch handlers for any asynchronous operations performed on the timer. 192 * 193 * @param expiry_time The expiry time to be used for the timer, expressed 194 * as an absolute time. 195 */ basic_deadline_timer(const executor_type & ex,const time_type & expiry_time)196 basic_deadline_timer(const executor_type& ex, const time_type& expiry_time) 197 : impl_(0, ex) 198 { 199 boost::system::error_code ec; 200 impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); 201 boost::asio::detail::throw_error(ec, "expires_at"); 202 } 203 204 /// Constructor to set a particular expiry time as an absolute time. 205 /** 206 * This constructor creates a timer and sets the expiry time. 207 * 208 * @param context An execution context which provides the I/O executor that 209 * the timer will use, by default, to dispatch handlers for any asynchronous 210 * operations performed on the timer. 211 * 212 * @param expiry_time The expiry time to be used for the timer, expressed 213 * as an absolute time. 214 */ 215 template <typename ExecutionContext> basic_deadline_timer(ExecutionContext & context,const time_type & expiry_time,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)216 basic_deadline_timer(ExecutionContext& context, const time_type& expiry_time, 217 typename constraint< 218 is_convertible<ExecutionContext&, execution_context&>::value 219 >::type = 0) 220 : impl_(0, 0, context) 221 { 222 boost::system::error_code ec; 223 impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); 224 boost::asio::detail::throw_error(ec, "expires_at"); 225 } 226 227 /// Constructor to set a particular expiry time relative to now. 228 /** 229 * This constructor creates a timer and sets the expiry time. 230 * 231 * @param ex The I/O executor that the timer will use, by default, to 232 * dispatch handlers for any asynchronous operations performed on the timer. 233 * 234 * @param expiry_time The expiry time to be used for the timer, relative to 235 * now. 236 */ basic_deadline_timer(const executor_type & ex,const duration_type & expiry_time)237 basic_deadline_timer(const executor_type& ex, 238 const duration_type& expiry_time) 239 : impl_(0, ex) 240 { 241 boost::system::error_code ec; 242 impl_.get_service().expires_from_now( 243 impl_.get_implementation(), expiry_time, ec); 244 boost::asio::detail::throw_error(ec, "expires_from_now"); 245 } 246 247 /// Constructor to set a particular expiry time relative to now. 248 /** 249 * This constructor creates a timer and sets the expiry time. 250 * 251 * @param context An execution context which provides the I/O executor that 252 * the timer will use, by default, to dispatch handlers for any asynchronous 253 * operations performed on the timer. 254 * 255 * @param expiry_time The expiry time to be used for the timer, relative to 256 * now. 257 */ 258 template <typename ExecutionContext> basic_deadline_timer(ExecutionContext & context,const duration_type & expiry_time,typename constraint<is_convertible<ExecutionContext &,execution_context &>::value>::type=0)259 basic_deadline_timer(ExecutionContext& context, 260 const duration_type& expiry_time, 261 typename constraint< 262 is_convertible<ExecutionContext&, execution_context&>::value 263 >::type = 0) 264 : impl_(0, 0, context) 265 { 266 boost::system::error_code ec; 267 impl_.get_service().expires_from_now( 268 impl_.get_implementation(), expiry_time, ec); 269 boost::asio::detail::throw_error(ec, "expires_from_now"); 270 } 271 272 #if defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 273 /// Move-construct a basic_deadline_timer from another. 274 /** 275 * This constructor moves a timer from one object to another. 276 * 277 * @param other The other basic_deadline_timer object from which the move will 278 * occur. 279 * 280 * @note Following the move, the moved-from object is in the same state as if 281 * constructed using the @c basic_deadline_timer(const executor_type&) 282 * constructor. 283 */ basic_deadline_timer(basic_deadline_timer && other)284 basic_deadline_timer(basic_deadline_timer&& other) 285 : impl_(std::move(other.impl_)) 286 { 287 } 288 289 /// Move-assign a basic_deadline_timer from another. 290 /** 291 * This assignment operator moves a timer from one object to another. Cancels 292 * any outstanding asynchronous operations associated with the target object. 293 * 294 * @param other The other basic_deadline_timer object from which the move will 295 * occur. 296 * 297 * @note Following the move, the moved-from object is in the same state as if 298 * constructed using the @c basic_deadline_timer(const executor_type&) 299 * constructor. 300 */ operator =(basic_deadline_timer && other)301 basic_deadline_timer& operator=(basic_deadline_timer&& other) 302 { 303 impl_ = std::move(other.impl_); 304 return *this; 305 } 306 #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) 307 308 /// Destroys the timer. 309 /** 310 * This function destroys the timer, cancelling any outstanding asynchronous 311 * wait operations associated with the timer as if by calling @c cancel. 312 */ ~basic_deadline_timer()313 ~basic_deadline_timer() 314 { 315 } 316 317 /// Get the executor associated with the object. get_executor()318 executor_type get_executor() BOOST_ASIO_NOEXCEPT 319 { 320 return impl_.get_executor(); 321 } 322 323 /// Cancel any asynchronous operations that are waiting on the timer. 324 /** 325 * This function forces the completion of any pending asynchronous wait 326 * operations against the timer. The handler for each cancelled operation will 327 * be invoked with the boost::asio::error::operation_aborted error code. 328 * 329 * Cancelling the timer does not change the expiry time. 330 * 331 * @return The number of asynchronous operations that were cancelled. 332 * 333 * @throws boost::system::system_error Thrown on failure. 334 * 335 * @note If the timer has already expired when cancel() is called, then the 336 * handlers for asynchronous wait operations will: 337 * 338 * @li have already been invoked; or 339 * 340 * @li have been queued for invocation in the near future. 341 * 342 * These handlers can no longer be cancelled, and therefore are passed an 343 * error code that indicates the successful completion of the wait operation. 344 */ cancel()345 std::size_t cancel() 346 { 347 boost::system::error_code ec; 348 std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec); 349 boost::asio::detail::throw_error(ec, "cancel"); 350 return s; 351 } 352 353 /// Cancel any asynchronous operations that are waiting on the timer. 354 /** 355 * This function forces the completion of any pending asynchronous wait 356 * operations against the timer. The handler for each cancelled operation will 357 * be invoked with the boost::asio::error::operation_aborted error code. 358 * 359 * Cancelling the timer does not change the expiry time. 360 * 361 * @param ec Set to indicate what error occurred, if any. 362 * 363 * @return The number of asynchronous operations that were cancelled. 364 * 365 * @note If the timer has already expired when cancel() is called, then the 366 * handlers for asynchronous wait operations will: 367 * 368 * @li have already been invoked; or 369 * 370 * @li have been queued for invocation in the near future. 371 * 372 * These handlers can no longer be cancelled, and therefore are passed an 373 * error code that indicates the successful completion of the wait operation. 374 */ cancel(boost::system::error_code & ec)375 std::size_t cancel(boost::system::error_code& ec) 376 { 377 return impl_.get_service().cancel(impl_.get_implementation(), ec); 378 } 379 380 /// Cancels one asynchronous operation that is waiting on the timer. 381 /** 382 * This function forces the completion of one pending asynchronous wait 383 * operation against the timer. Handlers are cancelled in FIFO order. The 384 * handler for the cancelled operation will be invoked with the 385 * boost::asio::error::operation_aborted error code. 386 * 387 * Cancelling the timer does not change the expiry time. 388 * 389 * @return The number of asynchronous operations that were cancelled. That is, 390 * either 0 or 1. 391 * 392 * @throws boost::system::system_error Thrown on failure. 393 * 394 * @note If the timer has already expired when cancel_one() is called, then 395 * the handlers for asynchronous wait operations will: 396 * 397 * @li have already been invoked; or 398 * 399 * @li have been queued for invocation in the near future. 400 * 401 * These handlers can no longer be cancelled, and therefore are passed an 402 * error code that indicates the successful completion of the wait operation. 403 */ cancel_one()404 std::size_t cancel_one() 405 { 406 boost::system::error_code ec; 407 std::size_t s = impl_.get_service().cancel_one( 408 impl_.get_implementation(), ec); 409 boost::asio::detail::throw_error(ec, "cancel_one"); 410 return s; 411 } 412 413 /// Cancels one asynchronous operation that is waiting on the timer. 414 /** 415 * This function forces the completion of one pending asynchronous wait 416 * operation against the timer. Handlers are cancelled in FIFO order. The 417 * handler for the cancelled operation will be invoked with the 418 * boost::asio::error::operation_aborted error code. 419 * 420 * Cancelling the timer does not change the expiry time. 421 * 422 * @param ec Set to indicate what error occurred, if any. 423 * 424 * @return The number of asynchronous operations that were cancelled. That is, 425 * either 0 or 1. 426 * 427 * @note If the timer has already expired when cancel_one() is called, then 428 * the handlers for asynchronous wait operations will: 429 * 430 * @li have already been invoked; or 431 * 432 * @li have been queued for invocation in the near future. 433 * 434 * These handlers can no longer be cancelled, and therefore are passed an 435 * error code that indicates the successful completion of the wait operation. 436 */ cancel_one(boost::system::error_code & ec)437 std::size_t cancel_one(boost::system::error_code& ec) 438 { 439 return impl_.get_service().cancel_one(impl_.get_implementation(), ec); 440 } 441 442 /// Get the timer's expiry time as an absolute time. 443 /** 444 * This function may be used to obtain the timer's current expiry time. 445 * Whether the timer has expired or not does not affect this value. 446 */ expires_at() const447 time_type expires_at() const 448 { 449 return impl_.get_service().expires_at(impl_.get_implementation()); 450 } 451 452 /// Set the timer's expiry time as an absolute time. 453 /** 454 * This function sets the expiry time. Any pending asynchronous wait 455 * operations will be cancelled. The handler for each cancelled operation will 456 * be invoked with the boost::asio::error::operation_aborted error code. 457 * 458 * @param expiry_time The expiry time to be used for the timer. 459 * 460 * @return The number of asynchronous operations that were cancelled. 461 * 462 * @throws boost::system::system_error Thrown on failure. 463 * 464 * @note If the timer has already expired when expires_at() is called, then 465 * the handlers for asynchronous wait operations will: 466 * 467 * @li have already been invoked; or 468 * 469 * @li have been queued for invocation in the near future. 470 * 471 * These handlers can no longer be cancelled, and therefore are passed an 472 * error code that indicates the successful completion of the wait operation. 473 */ expires_at(const time_type & expiry_time)474 std::size_t expires_at(const time_type& expiry_time) 475 { 476 boost::system::error_code ec; 477 std::size_t s = impl_.get_service().expires_at( 478 impl_.get_implementation(), expiry_time, ec); 479 boost::asio::detail::throw_error(ec, "expires_at"); 480 return s; 481 } 482 483 /// Set the timer's expiry time as an absolute time. 484 /** 485 * This function sets the expiry time. Any pending asynchronous wait 486 * operations will be cancelled. The handler for each cancelled operation will 487 * be invoked with the boost::asio::error::operation_aborted error code. 488 * 489 * @param expiry_time The expiry time to be used for the timer. 490 * 491 * @param ec Set to indicate what error occurred, if any. 492 * 493 * @return The number of asynchronous operations that were cancelled. 494 * 495 * @note If the timer has already expired when expires_at() is called, then 496 * the handlers for asynchronous wait operations will: 497 * 498 * @li have already been invoked; or 499 * 500 * @li have been queued for invocation in the near future. 501 * 502 * These handlers can no longer be cancelled, and therefore are passed an 503 * error code that indicates the successful completion of the wait operation. 504 */ expires_at(const time_type & expiry_time,boost::system::error_code & ec)505 std::size_t expires_at(const time_type& expiry_time, 506 boost::system::error_code& ec) 507 { 508 return impl_.get_service().expires_at( 509 impl_.get_implementation(), expiry_time, ec); 510 } 511 512 /// Get the timer's expiry time relative to now. 513 /** 514 * This function may be used to obtain the timer's current expiry time. 515 * Whether the timer has expired or not does not affect this value. 516 */ expires_from_now() const517 duration_type expires_from_now() const 518 { 519 return impl_.get_service().expires_from_now(impl_.get_implementation()); 520 } 521 522 /// Set the timer's expiry time relative to now. 523 /** 524 * This function sets the expiry time. Any pending asynchronous wait 525 * operations will be cancelled. The handler for each cancelled operation will 526 * be invoked with the boost::asio::error::operation_aborted error code. 527 * 528 * @param expiry_time The expiry time to be used for the timer. 529 * 530 * @return The number of asynchronous operations that were cancelled. 531 * 532 * @throws boost::system::system_error Thrown on failure. 533 * 534 * @note If the timer has already expired when expires_from_now() is called, 535 * then the handlers for asynchronous wait operations will: 536 * 537 * @li have already been invoked; or 538 * 539 * @li have been queued for invocation in the near future. 540 * 541 * These handlers can no longer be cancelled, and therefore are passed an 542 * error code that indicates the successful completion of the wait operation. 543 */ expires_from_now(const duration_type & expiry_time)544 std::size_t expires_from_now(const duration_type& expiry_time) 545 { 546 boost::system::error_code ec; 547 std::size_t s = impl_.get_service().expires_from_now( 548 impl_.get_implementation(), expiry_time, ec); 549 boost::asio::detail::throw_error(ec, "expires_from_now"); 550 return s; 551 } 552 553 /// Set the timer's expiry time relative to now. 554 /** 555 * This function sets the expiry time. Any pending asynchronous wait 556 * operations will be cancelled. The handler for each cancelled operation will 557 * be invoked with the boost::asio::error::operation_aborted error code. 558 * 559 * @param expiry_time The expiry time to be used for the timer. 560 * 561 * @param ec Set to indicate what error occurred, if any. 562 * 563 * @return The number of asynchronous operations that were cancelled. 564 * 565 * @note If the timer has already expired when expires_from_now() is called, 566 * then the handlers for asynchronous wait operations will: 567 * 568 * @li have already been invoked; or 569 * 570 * @li have been queued for invocation in the near future. 571 * 572 * These handlers can no longer be cancelled, and therefore are passed an 573 * error code that indicates the successful completion of the wait operation. 574 */ expires_from_now(const duration_type & expiry_time,boost::system::error_code & ec)575 std::size_t expires_from_now(const duration_type& expiry_time, 576 boost::system::error_code& ec) 577 { 578 return impl_.get_service().expires_from_now( 579 impl_.get_implementation(), expiry_time, ec); 580 } 581 582 /// Perform a blocking wait on the timer. 583 /** 584 * This function is used to wait for the timer to expire. This function 585 * blocks and does not return until the timer has expired. 586 * 587 * @throws boost::system::system_error Thrown on failure. 588 */ wait()589 void wait() 590 { 591 boost::system::error_code ec; 592 impl_.get_service().wait(impl_.get_implementation(), ec); 593 boost::asio::detail::throw_error(ec, "wait"); 594 } 595 596 /// Perform a blocking wait on the timer. 597 /** 598 * This function is used to wait for the timer to expire. This function 599 * blocks and does not return until the timer has expired. 600 * 601 * @param ec Set to indicate what error occurred, if any. 602 */ wait(boost::system::error_code & ec)603 void wait(boost::system::error_code& ec) 604 { 605 impl_.get_service().wait(impl_.get_implementation(), ec); 606 } 607 608 /// Start an asynchronous wait on the timer. 609 /** 610 * This function may be used to initiate an asynchronous wait against the 611 * timer. It always returns immediately. 612 * 613 * For each call to async_wait(), the supplied handler will be called exactly 614 * once. The handler will be called when: 615 * 616 * @li The timer has expired. 617 * 618 * @li The timer was cancelled, in which case the handler is passed the error 619 * code boost::asio::error::operation_aborted. 620 * 621 * @param handler The handler to be called when the timer expires. Copies 622 * will be made of the handler as required. The function signature of the 623 * handler must be: 624 * @code void handler( 625 * const boost::system::error_code& error // Result of operation. 626 * ); @endcode 627 * Regardless of whether the asynchronous operation completes immediately or 628 * not, the handler will not be invoked from within this function. On 629 * immediate completion, invocation of the handler will be performed in a 630 * manner equivalent to using boost::asio::post(). 631 */ 632 template < 633 BOOST_ASIO_COMPLETION_TOKEN_FOR(void (boost::system::error_code)) 634 WaitHandler BOOST_ASIO_DEFAULT_COMPLETION_TOKEN_TYPE(executor_type)> BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler,void (boost::system::error_code))635 BOOST_ASIO_INITFN_AUTO_RESULT_TYPE(WaitHandler, 636 void (boost::system::error_code)) 637 async_wait( 638 BOOST_ASIO_MOVE_ARG(WaitHandler) handler 639 BOOST_ASIO_DEFAULT_COMPLETION_TOKEN(executor_type)) 640 { 641 return async_initiate<WaitHandler, void (boost::system::error_code)>( 642 initiate_async_wait(this), handler); 643 } 644 645 private: 646 // Disallow copying and assignment. 647 basic_deadline_timer(const basic_deadline_timer&) BOOST_ASIO_DELETED; 648 basic_deadline_timer& operator=( 649 const basic_deadline_timer&) BOOST_ASIO_DELETED; 650 651 class initiate_async_wait 652 { 653 public: 654 typedef Executor executor_type; 655 initiate_async_wait(basic_deadline_timer * self)656 explicit initiate_async_wait(basic_deadline_timer* self) 657 : self_(self) 658 { 659 } 660 get_executor() const661 executor_type get_executor() const BOOST_ASIO_NOEXCEPT 662 { 663 return self_->get_executor(); 664 } 665 666 template <typename WaitHandler> operator ()(BOOST_ASIO_MOVE_ARG (WaitHandler)handler) const667 void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) const 668 { 669 // If you get an error on the following line it means that your handler 670 // does not meet the documented type requirements for a WaitHandler. 671 BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; 672 673 detail::non_const_lvalue<WaitHandler> handler2(handler); 674 self_->impl_.get_service().async_wait( 675 self_->impl_.get_implementation(), 676 handler2.value, self_->impl_.get_executor()); 677 } 678 679 private: 680 basic_deadline_timer* self_; 681 }; 682 683 detail::io_object_impl< 684 detail::deadline_timer_service<TimeTraits>, Executor> impl_; 685 }; 686 687 } // namespace asio 688 } // namespace boost 689 690 #include <boost/asio/detail/pop_options.hpp> 691 692 #endif // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) 693 // || defined(GENERATING_DOCUMENTATION) 694 695 #endif // BOOST_ASIO_BASIC_DEADLINE_TIMER_HPP 696