// // reactive_deadline_timer_service.hpp // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // // Copyright (c) 2003-2005 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) // #ifndef BOOST_ASIO_DETAIL_REACTIVE_DEADLINE_TIMER_SERVICE_HPP #define BOOST_ASIO_DETAIL_REACTIVE_DEADLINE_TIMER_SERVICE_HPP #if defined(_MSC_VER) && (_MSC_VER >= 1200) # pragma once #endif // defined(_MSC_VER) && (_MSC_VER >= 1200) #include #include #include #include #include #include #include #include #include #include #include #include namespace boost { namespace asio { namespace detail { template class reactive_deadline_timer_service { public: // Implementation structure for a timer. struct timer_impl : private noncopyable { boost::posix_time::ptime expiry; }; // The native type of the timer. This type is dependent on the underlying // implementation of the timer service. typedef timer_impl* impl_type; // The demuxer type for this service. typedef Demuxer demuxer_type; // The time type. typedef typename Time_Traits::time_type time_type; // The duration type. typedef typename Time_Traits::duration_type duration_type; // Constructor. reactive_deadline_timer_service(demuxer_type& d) : demuxer_(d), reactor_(d.get_service(service_factory())) { } // Get the demuxer associated with the service. demuxer_type& demuxer() { return demuxer_; } // Return a null timer implementation. static impl_type null() { return 0; } // Create a new timer implementation. void create(impl_type& impl) { impl = new timer_impl; } // Destroy a timer implementation. void destroy(impl_type& impl) { if (impl != null()) { reactor_.cancel_timer(impl); delete impl; impl = null(); } } // Get the expiry time for the timer as an absolute time. time_type expires_at(const impl_type& impl) const { return Time_Traits::from_utc(impl->expiry); } // Set the expiry time for the timer as an absolute time. void expires_at(impl_type& impl, const time_type& expiry_time) { impl->expiry = Time_Traits::to_utc(expiry_time); } // Get the expiry time for the timer relative to now. duration_type expires_from_now(const impl_type& impl) const { return Time_Traits::subtract(expires_at(impl), Time_Traits::now()); } // Set the expiry time for the timer relative to now. void expires_from_now(impl_type& impl, const duration_type& expiry_time) { expires_at(impl, Time_Traits::add(Time_Traits::now(), expiry_time)); } // Cancel any asynchronous wait operations associated with the timer. std::size_t cancel(impl_type& impl) { return reactor_.cancel_timer(impl); } // Perform a blocking wait on the timer. void wait(impl_type& impl) { boost::posix_time::ptime now = boost::posix_time::microsec_clock::universal_time(); while (now < impl->expiry) { boost::posix_time::time_duration timeout = impl->expiry - now; ::timeval tv; tv.tv_sec = timeout.total_seconds(); tv.tv_usec = timeout.total_microseconds() % 1000000; socket_ops::select(0, 0, 0, 0, &tv); now = boost::posix_time::microsec_clock::universal_time(); } } template class wait_handler { public: wait_handler(impl_type& impl, Demuxer& demuxer, Handler handler) : impl_(impl), demuxer_(demuxer), work_(demuxer), handler_(handler) { } void operator()(int result) { boost::asio::error e(result); demuxer_.post(detail::bind_handler(handler_, e)); } private: impl_type& impl_; Demuxer& demuxer_; typename Demuxer::work work_; Handler handler_; }; // Start an asynchronous wait on the timer. template void async_wait(impl_type& impl, Handler handler) { reactor_.schedule_timer(impl->expiry, wait_handler(impl, demuxer_, handler), impl); } private: // The demuxer used for dispatching handlers. Demuxer& demuxer_; // The selector that performs event demultiplexing for the provider. Reactor& reactor_; }; } // namespace detail } // namespace asio } // namespace boost #include #endif // BOOST_ASIO_DETAIL_REACTIVE_DEADLINE_TIMER_SERVICE_HPP