deadline_timer_service.hpp
Go to the documentation of this file.
00001 //
00002 // deadline_timer_service.hpp
00003 // ~~~~~~~~~~~~~~~~~~~~~~~~~~
00004 //
00005 // Copyright (c) 2003-2008 Christopher M. Kohlhoff (chris at kohlhoff dot com)
00006 //
00007 // Distributed under the Boost Software License, Version 1.0. (See accompanying
00008 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
00009 //
00010 
00011 #ifndef ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
00012 #define ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
00013 
00014 #if defined(_MSC_VER) && (_MSC_VER >= 1200)
00015 # pragma once
00016 #endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
00017 
00018 #include "asio/detail/push_options.hpp"
00019 
00020 #include "asio/detail/push_options.hpp"
00021 #include <cstddef>
00022 #include <boost/config.hpp>
00023 #include <boost/date_time/posix_time/posix_time_types.hpp>
00024 #include "asio/detail/pop_options.hpp"
00025 
00026 #include "asio/error.hpp"
00027 #include "asio/io_service.hpp"
00028 #include "asio/detail/bind_handler.hpp"
00029 #include "asio/detail/handler_base_from_member.hpp"
00030 #include "asio/detail/noncopyable.hpp"
00031 #include "asio/detail/service_base.hpp"
00032 #include "asio/detail/socket_ops.hpp"
00033 #include "asio/detail/socket_types.hpp"
00034 #include "asio/detail/timer_queue.hpp"
00035 
00036 namespace asio {
00037 namespace detail {
00038 
00039 template <typename Time_Traits, typename Timer_Scheduler>
00040 class deadline_timer_service
00041   : public asio::detail::service_base<
00042       deadline_timer_service<Time_Traits, Timer_Scheduler> >
00043 {
00044 public:
00045   // The time type.
00046   typedef typename Time_Traits::time_type time_type;
00047 
00048   // The duration type.
00049   typedef typename Time_Traits::duration_type duration_type;
00050 
00051   // The implementation type of the timer. This type is dependent on the
00052   // underlying implementation of the timer service.
00053   struct implementation_type
00054     : private asio::detail::noncopyable
00055   {
00056     time_type expiry;
00057     bool might_have_pending_waits;
00058   };
00059 
00060   // Constructor.
00061   deadline_timer_service(asio::io_service& io_service)
00062     : asio::detail::service_base<
00063         deadline_timer_service<Time_Traits, Timer_Scheduler> >(io_service),
00064       scheduler_(asio::use_service<Timer_Scheduler>(io_service))
00065   {
00066     scheduler_.add_timer_queue(timer_queue_);
00067   }
00068 
00069   // Destructor.
00070   ~deadline_timer_service()
00071   {
00072     scheduler_.remove_timer_queue(timer_queue_);
00073   }
00074 
00075   // Destroy all user-defined handler objects owned by the service.
00076   void shutdown_service()
00077   {
00078   }
00079 
00080   // Construct a new timer implementation.
00081   void construct(implementation_type& impl)
00082   {
00083     impl.expiry = time_type();
00084     impl.might_have_pending_waits = false;
00085   }
00086 
00087   // Destroy a timer implementation.
00088   void destroy(implementation_type& impl)
00089   {
00090     asio::error_code ec;
00091     cancel(impl, ec);
00092   }
00093 
00094   // Cancel any asynchronous wait operations associated with the timer.
00095   std::size_t cancel(implementation_type& impl, asio::error_code& ec)
00096   {
00097     if (!impl.might_have_pending_waits)
00098     {
00099       ec = asio::error_code();
00100       return 0;
00101     }
00102     std::size_t count = scheduler_.cancel_timer(timer_queue_, &impl);
00103     impl.might_have_pending_waits = false;
00104     ec = asio::error_code();
00105     return count;
00106   }
00107 
00108   // Get the expiry time for the timer as an absolute time.
00109   time_type expires_at(const implementation_type& impl) const
00110   {
00111     return impl.expiry;
00112   }
00113 
00114   // Set the expiry time for the timer as an absolute time.
00115   std::size_t expires_at(implementation_type& impl,
00116       const time_type& expiry_time, asio::error_code& ec)
00117   {
00118     std::size_t count = cancel(impl, ec);
00119     impl.expiry = expiry_time;
00120     ec = asio::error_code();
00121     return count;
00122   }
00123 
00124   // Get the expiry time for the timer relative to now.
00125   duration_type expires_from_now(const implementation_type& impl) const
00126   {
00127     return Time_Traits::subtract(expires_at(impl), Time_Traits::now());
00128   }
00129 
00130   // Set the expiry time for the timer relative to now.
00131   std::size_t expires_from_now(implementation_type& impl,
00132       const duration_type& expiry_time, asio::error_code& ec)
00133   {
00134     return expires_at(impl,
00135         Time_Traits::add(Time_Traits::now(), expiry_time), ec);
00136   }
00137 
00138   // Perform a blocking wait on the timer.
00139   void wait(implementation_type& impl, asio::error_code& ec)
00140   {
00141     time_type now = Time_Traits::now();
00142     while (Time_Traits::less_than(now, impl.expiry))
00143     {
00144       boost::posix_time::time_duration timeout =
00145         Time_Traits::to_posix_duration(Time_Traits::subtract(impl.expiry, now));
00146       ::timeval tv;
00147       tv.tv_sec = timeout.total_seconds();
00148       tv.tv_usec = timeout.total_microseconds() % 1000000;
00149       asio::error_code ec;
00150       socket_ops::select(0, 0, 0, 0, &tv, ec);
00151       now = Time_Traits::now();
00152     }
00153     ec = asio::error_code();
00154   }
00155 
00156   template <typename Handler>
00157   class wait_handler : 
00158     public handler_base_from_member<Handler>
00159   {
00160   public:
00161     wait_handler(asio::io_service& io_service, Handler handler)
00162       : handler_base_from_member<Handler>(handler),
00163         io_service_(io_service),
00164         work_(io_service)
00165     {
00166     }
00167 
00168     void operator()(const asio::error_code& result)
00169     {
00170       io_service_.post(detail::bind_handler(this->handler_, result));
00171     }
00172 
00173   private:
00174     asio::io_service& io_service_;
00175     asio::io_service::work work_;
00176   };
00177 
00178   // Start an asynchronous wait on the timer.
00179   template <typename Handler>
00180   void async_wait(implementation_type& impl, Handler handler)
00181   {
00182     impl.might_have_pending_waits = true;
00183     scheduler_.schedule_timer(timer_queue_, impl.expiry,
00184         wait_handler<Handler>(this->get_io_service(), handler), &impl);
00185   }
00186 
00187 private:
00188   // The queue of timers.
00189   timer_queue<Time_Traits> timer_queue_;
00190 
00191   // The object that schedules and executes timers. Usually a reactor.
00192   Timer_Scheduler& scheduler_;
00193 };
00194 
00195 } // namespace detail
00196 } // namespace asio
00197 
00198 #include "asio/detail/pop_options.hpp"
00199 
00200 #endif // ASIO_DETAIL_DEADLINE_TIMER_SERVICE_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines


Castor
Author(s): Carpe Noctem
autogenerated on Fri Nov 8 2013 11:05:39