ana/api/timers.hpp

Go to the documentation of this file.
00001 /* $Id: timers.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 
00003 /**
00004  * @file
00005  * @brief Implementation details for the ana project dealing with timers.
00006  *
00007  * ana: Asynchronous Network API.
00008  * Copyright (C) 2010 - 2012 Guillermo Biset.
00009  *
00010  * This file is part of the ana project.
00011  *
00012  * System:         ana
00013  * Language:       C++
00014  *
00015  * Author:         Guillermo Biset
00016  * E-Mail:         billybiset AT gmail DOT com
00017  *
00018  * ana is free software: you can redistribute it and/or modify
00019  * it under the terms of the GNU General Public License as published by
00020  * the Free Software Foundation, either version 2 of the License, or
00021  * (at your option) any later version.
00022  *
00023  * ana is distributed in the hope that it will be useful,
00024  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00025  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00026  * GNU General Public License for more details.
00027  *
00028  * You should have received a copy of the GNU General Public License
00029  * along with ana.  If not, see <http://www.gnu.org/licenses/>.
00030  *
00031  */
00032 
00033 #ifndef ANA_TIMERS_HPP
00034 #define ANA_TIMERS_HPP
00035 
00036 #include <boost/bind.hpp>
00037 #include <boost/thread.hpp>
00038 
00039 #include "buffers.hpp"
00040 
00041 namespace ana
00042 {
00043     /** @name Time duration functions. */
00044     //@{
00045     /**
00046      * Time conversion functions.
00047      */
00048     namespace time
00049     {
00050         /**
00051          * Create a time lapse from a given amount of milliseconds.
00052          *
00053          * @param ms : Milliseconds of elapsed time, must be a positive integer value.
00054          *
00055          * @returns : A time duration amount (in milliseconds) to be used with timers.
00056          */
00057         inline size_t milliseconds(size_t ms) { return ms;              }
00058 
00059         /**
00060          * Create a time lapse from a given amount of seconds.
00061          *
00062          * @param s : Seconds of elapsed time.
00063          *
00064          * @returns : A time duration amount (in milliseconds) to be used with timers.
00065          */
00066         inline size_t seconds(double s)       { return size_t(s * 1000);}
00067 
00068         /**
00069          * Create a time lapse from a given amount of minutes.
00070          *
00071          * @param m : Minutes of elapsed time.
00072          *
00073          * @returns : A time duration amount (in milliseconds) to be used with timers.
00074          */
00075         inline size_t minutes(double m)       { return seconds(m * 60); }
00076 
00077         /**
00078          * Create a time lapse from a given amount of hours.
00079          *
00080          * @param h : Hours of elapsed time.
00081          *
00082          * @returns : A time duration amount (in milliseconds) to be used with timers.
00083          */
00084         inline size_t hours(double h)         { return minutes(h * 60); }
00085 
00086         /**
00087          * Create a time lapse from a given amount of days.
00088          *
00089          * @param d : Hours of elapsed time.
00090          *
00091          * @returns : A time duration amount (in milliseconds) to be used with timers.
00092          */
00093         inline size_t days(double d)         { return hours(d * 24); }
00094     }
00095     //@}
00096 
00097     /**
00098      * Timeout policies for send operations.
00099      *
00100      * \sa timer
00101      */
00102     enum timeout_policy
00103     {
00104         /** Don't use timers in any operation.                */
00105         NoTimeouts,
00106 
00107         /** Use timers with a fixed time for every operation. */
00108         FixedTime,
00109 
00110         /**
00111          * Use timers, calculating the necessary time from
00112          * the size of the buffer that is to be sent.
00113          */
00114         TimePerKilobyte
00115     };
00116 
00117     /** @name Timers
00118      *
00119      * Definitions of timer related types.
00120      */
00121     //@{
00122 
00123     /// @cond false
00124     namespace detail
00125     {
00126         /** Private class providing traits for the timer type. */
00127         struct time_t_traits
00128         {
00129             // The time type.
00130             typedef std::time_t time_type;
00131 
00132             // The duration type.
00133             struct duration_type
00134             {
00135                 duration_type() : value(0) {}
00136                 duration_type(std::time_t v) : value(v) {}
00137                 std::time_t value;
00138             };
00139 
00140             // Get the current time.
00141             static time_type now();
00142 
00143             // Add a duration to a time.
00144             static time_type add(const time_type& t, const duration_type& d);
00145 
00146             // Subtract one time from another.
00147             static duration_type subtract(const time_type& t1, const time_type& t2);
00148 
00149             // Test whether one time is less than another.
00150             static bool less_than(const time_type& t1, const time_type& t2);
00151 
00152             // Convert to POSIX duration type.
00153             static boost::posix_time::time_duration to_posix_duration(const duration_type& d);
00154         };
00155     }
00156     /// @endcond
00157 
00158     /** A boost::asio::basic_deadline_timer, can be used externally. */
00159     typedef boost::asio::basic_deadline_timer<std::time_t,detail::time_t_traits> boost_timer;
00160 
00161     /**
00162      * General purpose asynchronous timer.
00163      */
00164     class timer
00165     {
00166         public:
00167             /**
00168              * Standard constructor.
00169              * Creates its own io_service object and runs in its own thread.
00170              */
00171             timer();
00172 
00173             /**
00174              * Construct a timer object using a running io_service object.
00175              * The timer insures it won't stop the io_service.
00176              *
00177              * @pre The io_service will be running during the timer's lifetime.
00178              */
00179             timer( boost::asio::io_service& io );
00180 
00181             /**
00182              * Wait in background a given amount of milliseconds.
00183              *
00184              * The method shouldn't be called with a size_t constant
00185              * directly. Instead, the user should use the functions in
00186              * the ana::time namespace.
00187              *
00188              * @param milliseconds : Amount of milliseconds to wait.
00189              * @param handler : Handler object to handle the timeout event.
00190              *
00191              * Examples:
00192              *    - wait( ana::time::seconds(5),
00193              *            boost::bind( &ChatServer::handle_timeout, this,
00194              *                         boost::asio::placeholders::error);
00195              *
00196              * \sa ana::time
00197              */
00198             template<class Handler>
00199             void wait(size_t milliseconds, Handler handler)
00200             {
00201                 //conversion will use a double or float
00202                 timer_.expires_from_now( milliseconds / 1000.0);
00203                 timer_.async_wait(handler);
00204 
00205                 if ( holds_fresh_io_service_ )
00206                     timer_thread_ = new boost::thread( boost::bind( &timer::run, this ) );
00207             }
00208 
00209             /** Standard destructor, cancels pending operations if handler wasn't called. */
00210             ~timer();
00211 
00212         private:
00213             void run();
00214 
00215             const bool holds_fresh_io_service_;
00216 
00217             boost::asio::io_service* io_service_;
00218 
00219             boost::thread* timer_thread_;
00220 
00221             boost_timer timer_;
00222     };
00223 
00224     namespace detail
00225     {
00226         /**
00227          * A network sender component that can be configured to issue timeout events.
00228          */
00229         class timed_sender
00230         {
00231             public:
00232 
00233                 virtual ~timed_sender() {}
00234 
00235                 /**
00236                  * Set the policy for timed operations (such as send.)
00237                  *
00238                  * @param type : Type of timeout policy.
00239                  * @param ms : Milliseconds related to the given policy, 0 means no timeouts.
00240                  *
00241                  * Examples:
00242                  *    - set_timeouts( ana::NoTimeouts );
00243                  *    - set_timeouts( ana::FixedTime, ana::time::minutes( 1 ) );
00244                  *
00245                  * \sa timeout_policy
00246                  * \sa ana::time
00247                  */
00248                 void set_timeouts(timeout_policy type, size_t ms = 0);
00249 
00250                 /**
00251                  * Start a timer given the current configuration.
00252                  *
00253                  * @param buffer : The buffer used in the send operation.
00254                  * @param handler : The handler of the timeout/abort event.
00255                  *
00256                  * @returns : A pointer to a newly created timer object.
00257                  */
00258                 template<class Handler>
00259                 void start_timer( timer* timer, shared_buffer buffer, Handler handler ) const
00260                 {
00261                     if ( ! timeouts_enabled() )
00262                         delete timer;
00263                     else
00264                     {
00265                         if ( timer != NULL )
00266                         {
00267                             if ( timeout_type_ == TimePerKilobyte)
00268                                 timer->wait( (buffer->size() / 1024.0) * timeout_milliseconds_,
00269                                              handler);
00270                             else
00271                                 timer->wait( timeout_milliseconds_, handler);
00272                         }
00273                     }
00274                 }
00275 
00276                 bool timeouts_enabled() const;
00277 
00278                 /**
00279                  * Creates a timer using the current io_service of this component.
00280                  * For efficiency reasons, always create timers this way when you have the chance.
00281                  */
00282                 virtual timer* create_timer() = 0;
00283 
00284             protected:
00285                 /** Standard constructor. */
00286                 timed_sender();
00287 
00288                 /** Type of timer policy.                 */
00289                 timeout_policy timeout_type_         ;
00290 
00291                 /** Amount of ms relevant to this policy. */
00292                 size_t         timeout_milliseconds_ ;
00293         };
00294     }
00295 }
00296 
00297 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:45 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs