00001 /* -*- C++ -*- */ 00002 00003 //============================================================================= 00004 /** 00005 * @file Timer_Queue_T.h 00006 * 00007 * $Id: Timer_Queue_T.h,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $ 00008 * 00009 * @author Doug Schmidt <schmidt@cs.wustl.edu> 00010 * @author Irfan Pyarali <irfan@cs.wustl.edu> and 00011 * @author Darrell Brunsch <brunsch@cs.wustl.edu> 00012 */ 00013 //============================================================================= 00014 00015 #ifndef ACE_TIMER_QUEUE_T_H 00016 #define ACE_TIMER_QUEUE_T_H 00017 #include "ace/pre.h" 00018 00019 #include "ace/Free_List.h" 00020 00021 #if !defined (ACE_LACKS_PRAGMA_ONCE) 00022 # pragma once 00023 #endif /* ACE_LACKS_PRAGMA_ONCE */ 00024 00025 #include "ace/Test_and_Set.h" 00026 00027 /** 00028 * @class ACE_Timer_Node_Dispatch_Info_T 00029 * 00030 * @brief Maintains generated dispatch information for Timer nodes. 00031 * 00032 */ 00033 template <class TYPE> 00034 class ACE_Timer_Node_Dispatch_Info_T 00035 { 00036 public: 00037 /// The type of object held in the queue 00038 TYPE type_; 00039 00040 /// Asynchronous completion token associated with the timer. 00041 const void *act_; 00042 }; 00043 00044 /** 00045 * @class ACE_Timer_Node_T 00046 * 00047 * @brief Maintains the state associated with a Timer entry. 00048 */ 00049 template <class TYPE> 00050 class ACE_Timer_Node_T 00051 { 00052 public: 00053 /// Default constructor 00054 ACE_Timer_Node_T (void); 00055 00056 /// Destructor 00057 ~ACE_Timer_Node_T (void); 00058 00059 /// Useful typedef .. 00060 typedef ACE_Timer_Node_Dispatch_Info_T <TYPE> DISPATCH_INFO; 00061 00062 /// Singly linked list 00063 void set (const TYPE &type, 00064 const void *a, 00065 const ACE_Time_Value &t, 00066 const ACE_Time_Value &i, 00067 ACE_Timer_Node_T<TYPE> *n, 00068 long timer_id); 00069 00070 /// Doubly linked list version 00071 void set (const TYPE &type, 00072 const void *a, 00073 const ACE_Time_Value &t, 00074 const ACE_Time_Value &i, 00075 ACE_Timer_Node_T<TYPE> *p, 00076 ACE_Timer_Node_T<TYPE> *n, 00077 long timer_id); 00078 00079 // = Accessors 00080 00081 /// Get the type. 00082 TYPE &get_type (void); 00083 00084 /// Set the type. 00085 void set_type (TYPE &type); 00086 00087 /// Get the asynchronous completion token. 00088 const void *get_act (void); 00089 00090 /// Set the asynchronous completion token. 00091 void set_act (void *act); 00092 00093 /// Get the timer value. 00094 const ACE_Time_Value &get_timer_value (void) const; 00095 00096 /// Set the timer value. 00097 void set_timer_value (const ACE_Time_Value &timer_value); 00098 00099 /// Get the timer interval. 00100 const ACE_Time_Value &get_interval (void) const; 00101 00102 /// Set the timer interval. 00103 void set_interval (const ACE_Time_Value &interval); 00104 00105 /// Get the previous pointer. 00106 ACE_Timer_Node_T<TYPE> *get_prev (void); 00107 00108 /// Set the previous pointer. 00109 void set_prev (ACE_Timer_Node_T<TYPE> *prev); 00110 00111 /// Get the next pointer. 00112 ACE_Timer_Node_T<TYPE> *get_next (void); 00113 00114 /// Set the next pointer. 00115 void set_next (ACE_Timer_Node_T<TYPE> *next); 00116 00117 /// Get the timer_id. 00118 long get_timer_id (void) const; 00119 00120 /// Set the timer_id. 00121 void set_timer_id (long timer_id); 00122 00123 /// Get the dispatch info. The dispatch information is got 00124 /// through <info>. This form helps us in preventing allocation and 00125 /// deleting data along the criticl path. 00126 /// @@TODO: We may want to have a copying version too, so that our 00127 /// interface will be complete.. 00128 void get_dispatch_info (ACE_Timer_Node_Dispatch_Info_T <TYPE> &info); 00129 00130 /// Dump the state of an TYPE. 00131 void dump (void) const; 00132 00133 private: 00134 /// Type of object stored in the Queue 00135 TYPE type_; 00136 00137 /// Asynchronous completion token associated with the timer. 00138 const void *act_; 00139 00140 /// Time until the timer expires. 00141 ACE_Time_Value timer_value_; 00142 00143 /// If this is a periodic timer this holds the time until the next 00144 /// timeout. 00145 ACE_Time_Value interval_; 00146 00147 /// Pointer to previous timer. 00148 ACE_Timer_Node_T<TYPE> *prev_; 00149 00150 /// Pointer to next timer. 00151 ACE_Timer_Node_T<TYPE> *next_; 00152 00153 /// Id of this timer (used to cancel timers before they expire). 00154 long timer_id_; 00155 }; 00156 00157 /** 00158 * @class ACE_Timer_Queue_Iterator_T 00159 * 00160 * @brief Generic interface for iterating over a subclass of 00161 * <ACE_Timer_Queue>. 00162 * 00163 * This is a generic iterator that can be used to visit every 00164 * node of a timer queue. Be aware that it isn't guaranteed 00165 * that the transversal will be in order of timeout values. 00166 */ 00167 template <class TYPE, class FUNCTOR, class ACE_LOCK> 00168 class ACE_Timer_Queue_Iterator_T 00169 { 00170 public: 00171 // = Initialization and termination methods. 00172 /// Constructor. 00173 ACE_Timer_Queue_Iterator_T (void); 00174 00175 /// Destructor. 00176 virtual ~ACE_Timer_Queue_Iterator_T (void); 00177 00178 /// Positions the iterator at the earliest node in the Timer Queue 00179 virtual void first (void) = 0; 00180 00181 /// Positions the iterator at the next node in the Timer Queue 00182 virtual void next (void) = 0; 00183 00184 /// Returns true when there are no more nodes in the sequence 00185 virtual int isdone (void) const = 0; 00186 00187 /// Returns the node at the current position in the sequence 00188 virtual ACE_Timer_Node_T<TYPE> *item (void) = 0; 00189 }; 00190 00191 /** 00192 * @class ACE_Timer_Queue_T 00193 * 00194 * @brief Provides an interface to timers. 00195 * 00196 * This is an abstract base class that provides hook for 00197 * implementing specialized policies such as <ACE_Timer_List> 00198 * and <ACE_Timer_Heap>. 00199 */ 00200 template <class TYPE, class FUNCTOR, class ACE_LOCK> 00201 class ACE_Timer_Queue_T 00202 { 00203 public: 00204 /// Type of Iterator. 00205 typedef ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> ITERATOR; 00206 00207 // = Initialization and termination methods. 00208 /** 00209 * Default constructor. <upcall_functor> is the instance of the 00210 * FUNCTOR to be used by the queue. If <upcall_functor> is 0, Timer 00211 * Queue will create a default FUNCTOR. <freelist> the freelist of 00212 * timer nodes. If 0, then a default freelist will be created. 00213 */ 00214 ACE_Timer_Queue_T (FUNCTOR *upcall_functor = 0, 00215 ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist = 0); 00216 00217 /// Destructor - make virtual for proper destruction of inherited 00218 /// classes. 00219 virtual ~ACE_Timer_Queue_T (void); 00220 00221 /// True if queue is empty, else false. 00222 virtual int is_empty (void) const = 0; 00223 00224 /// Returns the time of the earlier node in the Timer_Queue. Must 00225 /// be called on a non-empty queue. 00226 virtual const ACE_Time_Value &earliest_time (void) const = 0; 00227 00228 /** 00229 * Schedule <type> that will expire at <future_time>, 00230 * which is specified in absolute time. If it expires then <act> is 00231 * passed in as the value to the <functor>. If <interval> is != to 00232 * <ACE_Time_Value::zero> then it is used to reschedule the <type> 00233 * automatically, using relative time to the current <gettimeofday>. 00234 * This method returns a <timer_id> that uniquely identifies the the 00235 * <type> entry in an internal list. This <timer_id> can be used to 00236 * cancel the timer before it expires. The cancellation ensures 00237 * that <timer_ids> are unique up to values of greater than 2 00238 * billion timers. As long as timers don't stay around longer than 00239 * this there should be no problems with accidentally deleting the 00240 * wrong timer. Returns -1 on failure (which is guaranteed never to 00241 * be a valid <timer_id>). 00242 */ 00243 virtual long schedule (const TYPE &type, 00244 const void *act, 00245 const ACE_Time_Value &future_time, 00246 const ACE_Time_Value &interval = ACE_Time_Value::zero) = 0; 00247 00248 /** 00249 * Resets the interval of the timer represented by <timer_id> to 00250 * <interval>, which is specified in relative time to the current 00251 * <gettimeofday>. If <interval> is equal to 00252 * <ACE_Time_Value::zero>, the timer will become a non-rescheduling 00253 * timer. Returns 0 if successful, -1 if not. 00254 */ 00255 virtual int reset_interval (long timer_id, 00256 const ACE_Time_Value &interval) = 0; 00257 00258 /** 00259 * Cancel all timer associated with <type>. If 00260 * <dont_call_handle_close> is 0 then the <functor> will be invoked, 00261 * which typically invokes the <handle_close> hook. Returns number 00262 * of timers cancelled. 00263 */ 00264 virtual int cancel (const TYPE &type, 00265 int dont_call_handle_close = 1) = 0; 00266 00267 /** 00268 * Cancel the single timer that matches the <timer_id> value (which 00269 * was returned from the <schedule> method). If act is non-NULL 00270 * then it will be set to point to the ``magic cookie'' argument 00271 * passed in when the timer was registered. This makes it possible 00272 * to free up the memory and avoid memory leaks. If 00273 * <dont_call_handle_close> is 0 then the <functor> will be invoked, 00274 * which typically calls the <handle_close> hook. Returns 1 if 00275 * cancellation succeeded and 0 if the <timer_id> wasn't found. 00276 */ 00277 virtual int cancel (long timer_id, 00278 const void **act = 0, 00279 int dont_call_handle_close = 1) = 0; 00280 00281 /** 00282 * Run the <functor> for all timers whose values are <= <cur_time>. 00283 * This does not account for <timer_skew>. Returns the number of 00284 * timers canceled. 00285 */ 00286 virtual int expire (const ACE_Time_Value ¤t_time); 00287 00288 /** 00289 * Get the dispatch information for a timer whose value is <= <cur_time>. 00290 * This does not account for <timer_skew>. Returns 1 if 00291 * there is a node whose value <= <cur_time> else returns a 0. 00292 * 00293 */ 00294 int dispatch_info (const ACE_Time_Value ¤t_time, 00295 ACE_Timer_Node_Dispatch_Info_T<TYPE> &info); 00296 00297 /** 00298 * Run the <functor> for all timers whose values are <= 00299 * <ACE_OS::gettimeofday>. Also accounts for <timer_skew>. 00300 * 00301 * Depending on the resolution of the underlying OS the system calls 00302 * like select()/poll() might return at time different than that is 00303 * specified in the timeout. Suppose the OS guarantees a resolution of t ms. 00304 * The timeline will look like 00305 * 00306 * A B 00307 * | | 00308 * V V 00309 * |-------------|-------------|-------------|-------------| 00310 * t t t t t 00311 * 00312 * 00313 * If you specify a timeout value of A, then the timeout will not occur 00314 * at A but at the next interval of the timer, which is later than 00315 * that is expected. Similarly, if your timeout value is equal to B, 00316 * then the timeout will occur at interval after B. Now depending upon the 00317 * resolution of your timeouts and the accuracy of the timeouts 00318 * needed for your application, you should set the value of 00319 * <timer_skew>. In the above case, if you want the timeout A to fire 00320 * no later than A, then you should specify your <timer_skew> to be 00321 * A % t. 00322 * 00323 * The timeout value should be specified via the macro ACE_TIMER_SKEW 00324 * in your config.h file. The default value is zero. 00325 * 00326 * Things get interesting if the t before the timeout value B is zero 00327 * i.e your timeout is less than the interval. In that case, you are 00328 * almost sure of not getting the desired timeout behaviour. Maybe you 00329 * should look for a better OS :-) 00330 * 00331 * Returns the number of timers canceled. 00332 */ 00333 00334 /* virtual */ int expire (void); 00335 00336 /** 00337 * Returns the current time of day. This method allows different 00338 * implementations of the timer queue to use special high resolution 00339 * timers. 00340 */ 00341 /* virtual */ ACE_Time_Value gettimeofday (void); 00342 00343 /// Allows applications to control how the timer queue gets the time 00344 /// of day. 00345 void gettimeofday (ACE_Time_Value (*gettimeofday)(void)); 00346 00347 /// Determine the next event to timeout. Returns <max> if there are 00348 /// no pending timers or if all pending timers are longer than max. 00349 /// This method acquires a lock internally since it modifies internal state. 00350 virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max); 00351 00352 /** 00353 * Determine the next event to timeout. Returns <max> if there are 00354 * no pending timers or if all pending timers are longer than max. 00355 * <the_timeout> should be a pointer to storage for the timeout value, 00356 * and this value is also returned. This method does not acquire a 00357 * lock internally since it doesn't modify internal state. If you 00358 * need to call this method when the queue is being modified 00359 * concurrently, however, you should make sure to acquire the <mutex()> 00360 * externally before making the call. 00361 */ 00362 virtual ACE_Time_Value *calculate_timeout (ACE_Time_Value *max, 00363 ACE_Time_Value *the_timeout); 00364 00365 /// Set the timer skew for the Timer_Queue. 00366 void timer_skew (const ACE_Time_Value &skew); 00367 00368 /// Get the timer skew for the Timer_Queue. 00369 const ACE_Time_Value &timer_skew (void) const; 00370 00371 /// Synchronization variable used by the queue 00372 ACE_LOCK &mutex (void); 00373 00374 /// Accessor to the upcall functor 00375 FUNCTOR &upcall_functor (void); 00376 00377 /// Returns a pointer to this <ACE_Timer_Queue>'s iterator. 00378 virtual ITERATOR &iter (void) = 0; 00379 00380 /// Removes the earliest node from the queue and returns it 00381 virtual ACE_Timer_Node_T<TYPE> *remove_first (void) = 0; 00382 00383 /// Dump the state of a object. 00384 virtual void dump (void) const; 00385 00386 /// Reads the earliest node from the queue and returns it. 00387 virtual ACE_Timer_Node_T<TYPE> *get_first (void) = 0; 00388 00389 /// Method used to return a timer node to the queue's ownership 00390 /// after it is returned by a method like <remove_first>. 00391 virtual void return_node (ACE_Timer_Node_T<TYPE> *); 00392 00393 00394 /// This method will call the <functor> with the <type>, <act> and 00395 /// <cur_time> 00396 /* virtual */ void upcall (TYPE &type, 00397 const void *act, 00398 const ACE_Time_Value &cur_time); 00399 00400 protected: 00401 /// Reschedule an "interval" <ACE_Timer_Node>. 00402 virtual void reschedule (ACE_Timer_Node_T<TYPE> *) = 0; 00403 00404 /// Factory method that allocates a new node. 00405 virtual ACE_Timer_Node_T<TYPE> *alloc_node (void); 00406 00407 /// Factory method that frees a previously allocated node. 00408 virtual void free_node (ACE_Timer_Node_T<TYPE> *); 00409 00410 /// Non-locking version of dispatch_info () 00411 int dispatch_info_i (const ACE_Time_Value ¤t_time, 00412 ACE_Timer_Node_Dispatch_Info_T<TYPE> &info); 00413 00414 /// Synchronization variable for <ACE_Timer_Queue>. 00415 /// NOTE: the right name would be lock_, but HP/C++ will choke on that! 00416 ACE_LOCK mutex_; 00417 00418 /// Class that implements a free list 00419 ACE_Free_List<ACE_Timer_Node_T<TYPE> > *free_list_; 00420 00421 /// Pointer to function that returns the current time of day. 00422 ACE_Time_Value (*gettimeofday_)(void); 00423 00424 /// Upcall functor 00425 FUNCTOR *upcall_functor_; 00426 00427 /// To delete or not to delete is the question? 00428 int delete_upcall_functor_; 00429 00430 /// Flag to delete only if the class created the <free_list_> 00431 int delete_free_list_; 00432 00433 private: 00434 00435 /// Returned by <calculate_timeout>. 00436 ACE_Time_Value timeout_; 00437 00438 /// Adjusts for timer skew in various clocks. 00439 ACE_Time_Value timer_skew_; 00440 00441 // = Don't allow these operations for now. 00442 ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Queue_T (const ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> &)) 00443 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> &)) 00444 }; 00445 00446 /** 00447 * @class ACE_Event_Handler_Handle_Timeout_Upcall 00448 * 00449 * @brief Functor for Timer_Queues. 00450 * 00451 * This class implements the functor required by the Timer 00452 * Queue to call <handle_timeout> on ACE_Event_Handlers. 00453 */ 00454 template <class ACE_LOCK> 00455 class ACE_Event_Handler_Handle_Timeout_Upcall 00456 { 00457 public: 00458 typedef ACE_Timer_Queue_T<ACE_Event_Handler *, 00459 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>, 00460 ACE_LOCK> 00461 TIMER_QUEUE; 00462 00463 // = Initialization and termination methods. 00464 /// Constructor. 00465 ACE_Event_Handler_Handle_Timeout_Upcall (void); 00466 00467 /// Destructor. 00468 ~ACE_Event_Handler_Handle_Timeout_Upcall (void); 00469 00470 /// This method is called when the timer expires 00471 int timeout (TIMER_QUEUE &timer_queue, 00472 ACE_Event_Handler *handler, 00473 const void *arg, 00474 const ACE_Time_Value &cur_time); 00475 00476 /// This method is called when the timer is cancelled 00477 int cancellation (TIMER_QUEUE &timer_queue, 00478 ACE_Event_Handler *handler); 00479 00480 /// This method is called when the timer queue is destroyed and 00481 /// the timer is still contained in it 00482 int deletion (TIMER_QUEUE &timer_queue, 00483 ACE_Event_Handler *handler, 00484 const void *arg); 00485 private: 00486 // = Don't allow these operations for now. 00487 ACE_UNIMPLEMENTED_FUNC (ACE_Event_Handler_Handle_Timeout_Upcall (const ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK> &)) 00488 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK> &)) 00489 }; 00490 00491 #if defined (__ACE_INLINE__) 00492 #include "ace/Timer_Queue_T.i" 00493 #endif /* __ACE_INLINE__ */ 00494 00495 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE) && !defined (ACE_HAS_BROKEN_HPUX_TEMPLATES) 00496 #include "ace/Timer_Queue_T.cpp" 00497 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE && !ACE_HAS_BROKEN_HPUX_TEMPLATES */ 00498 00499 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA) 00500 #pragma implementation ("Timer_Queue_T.cpp") 00501 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */ 00502 00503 #include "ace/post.h" 00504 #endif /* ACE_TIMER_QUEUE_T_H */
1.2.14 written by Dimitri van Heesch,
© 1997-2002