diff options
Diffstat (limited to 'boost/asio/basic_deadline_timer.hpp')
-rw-r--r-- | boost/asio/basic_deadline_timer.hpp | 258 |
1 files changed, 148 insertions, 110 deletions
diff --git a/boost/asio/basic_deadline_timer.hpp b/boost/asio/basic_deadline_timer.hpp index 56a265bfbc..75f0fcd8bc 100644 --- a/boost/asio/basic_deadline_timer.hpp +++ b/boost/asio/basic_deadline_timer.hpp @@ -2,7 +2,7 @@ // basic_deadline_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) @@ -21,19 +21,16 @@ || defined(GENERATING_DOCUMENTATION) #include <cstddef> -#include <boost/asio/basic_io_object.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/execution_context.hpp> +#include <boost/asio/executor.hpp> #include <boost/asio/time_traits.hpp> -#if defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# include <boost/asio/deadline_timer_service.hpp> -#else // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) -# include <boost/asio/detail/deadline_timer_service.hpp> -# define BOOST_ASIO_SVC_T detail::deadline_timer_service<TimeTraits> -#endif // defined(BOOST_ASIO_ENABLE_OLD_SERVICES) - #include <boost/asio/detail/push_options.hpp> namespace boost { @@ -58,7 +55,7 @@ namespace asio { * Performing a blocking wait: * @code * // Construct a timer without setting an expiry time. - * boost::asio::deadline_timer timer(io_context); + * boost::asio::deadline_timer timer(my_context); * * // Set an expiry time relative to now. * timer.expires_from_now(boost::posix_time::seconds(5)); @@ -81,7 +78,7 @@ namespace asio { * ... * * // Construct a timer with an absolute expiry time. - * boost::asio::deadline_timer timer(io_context, + * boost::asio::deadline_timer timer(my_context, * boost::posix_time::time_from_string("2005-12-07 23:59:59.000")); * * // Start an asynchronous wait. @@ -128,14 +125,13 @@ namespace asio { * it contains the value boost::asio::error::operation_aborted. */ template <typename Time, - typename TimeTraits = boost::asio::time_traits<Time> - BOOST_ASIO_SVC_TPARAM_DEF2(= deadline_timer_service<Time, TimeTraits>)> + typename TimeTraits = boost::asio::time_traits<Time>, + typename Executor = executor> class basic_deadline_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 time traits type. typedef TimeTraits traits_type; @@ -152,11 +148,30 @@ public: * expires_at() or expires_from_now() 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_deadline_timer(const executor_type& ex) + : impl_(ex) + { + } + + /// Constructor. + /** + * This constructor creates a timer without setting an expiry time. The + * expires_at() or expires_from_now() 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_deadline_timer(boost::asio::io_context& io_context) - : basic_io_object<BOOST_ASIO_SVC_T>(io_context) + template <typename ExecutionContext> + explicit basic_deadline_timer(ExecutionContext& context, + typename enable_if< + is_convertible<ExecutionContext&, execution_context&>::value + >::type* = 0) + : impl_(context) { } @@ -164,18 +179,40 @@ 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 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_deadline_timer(boost::asio::io_context& io_context, - const time_type& expiry_time) - : basic_io_object<BOOST_ASIO_SVC_T>(io_context) + basic_deadline_timer(const executor_type& ex, const time_type& 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> + basic_deadline_timer(ExecutionContext& context, const time_type& 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"); } @@ -183,19 +220,44 @@ 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 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_deadline_timer(boost::asio::io_context& io_context, + basic_deadline_timer(const executor_type& ex, const duration_type& expiry_time) - : basic_io_object<BOOST_ASIO_SVC_T>(io_context) + : impl_(ex) { boost::system::error_code ec; - this->get_service().expires_from_now( - this->get_implementation(), expiry_time, ec); + impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); + boost::asio::detail::throw_error(ec, "expires_from_now"); + } + + /// Constructor to set a particular expiry time relative to now. + /** + * 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, relative to + * now. + */ + template <typename ExecutionContext> + basic_deadline_timer(ExecutionContext& context, + const duration_type& expiry_time, + typename enable_if< + is_convertible<ExecutionContext&, execution_context&>::value + >::type* = 0) + : impl_(context) + { + boost::system::error_code ec; + impl_.get_service().expires_from_now( + impl_.get_implementation(), expiry_time, ec); boost::asio::detail::throw_error(ec, "expires_from_now"); } @@ -208,10 +270,11 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_deadline_timer(io_context&) constructor. + * constructed using the @c basic_deadline_timer(const executor_type&) + * constructor. */ basic_deadline_timer(basic_deadline_timer&& other) - : basic_io_object<BOOST_ASIO_SVC_T>(std::move(other)) + : impl_(std::move(other.impl_)) { } @@ -224,11 +287,12 @@ public: * occur. * * @note Following the move, the moved-from object is in the same state as if - * constructed using the @c basic_deadline_timer(io_context&) constructor. + * constructed using the @c basic_deadline_timer(const executor_type&) + * constructor. */ basic_deadline_timer& operator=(basic_deadline_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) @@ -242,45 +306,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. /** @@ -307,7 +337,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; } @@ -336,7 +366,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); } /// Cancels one asynchronous operation that is waiting on the timer. @@ -366,8 +396,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; } @@ -398,7 +428,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); } /// Get the timer's expiry time as an absolute time. @@ -408,7 +438,7 @@ public: */ time_type expires_at() const { - return this->get_service().expires_at(this->get_implementation()); + return impl_.get_service().expires_at(impl_.get_implementation()); } /// Set the timer's expiry time as an absolute time. @@ -436,8 +466,8 @@ public: std::size_t expires_at(const time_type& 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; } @@ -467,8 +497,8 @@ public: std::size_t expires_at(const time_type& 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); } /// Get the timer's expiry time relative to now. @@ -478,7 +508,7 @@ public: */ duration_type expires_from_now() const { - return this->get_service().expires_from_now(this->get_implementation()); + return impl_.get_service().expires_from_now(impl_.get_implementation()); } /// Set the timer's expiry time relative to now. @@ -506,8 +536,8 @@ public: std::size_t expires_from_now(const duration_type& 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; } @@ -537,8 +567,8 @@ public: std::size_t expires_from_now(const duration_type& 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); } /// Perform a blocking wait on the timer. @@ -551,7 +581,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"); } @@ -564,7 +594,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. @@ -587,32 +617,44 @@ 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: + // Disallow copying and assignment. + basic_deadline_timer(const basic_deadline_timer&) BOOST_ASIO_DELETED; + basic_deadline_timer& operator=( + const basic_deadline_timer&) BOOST_ASIO_DELETED; + + struct initiate_async_wait + { + template <typename WaitHandler> + void operator()(BOOST_ASIO_MOVE_ARG(WaitHandler) handler, + basic_deadline_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<TimeTraits>, Executor> impl_; }; } // namespace asio @@ -620,10 +662,6 @@ public: #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 // defined(BOOST_ASIO_HAS_BOOST_DATE_TIME) // || defined(GENERATING_DOCUMENTATION) |