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