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
| Generated by doxygen 1.7.1 on Fri May 25 2012 01:02:45 for The Battle for Wesnoth | Gna! | Forum | Wiki | CIA | devdocs |