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