diff options
Diffstat (limited to 'boost/asio/basic_waitable_timer.hpp')
-rw-r--r-- | boost/asio/basic_waitable_timer.hpp | 267 |
1 files changed, 149 insertions, 118 deletions
diff --git a/boost/asio/basic_waitable_timer.hpp b/boost/asio/basic_waitable_timer.hpp index 6dc4bded98..45373f7caf 100644 --- a/boost/asio/basic_waitable_timer.hpp +++ b/boost/asio/basic_waitable_timer.hpp @@ -2,7 +2,7 @@ // basic_waitable_timer.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~ // -// Copyright (c) 2003-2018 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2003-2019 Christopher M. Kohlhoff (chris at kohlhoff dot com) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) @@ -17,26 +17,20 @@ #include <boost/asio/detail/config.hpp> #include <cstddef> -#include <boost/asio/basic_io_object.hpp> +#include <boost/asio/detail/chrono_time_traits.hpp> +#include <boost/asio/detail/deadline_timer_service.hpp> #include <boost/asio/detail/handler_type_requirements.hpp> +#include <boost/asio/detail/io_object_impl.hpp> +#include <boost/asio/detail/non_const_lvalue.hpp> #include <boost/asio/detail/throw_error.hpp> #include <boost/asio/error.hpp> +#include <boost/asio/executor.hpp> #include <boost/asio/wait_traits.hpp> #if defined(BOOST_ASIO_HAS_MOVE) # include <utility> #endif // defined(BOOST_ASIO_HAS_MOVE) -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# include <boost/asio/waitable_timer_service.hpp> -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# include <boost/asio/detail/chrono_time_traits.hpp> -# include <boost/asio/detail/deadline_timer_service.hpp> -# define BOOST_ASIO_SVC_T \ - detail::deadline_timer_service< \ - detail::chrono_time_traits<Clock, WaitTraits> > -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - #include <boost/asio/detail/push_options.hpp> namespace boost { @@ -47,8 +41,8 @@ namespace asio { // Forward declaration with defaulted arguments. template <typename Clock, - typename WaitTraits = boost::asio::wait_traits<Clock> - BOOST_ASIO_SVC_TPARAM_DEF2(= waitable_timer_service<Clock, WaitTraits>)> + typename WaitTraits = boost::asio::wait_traits<Clock>, + typename Executor = executor> class basic_waitable_timer; #endif // !defined(BOOST_ASIO_BASIC_WAITABLE_TIMER_FWD_DECL) @@ -76,7 +70,7 @@ class basic_waitable_timer; * Performing a blocking wait (C++11): * @code * // Construct a timer without setting an expiry time. - * boost::asio::steady_timer timer(io_context); + * boost::asio::steady_timer timer(my_context); * * // Set an expiry time relative to now. * timer.expires_after(std::chrono::seconds(5)); @@ -99,7 +93,7 @@ class basic_waitable_timer; * ... * * // Construct a timer with an absolute expiry time. - * boost::asio::steady_timer timer(io_context, + * boost::asio::steady_timer timer(my_context, * std::chrono::steady_clock::now() + std::chrono::seconds(60)); * * // Start an asynchronous wait. @@ -145,13 +139,12 @@ class basic_waitable_timer; * @li If a wait handler is cancelled, the boost::system::error_code passed to * it contains the value boost::asio::error::operation_aborted. */ -template <typename Clock, typename WaitTraits BOOST_ASIO_SVC_TPARAM> +template <typename Clock, typename WaitTraits, typename Executor> class basic_waitable_timer - : BOOST_ASIO_SVC_ACCESS basic_io_object<BOOST_ASIO_SVC_T> { public: /// The type of the executor associated with the object. - typedef io_context::executor_type executor_type; + typedef Executor executor_type; /// The clock type. typedef Clock clock_type; @@ -171,11 +164,30 @@ public: * expires_at() or expires_after() functions must be called to set an expiry * time before the timer can be waited on. * - * @param io_context The io_context object that the timer will use to dispatch - * handlers for any asynchronous operations performed on the timer. + * @param ex The I/O executor that the timer will use, by default, to + * dispatch handlers for any asynchronous operations performed on the timer. + */ + explicit basic_waitable_timer(const executor_type& ex) + : impl_(ex) + { + } + + /// Constructor. + /** + * This constructor creates a timer without setting an expiry time. The + * expires_at() or expires_after() functions must be called to set an expiry + * time before the timer can be waited on. + * + * @param context An execution context which provides the I/O executor that + * the timer will use, by default, to dispatch handlers for any asynchronous + * operations performed on the timer. */ - explicit basic_waitable_timer(boost::asio::io_context& io_context) - : basic_io_object<BOOST_ASIO_SVC_T>(io_context) + template <typename ExecutionContext> + explicit basic_waitable_timer(ExecutionContext& context, + typename enable_if< + is_convertible<ExecutionContext&, execution_context&>::value + >::type* = 0) + : impl_(context) { } @@ -183,38 +195,85 @@ public: /** * This constructor creates a timer and sets the expiry time. * - * @param io_context The io_context object that the timer will use to dispatch - * handlers for any asynchronous operations performed on the timer. + * @param ex The I/O executor object that the timer will use, by default, to + * dispatch handlers for any asynchronous operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, expressed * as an absolute time. */ - basic_waitable_timer(boost::asio::io_context& io_context, - const time_point& expiry_time) - : basic_io_object<BOOST_ASIO_SVC_T>(io_context) + basic_waitable_timer(const executor_type& ex, const time_point& expiry_time) + : impl_(ex) { boost::system::error_code ec; - this->get_service().expires_at(this->get_implementation(), expiry_time, ec); + impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_at"); } + /// Constructor to set a particular expiry time as an absolute time. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param context An execution context which provides the I/O executor that + * the timer will use, by default, to dispatch handlers for any asynchronous + * operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, expressed + * as an absolute time. + */ + template <typename ExecutionContext> + explicit basic_waitable_timer(ExecutionContext& context, + const time_point& expiry_time, + typename enable_if< + is_convertible<ExecutionContext&, execution_context&>::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().expires_at(impl_.get_implementation(), expiry_time, ec); + boost::asio::detail::throw_error(ec, "expires_at"); + } + + /// Constructor to set a particular expiry time relative to now. + /** + * This constructor creates a timer and sets the expiry time. + * + * @param ex The I/O executor that the timer will use, by default, to + * dispatch handlers for any asynchronous operations performed on the timer. + * + * @param expiry_time The expiry time to be used for the timer, relative to + * now. + */ + basic_waitable_timer(const executor_type& ex, const duration& expiry_time) + : impl_(ex) + { + boost::system::error_code ec; + impl_.get_service().expires_after( + impl_.get_implementation(), expiry_time, ec); + boost::asio::detail::throw_error(ec, "expires_after"); + } + /// Constructor to set a particular expiry time relative to now. /** * This constructor creates a timer and sets the expiry time. * - * @param io_context The io_context object that the timer will use to dispatch - * handlers for any asynchronous operations performed on the timer. + * @param context An execution context which provides the I/O executor that + * the timer will use, by default, to dispatch handlers for any asynchronous + * operations performed on the timer. * * @param expiry_time The expiry time to be used for the timer, relative to * now. */ - basic_waitable_timer(boost::asio::io_context& io_context, - const duration& expiry_time) - : basic_io_object<BOOST_ASIO_SVC_T>(io_context) + template <typename ExecutionContext> + explicit basic_waitable_timer(ExecutionContext& context, + const duration& expiry_time, + typename enable_if< + is_convertible<ExecutionContext&, execution_context&>::value + >::type* = 0) + : impl_(context) { boost::system::error_code ec; - this->get_service().expires_after( - this->get_implementation(), expiry_time, ec); + impl_.get_service().expires_after( + impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_after"); } @@ -227,10 +286,11 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_waitable_timer(io_context&) constructor. + * constructed using the @c basic_waitable_timer(const executor_type&) + * constructor. */ basic_waitable_timer(basic_waitable_timer&& other) - : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other)) + : impl_(std::move(other.impl_)) { } @@ -243,11 +303,12 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_waitable_timer(io_context&) constructor. + * constructed using the @c basic_waitable_timer(const executor_type&) + * constructor. */ basic_waitable_timer& operator=(basic_waitable_timer&& other) { - basic_io_object<BOOST_ASIO_SVC_T>::operator=(std::move(other)); + impl_ = std::move(other.impl_); return *this; } #endif // defined(BOOST_ASIO_HAS_MOVE) || defined(GENERATING_DOCUMENTATION) @@ -261,45 +322,11 @@ public: { } -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - // These functions are provided by basic_io_object<>. -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -#if !defined(BOOST_ASIO_NO_DEPRECATED) - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_context() - { - return basic_io_object<BOOST_ASIO_SVC_T>::get_io_context(); - } - - /// (Deprecated: Use get_executor().) Get the io_context associated with the - /// object. - /** - * This function may be used to obtain the io_context object that the I/O - * object uses to dispatch handlers for asynchronous operations. - * - * @return A reference to the io_context object that the I/O object will use - * to dispatch handlers. Ownership is not transferred to the caller. - */ - boost::asio::io_context& get_io_service() - { - return basic_io_object<BOOST_ASIO_SVC_T>::get_io_service(); - } -#endif // !defined(BOOST_ASIO_NO_DEPRECATED) - /// Get the executor associated with the object. executor_type get_executor() BOOST_ASIO_NOEXCEPT { - return basic_io_object<BOOST_ASIO_SVC_T>::get_executor(); + return impl_.get_executor(); } -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) /// Cancel any asynchronous operations that are waiting on the timer. /** @@ -326,7 +353,7 @@ public: std::size_t cancel() { boost::system::error_code ec; - std::size_t s = this->get_service().cancel(this->get_implementation(), ec); + std::size_t s = impl_.get_service().cancel(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "cancel"); return s; } @@ -357,7 +384,7 @@ public: */ std::size_t cancel(boost::system::error_code& ec) { - return this->get_service().cancel(this->get_implementation(), ec); + return impl_.get_service().cancel(impl_.get_implementation(), ec); } #endif // !defined(BOOST_ASIO_NO_DEPRECATED) @@ -388,8 +415,8 @@ public: std::size_t cancel_one() { boost::system::error_code ec; - std::size_t s = this->get_service().cancel_one( - this->get_implementation(), ec); + std::size_t s = impl_.get_service().cancel_one( + impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "cancel_one"); return s; } @@ -422,7 +449,7 @@ public: */ std::size_t cancel_one(boost::system::error_code& ec) { - return this->get_service().cancel_one(this->get_implementation(), ec); + return impl_.get_service().cancel_one(impl_.get_implementation(), ec); } /// (Deprecated: Use expiry().) Get the timer's expiry time as an absolute @@ -433,7 +460,7 @@ public: */ time_point expires_at() const { - return this->get_service().expires_at(this->get_implementation()); + return impl_.get_service().expires_at(impl_.get_implementation()); } #endif // !defined(BOOST_ASIO_NO_DEPRECATED) @@ -444,7 +471,7 @@ public: */ time_point expiry() const { - return this->get_service().expiry(this->get_implementation()); + return impl_.get_service().expiry(impl_.get_implementation()); } /// Set the timer's expiry time as an absolute time. @@ -472,8 +499,8 @@ public: std::size_t expires_at(const time_point& expiry_time) { boost::system::error_code ec; - std::size_t s = this->get_service().expires_at( - this->get_implementation(), expiry_time, ec); + std::size_t s = impl_.get_service().expires_at( + impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_at"); return s; } @@ -505,8 +532,8 @@ public: std::size_t expires_at(const time_point& expiry_time, boost::system::error_code& ec) { - return this->get_service().expires_at( - this->get_implementation(), expiry_time, ec); + return impl_.get_service().expires_at( + impl_.get_implementation(), expiry_time, ec); } #endif // !defined(BOOST_ASIO_NO_DEPRECATED) @@ -535,8 +562,8 @@ public: std::size_t expires_after(const duration& expiry_time) { boost::system::error_code ec; - std::size_t s = this->get_service().expires_after( - this->get_implementation(), expiry_time, ec); + std::size_t s = impl_.get_service().expires_after( + impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_after"); return s; } @@ -549,7 +576,7 @@ public: */ duration expires_from_now() const { - return this->get_service().expires_from_now(this->get_implementation()); + return impl_.get_service().expires_from_now(impl_.get_implementation()); } /// (Deprecated: Use expires_after().) Set the timer's expiry time relative @@ -578,8 +605,8 @@ public: std::size_t expires_from_now(const duration& expiry_time) { boost::system::error_code ec; - std::size_t s = this->get_service().expires_from_now( - this->get_implementation(), expiry_time, ec); + std::size_t s = impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_from_now"); return s; } @@ -610,8 +637,8 @@ public: std::size_t expires_from_now(const duration& expiry_time, boost::system::error_code& ec) { - return this->get_service().expires_from_now( - this->get_implementation(), expiry_time, ec); + return impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); } #endif // !defined(BOOST_ASIO_NO_DEPRECATED) @@ -625,7 +652,7 @@ public: void wait() { boost::system::error_code ec; - this->get_service().wait(this->get_implementation(), ec); + impl_.get_service().wait(impl_.get_implementation(), ec); boost::asio::detail::throw_error(ec, "wait"); } @@ -638,7 +665,7 @@ public: */ void wait(boost::system::error_code& ec) { - this->get_service().wait(this->get_implementation(), ec); + impl_.get_service().wait(impl_.get_implementation(), ec); } /// Start an asynchronous wait on the timer. @@ -661,31 +688,17 @@ public: * const boost::system::error_code& error // Result of operation. * ); @endcode * Regardless of whether the asynchronous operation completes immediately or - * not, the handler will not be invoked from within this function. Invocation - * of the handler will be performed in a manner equivalent to using - * boost::asio::io_context::post(). + * not, the handler will not be invoked from within this function. On + * immediate completion, invocation of the handler will be performed in a + * manner equivalent to using boost::asio::post(). */ template <typename WaitHandler> BOOST_ASIO_INITFN_RESULT_TYPE(WaitHandler, void (boost::system::error_code)) async_wait(BOOST_ASIO_MOVE_ARG(WaitHandler) handler) { - // If you get an error on the following line it means that your handler does - // not meet the documented type requirements for a WaitHandler. - BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; - -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - return this->get_service().async_wait(this->get_implementation(), - BOOST_ASIO_MOVE_CAST(WaitHandler)(handler)); -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - async_completion<WaitHandler, - void (boost::system::error_code)> init(handler); - - this->get_service().async_wait(this->get_implementation(), - init.completion_handler); - - return init.result.get(); -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) + return async_initiate<WaitHandler, void (boost::system::error_code)>( + initiate_async_wait(), handler, this); } private: @@ -693,6 +706,28 @@ private: basic_waitable_timer(const basic_waitable_timer&) BOOST_ASIO_DELETED; basic_waitable_timer& operator=( const basic_waitable_timer&) BOOST_ASIO_DELETED; + + struct initiate_async_wait + { + template <typename WaitHandler> + void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, + basic_waitable_timer* self) const + { + // If you get an error on the following line it means that your handler + // does not meet the documented type requirements for a WaitHandler. + BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check; + + detail::non_const_lvalue<WaitHandler> handler2(handler); + self->impl_.get_service().async_wait( + self->impl_.get_implementation(), handler2.value, + self->impl_.get_implementation_executor()); + } + }; + + detail::io_object_impl< + detail::deadline_timer_service< + detail::chrono_time_traits<Clock, WaitTraits> >, + executor_type > impl_; }; } // namespace asio @@ -700,8 +735,4 @@ private: #include <boost/asio/detail/pop_options.hpp> -#if !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# undef BOOST_ASIO_SVC_T -#endif // !defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - #endif // BOOST_ASIO_BASIC_WAITABLE_TIMER_HPP |