3 //=============================================================================
5 * @file Timer_Queue_T.h
7 * $Id: Timer_Queue_T.h 80826 2008-03-04 14:51:23Z wotte $
9 * @author Doug Schmidt <schmidt@cs.wustl.edu>
10 * @author Irfan Pyarali <irfan@cs.wustl.edu> and
11 * @author Darrell Brunsch <brunsch@cs.wustl.edu>
13 //=============================================================================
15 #ifndef ACE_TIMER_QUEUE_T_H
16 #define ACE_TIMER_QUEUE_T_H
17 #include /**/ "ace/pre.h"
19 #include "ace/Free_List.h"
21 #if !defined (ACE_LACKS_PRAGMA_ONCE)
23 #endif /* ACE_LACKS_PRAGMA_ONCE */
25 #include "ace/Event_Handler.h"
26 #include "ace/Time_Value.h"
28 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
31 * @class ACE_Timer_Node_Dispatch_Info_T
33 * @brief Maintains generated dispatch information for Timer nodes.
37 class ACE_Timer_Node_Dispatch_Info_T
40 /// The type of object held in the queue
43 /// Asynchronous completion token associated with the timer.
46 /// Flag to check if the timer is recurring.
51 * @class ACE_Timer_Node_T
53 * @brief Maintains the state associated with a Timer entry.
56 class ACE_Timer_Node_T
59 /// Default constructor
60 ACE_Timer_Node_T (void);
63 ~ACE_Timer_Node_T (void);
66 typedef ACE_Timer_Node_Dispatch_Info_T
<TYPE
> DISPATCH_INFO
;
68 /// Singly linked list
69 void set (const TYPE
&type
,
71 const ACE_Time_Value
&t
,
72 const ACE_Time_Value
&i
,
73 ACE_Timer_Node_T
<TYPE
> *n
,
76 /// Doubly linked list version
77 void set (const TYPE
&type
,
79 const ACE_Time_Value
&t
,
80 const ACE_Time_Value
&i
,
81 ACE_Timer_Node_T
<TYPE
> *p
,
82 ACE_Timer_Node_T
<TYPE
> *n
,
88 TYPE
&get_type (void);
91 void set_type (TYPE
&type
);
93 /// Get the asynchronous completion token.
94 const void *get_act (void);
96 /// Set the asynchronous completion token.
97 void set_act (void *act
);
99 /// Get the timer value.
100 const ACE_Time_Value
&get_timer_value (void) const;
102 /// Set the timer value.
103 void set_timer_value (const ACE_Time_Value
&timer_value
);
105 /// Get the timer interval.
106 const ACE_Time_Value
&get_interval (void) const;
108 /// Set the timer interval.
109 void set_interval (const ACE_Time_Value
&interval
);
111 /// Get the previous pointer.
112 ACE_Timer_Node_T
<TYPE
> *get_prev (void);
114 /// Set the previous pointer.
115 void set_prev (ACE_Timer_Node_T
<TYPE
> *prev
);
117 /// Get the next pointer.
118 ACE_Timer_Node_T
<TYPE
> *get_next (void);
120 /// Set the next pointer.
121 void set_next (ACE_Timer_Node_T
<TYPE
> *next
);
123 /// Get the timer_id.
124 long get_timer_id (void) const;
126 /// Set the timer_id.
127 void set_timer_id (long timer_id
);
129 /// Get the dispatch info. The dispatch information is got
130 /// through <info>. This form helps us in preventing allocation and
131 /// deleting data along the criticl path.
132 /// @@TODO: We may want to have a copying version too, so that our
133 /// interface will be complete..
134 void get_dispatch_info (ACE_Timer_Node_Dispatch_Info_T
<TYPE
> &info
);
136 /// Dump the state of an TYPE.
137 void dump (void) const;
140 /// Type of object stored in the Queue
143 /// Asynchronous completion token associated with the timer.
146 /// Time until the timer expires.
147 ACE_Time_Value timer_value_
;
149 /// If this is a periodic timer this holds the time until the next
151 ACE_Time_Value interval_
;
153 /// Pointer to previous timer.
154 ACE_Timer_Node_T
<TYPE
> *prev_
;
156 /// Pointer to next timer.
157 ACE_Timer_Node_T
<TYPE
> *next_
;
159 /// Id of this timer (used to cancel timers before they expire).
164 * @class ACE_Timer_Queue_Iterator_T
166 * @brief Generic interface for iterating over a subclass of
169 * This is a generic iterator that can be used to visit every
170 * node of a timer queue. Be aware that it isn't guaranteed
171 * that the transversal will be in order of timeout values.
173 template <class TYPE
, class FUNCTOR
, class ACE_LOCK
>
174 class ACE_Timer_Queue_Iterator_T
177 // = Initialization and termination methods.
179 ACE_Timer_Queue_Iterator_T (void);
182 virtual ~ACE_Timer_Queue_Iterator_T (void);
184 /// Positions the iterator at the earliest node in the Timer Queue
185 virtual void first (void) = 0;
187 /// Positions the iterator at the next node in the Timer Queue
188 virtual void next (void) = 0;
190 /// Returns true when there are no more nodes in the sequence
191 virtual bool isdone (void) const = 0;
193 /// Returns the node at the current position in the sequence
194 virtual ACE_Timer_Node_T
<TYPE
> *item (void) = 0;
198 * @class ACE_Timer_Queue_T
200 * @brief Provides an interface to timers.
202 * This is an abstract base class that provides hook for
203 * implementing specialized policies such as ACE_Timer_List
204 * and ACE_Timer_Heap.
206 template <class TYPE
, class FUNCTOR
, class ACE_LOCK
>
207 class ACE_Timer_Queue_T
210 /// Type of Iterator.
211 typedef ACE_Timer_Queue_Iterator_T
<TYPE
, FUNCTOR
, ACE_LOCK
> ITERATOR
;
213 // = Initialization and termination methods.
215 * Default constructor. @a upcall_functor is the instance of the
216 * FUNCTOR to be used by the queue. If @a upcall_functor is 0, Timer
217 * Queue will create a default FUNCTOR. @a freelist the freelist of
218 * timer nodes. If 0, then a default freelist will be created.
220 ACE_Timer_Queue_T (FUNCTOR
*upcall_functor
= 0,
221 ACE_Free_List
<ACE_Timer_Node_T
<TYPE
> > *freelist
= 0);
223 /// Destructor - make virtual for proper destruction of inherited
225 virtual ~ACE_Timer_Queue_T (void);
227 /// True if queue is empty, else false.
228 virtual bool is_empty (void) const = 0;
230 /// Returns the time of the earlier node in the Timer_Queue. Must
231 /// be called on a non-empty queue.
232 virtual const ACE_Time_Value
&earliest_time (void) const = 0;
235 * Schedule @a type that will expire at @a future_time, which is
236 * specified in absolute time. If it expires then @a act is passed
237 * in as the value to the <functor>. If @a interval is != to
238 * ACE_Time_Value::zero then it is used to reschedule the @a type
239 * automatically, using relative time to the current <gettimeofday>.
240 * This method returns a <timer_id> that uniquely identifies the the
241 * @a type entry in an internal list. This <timer_id> can be used to
242 * cancel the timer before it expires. The cancellation ensures
243 * that <timer_ids> are unique up to values of greater than 2
244 * billion timers. As long as timers don't stay around longer than
245 * this there should be no problems with accidentally deleting the
246 * wrong timer. Returns -1 on failure (which is guaranteed never to
247 * be a valid <timer_id>).
249 virtual long schedule (const TYPE
&type
,
251 const ACE_Time_Value
&future_time
,
252 const ACE_Time_Value
&interval
= ACE_Time_Value::zero
);
255 * Resets the interval of the timer represented by @a timer_id to
256 * @a interval, which is specified in relative time to the current
257 * <gettimeofday>. If @a interval is equal to
258 * ACE_Time_Value::zero, the timer will become a non-rescheduling
259 * timer. Returns 0 if successful, -1 if not.
261 virtual int reset_interval (long timer_id
,
262 const ACE_Time_Value
&interval
) = 0;
265 * Cancel all timer associated with @a type. If
266 * @a dont_call_handle_close is 0 then the <functor> will be invoked,
267 * which typically invokes the <handle_close> hook. Returns number
268 * of timers cancelled.
270 virtual int cancel (const TYPE
&type
,
271 int dont_call_handle_close
= 1) = 0;
274 * Cancel the single timer that matches the @a timer_id value (which
275 * was returned from the <schedule> method). If act is non-NULL
276 * then it will be set to point to the ``magic cookie'' argument
277 * passed in when the timer was registered. This makes it possible
278 * to free up the memory and avoid memory leaks. If
279 * @a dont_call_handle_close is 0 then the <functor> will be invoked,
280 * which typically calls the <handle_close> hook. Returns 1 if
281 * cancellation succeeded and 0 if the @a timer_id wasn't found.
283 virtual int cancel (long timer_id
,
284 const void **act
= 0,
285 int dont_call_handle_close
= 1) = 0;
288 * Run the <functor> for all timers whose values are <= @a current_time.
289 * This does not account for <timer_skew>. Returns the number of
292 virtual int expire (const ACE_Time_Value
¤t_time
);
295 * Get the dispatch information for a timer whose value is <= @a current_time.
296 * This does not account for <timer_skew>. Returns 1 if
297 * there is a node whose value <= @a current_time else returns a 0.
300 virtual int dispatch_info (const ACE_Time_Value
¤t_time
,
301 ACE_Timer_Node_Dispatch_Info_T
<TYPE
> &info
);
304 * Run the <functor> for all timers whose values are <=
305 * <ACE_OS::gettimeofday>. Also accounts for <timer_skew>.
307 * Depending on the resolution of the underlying OS the system calls
308 * like select()/poll() might return at time different than that is
309 * specified in the timeout. Suppose the OS guarantees a resolution of t ms.
310 * The timeline will look like
315 * |-------------|-------------|-------------|-------------|
319 * If you specify a timeout value of A, then the timeout will not occur
320 * at A but at the next interval of the timer, which is later than
321 * that is expected. Similarly, if your timeout value is equal to B,
322 * then the timeout will occur at interval after B. Now depending upon the
323 * resolution of your timeouts and the accuracy of the timeouts
324 * needed for your application, you should set the value of
325 * <timer_skew>. In the above case, if you want the timeout A to fire
326 * no later than A, then you should specify your <timer_skew> to be
329 * The timeout value should be specified via the macro ACE_TIMER_SKEW
330 * in your config.h file. The default value is zero.
332 * Things get interesting if the t before the timeout value B is zero
333 * i.e your timeout is less than the interval. In that case, you are
334 * almost sure of not getting the desired timeout behaviour. Maybe you
335 * should look for a better OS :-)
337 * Returns the number of timers canceled.
340 /* virtual */ int expire (void);
343 * Returns the current time of day. This method allows different
344 * implementations of the timer queue to use special high resolution
347 /* virtual */ ACE_Time_Value
gettimeofday (void);
349 /// Allows applications to control how the timer queue gets the time
351 void gettimeofday (ACE_Time_Value (*gettimeofday
)(void));
353 /// Determine the next event to timeout. Returns @a max if there are
354 /// no pending timers or if all pending timers are longer than max.
355 /// This method acquires a lock internally since it modifies internal state.
356 virtual ACE_Time_Value
*calculate_timeout (ACE_Time_Value
*max
);
359 * Determine the next event to timeout. Returns @a max if there are
360 * no pending timers or if all pending timers are longer than max.
361 * <the_timeout> should be a pointer to storage for the timeout value,
362 * and this value is also returned. This method does not acquire a
363 * lock internally since it doesn't modify internal state. If you
364 * need to call this method when the queue is being modified
365 * concurrently, however, you should make sure to acquire the <mutex()>
366 * externally before making the call.
368 virtual ACE_Time_Value
*calculate_timeout (ACE_Time_Value
*max
,
369 ACE_Time_Value
*the_timeout
);
371 /// Set the timer skew for the Timer_Queue.
372 void timer_skew (const ACE_Time_Value
&skew
);
374 /// Get the timer skew for the Timer_Queue.
375 const ACE_Time_Value
&timer_skew (void) const;
377 /// Synchronization variable used by the queue
378 ACE_LOCK
&mutex (void);
380 /// Accessor to the upcall functor
381 FUNCTOR
&upcall_functor (void);
383 /// Returns a pointer to this ACE_Timer_Queue's iterator.
384 virtual ITERATOR
&iter (void) = 0;
386 /// Removes the earliest node from the queue and returns it
387 virtual ACE_Timer_Node_T
<TYPE
> *remove_first (void) = 0;
389 /// Dump the state of a object.
390 virtual void dump (void) const;
392 /// Reads the earliest node from the queue and returns it.
393 virtual ACE_Timer_Node_T
<TYPE
> *get_first (void) = 0;
395 /// Method used to return a timer node to the queue's ownership
396 /// after it is returned by a method like <remove_first>.
397 virtual void return_node (ACE_Timer_Node_T
<TYPE
> *);
399 /// This method will call the preinvoke() on <functor>.
400 void preinvoke (ACE_Timer_Node_Dispatch_Info_T
<TYPE
> &info
,
401 const ACE_Time_Value
&cur_time
,
402 const void *&upcall_act
);
404 /// This method will call the timeout() on <functor>.
405 void upcall (ACE_Timer_Node_Dispatch_Info_T
<TYPE
> &info
,
406 const ACE_Time_Value
&cur_time
);
408 /// This method will call the postinvoke() on <functor>.
409 void postinvoke (ACE_Timer_Node_Dispatch_Info_T
<TYPE
> &info
,
410 const ACE_Time_Value
&cur_time
,
411 const void *upcall_act
);
415 /// Schedule a timer.
416 virtual long schedule_i (const TYPE
&type
,
418 const ACE_Time_Value
&future_time
,
419 const ACE_Time_Value
&interval
) = 0;
421 /// Reschedule an "interval" ACE_Timer_Node.
422 virtual void reschedule (ACE_Timer_Node_T
<TYPE
> *) = 0;
424 /// Factory method that allocates a new node.
425 virtual ACE_Timer_Node_T
<TYPE
> *alloc_node (void);
427 /// Factory method that frees a previously allocated node.
428 virtual void free_node (ACE_Timer_Node_T
<TYPE
> *);
430 /// Non-locking version of dispatch_info ()
431 virtual int dispatch_info_i (const ACE_Time_Value
¤t_time
,
432 ACE_Timer_Node_Dispatch_Info_T
<TYPE
> &info
);
434 /// Synchronization variable for ACE_Timer_Queue.
435 /// @note The right name would be lock_, but HP/C++ will choke on that!
438 /// Class that implements a free list
439 ACE_Free_List
<ACE_Timer_Node_T
<TYPE
> > *free_list_
;
441 /// Pointer to function that returns the current time of day.
442 ACE_Time_Value (*gettimeofday_
)(void);
445 FUNCTOR
*upcall_functor_
;
447 /// To delete or not to delete is the question?
448 bool const delete_upcall_functor_
;
450 /// Flag to delete only if the class created the <free_list_>
451 bool const delete_free_list_
;
455 /// Returned by <calculate_timeout>.
456 ACE_Time_Value timeout_
;
458 /// Adjusts for timer skew in various clocks.
459 ACE_Time_Value timer_skew_
;
461 // = Don't allow these operations for now.
462 ACE_UNIMPLEMENTED_FUNC (ACE_Timer_Queue_T (const ACE_Timer_Queue_T
<TYPE
, FUNCTOR
, ACE_LOCK
> &))
463 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Timer_Queue_T
<TYPE
, FUNCTOR
, ACE_LOCK
> &))
467 * @class ACE_Event_Handler_Handle_Timeout_Upcall
469 * @brief Functor for Timer_Queues.
471 * This class implements the functor required by the Timer
472 * Queue to call <handle_timeout> on ACE_Event_Handlers.
474 template <class ACE_LOCK
>
475 class ACE_Event_Handler_Handle_Timeout_Upcall
478 typedef ACE_Timer_Queue_T
<ACE_Event_Handler
*,
479 ACE_Event_Handler_Handle_Timeout_Upcall
<ACE_LOCK
>,
483 // = Initialization and termination methods.
485 ACE_Event_Handler_Handle_Timeout_Upcall (void);
488 ~ACE_Event_Handler_Handle_Timeout_Upcall (void);
490 /// This method is called when a timer is registered.
491 int registration (TIMER_QUEUE
&timer_queue
,
492 ACE_Event_Handler
*handler
,
495 /// This method is called before the timer expires.
496 int preinvoke (TIMER_QUEUE
&timer_queue
,
497 ACE_Event_Handler
*handler
,
500 const ACE_Time_Value
&cur_time
,
501 const void *&upcall_act
);
503 /// This method is called when the timer expires.
504 int timeout (TIMER_QUEUE
&timer_queue
,
505 ACE_Event_Handler
*handler
,
508 const ACE_Time_Value
&cur_time
);
510 /// This method is called after the timer expires.
511 int postinvoke (TIMER_QUEUE
&timer_queue
,
512 ACE_Event_Handler
*handler
,
515 const ACE_Time_Value
&cur_time
,
516 const void *upcall_act
);
518 /// This method is called when a handler is cancelled
519 int cancel_type (TIMER_QUEUE
&timer_queue
,
520 ACE_Event_Handler
*handler
,
522 int &requires_reference_counting
);
524 /// This method is called when a timer is cancelled
525 int cancel_timer (TIMER_QUEUE
&timer_queue
,
526 ACE_Event_Handler
*handler
,
528 int requires_reference_counting
);
530 /// This method is called when the timer queue is destroyed and
531 /// the timer is still contained in it
532 int deletion (TIMER_QUEUE
&timer_queue
,
533 ACE_Event_Handler
*handler
,
538 /// Flag indicating that reference counting is required for this
539 /// event handler upcall.
540 int requires_reference_counting_
;
542 // = Don't allow these operations for now.
543 ACE_UNIMPLEMENTED_FUNC (ACE_Event_Handler_Handle_Timeout_Upcall (const ACE_Event_Handler_Handle_Timeout_Upcall
<ACE_LOCK
> &))
544 ACE_UNIMPLEMENTED_FUNC (void operator= (const ACE_Event_Handler_Handle_Timeout_Upcall
<ACE_LOCK
> &))
547 ACE_END_VERSIONED_NAMESPACE_DECL
549 #if defined (__ACE_INLINE__)
550 #include "ace/Timer_Queue_T.inl"
551 #endif /* __ACE_INLINE__ */
553 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
554 #include "ace/Timer_Queue_T.cpp"
555 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
557 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
558 #pragma implementation ("Timer_Queue_T.cpp")
559 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
561 #include /**/ "ace/post.h"
562 #endif /* ACE_TIMER_QUEUE_T_H */