3 //=============================================================================
7 * @author Darrell Brunsch <brunsch@cs.wustl.edu>
9 //=============================================================================
11 #ifndef ACE_TIMER_HASH_T_H
12 #define ACE_TIMER_HASH_T_H
13 #include /**/ "ace/pre.h"
15 #include "ace/Timer_Queue_T.h"
17 #if !defined (ACE_LACKS_PRAGMA_ONCE)
19 #endif /* ACE_LACKS_PRAGMA_ONCE */
21 #include "ace/Free_List.h"
23 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
25 // Forward declaration.
26 template <class TYPE
, class FUNCTOR
, class ACE_LOCK
, class BUCKET
, typename TIME_POLICY
>
27 class ACE_Timer_Hash_T
;
28 template <typename TYPE
>
30 class ACE_Event_Handler
;
33 * @class ACE_Timer_Hash_Upcall
35 * @brief Functor for Timer_Hash
37 * This class calls up to the Timer Hash's functor from the
38 * timer queues in the hash table
40 template <class TYPE
, class FUNCTOR
, class ACE_LOCK
>
41 class ACE_Timer_Hash_Upcall
42 : private ACE_Copy_Disabled
45 typedef ACE_Timer_Queue_T
<ACE_Event_Handler
*,
46 ACE_Timer_Hash_Upcall
<TYPE
, FUNCTOR
, ACE_LOCK
>,
50 /// Default constructor (creates an invalid object, but needs to be here
51 /// so timer queues using this functor can be constructed)
52 ACE_Timer_Hash_Upcall ();
54 /// Constructor that specifies a Timer_Hash to call up to
55 ACE_Timer_Hash_Upcall (ACE_Timer_Queue_T
<TYPE
, FUNCTOR
, ACE_LOCK
> *timer_hash
);
57 /// This method is called when a timer is registered.
58 int registration (TIMER_QUEUE
&timer_queue
,
59 ACE_Event_Handler
*handler
,
62 /// This method is called before the timer expires.
63 int preinvoke (TIMER_QUEUE
&timer_queue
,
64 ACE_Event_Handler
*handler
,
67 const ACE_Time_Value
&cur_time
,
68 const void *&upcall_act
);
70 /// This method is called when the timer expires.
71 int timeout (TIMER_QUEUE
&timer_queue
,
72 ACE_Event_Handler
*handler
,
75 const ACE_Time_Value
&cur_time
);
77 /// This method is called after the timer expires.
78 int postinvoke (TIMER_QUEUE
&timer_queue
,
79 ACE_Event_Handler
*handler
,
82 const ACE_Time_Value
&cur_time
,
83 const void *upcall_act
);
85 /// This method is called when a handler is cancelled
86 int cancel_type (TIMER_QUEUE
&timer_queue
,
87 ACE_Event_Handler
*handler
,
89 int &requires_reference_counting
);
91 /// This method is called when a timer is cancelled
92 int cancel_timer (TIMER_QUEUE
&timer_queue
,
93 ACE_Event_Handler
*handler
,
95 int requires_reference_counting
);
97 /// This method is called when the timer queue is destroyed and
98 /// the timer is still contained in it
99 int deletion (TIMER_QUEUE
&timer_queue
,
100 ACE_Event_Handler
*handler
,
104 /// Timer Queue to do the calling up to
105 ACE_Timer_Queue_T
<TYPE
, FUNCTOR
, ACE_LOCK
> *timer_hash_
;
109 * @class ACE_Timer_Hash_Iterator_T
111 * @brief Iterates over an ACE_Timer_Hash_T.
113 * This is a generic iterator that can be used to visit every
114 * node of a timer queue. Be aware that it doesn't transverse
115 * in the order of timeout values.
117 template <class TYPE
, class FUNCTOR
, class ACE_LOCK
, class BUCKET
, typename TIME_POLICY
= ACE_Default_Time_Policy
>
118 class ACE_Timer_Hash_Iterator_T
: public ACE_Timer_Queue_Iterator_T
<TYPE
>
122 typedef ACE_Timer_Hash_T
<TYPE
, FUNCTOR
, ACE_LOCK
, BUCKET
, TIME_POLICY
> Hash
;
123 ACE_Timer_Hash_Iterator_T (Hash
&);
125 virtual ~ACE_Timer_Hash_Iterator_T ();
127 /// Positions the iterator at the earliest node in the Timer Queue
128 virtual void first ();
130 /// Positions the iterator at the next node in the Timer Queue
131 virtual void next ();
133 /// Returns true when there are no more nodes in the sequence
134 virtual bool isdone () const;
136 /// Returns the node at the current position in the sequence
137 virtual ACE_Timer_Node_T
<TYPE
> *item ();
140 /// Pointer to the ACE_Timer_Hash that we are iterating over.
143 /// Current position in <timer_hash_>'s table
146 /// Current iterator used on <position>'s bucket
147 ACE_Timer_Queue_Iterator_T
<TYPE
> *iter_
;
151 * @class ACE_Timer_Hash_T
153 * @brief Provides a hash table of BUCKETs as an implementation for
156 * This implementation uses a hash table of BUCKETs. The hash
157 * is based on the time_value of the event. Unlike other Timer
158 * Queues, ACE_Timer_Hash does not expire events in strict order,
159 * i.e., all events are expired after their deadline. But two events
160 * may expired out of order as defined by their deadlines.
162 template <class TYPE
, class FUNCTOR
, class ACE_LOCK
, class BUCKET
, typename TIME_POLICY
= ACE_Default_Time_Policy
>
163 class ACE_Timer_Hash_T
: public ACE_Timer_Queue_T
<TYPE
, FUNCTOR
, ACE_LOCK
, TIME_POLICY
>
167 typedef ACE_Timer_Hash_Iterator_T
<TYPE
, FUNCTOR
, ACE_LOCK
, BUCKET
, TIME_POLICY
>
170 /// Iterator is a friend
171 friend class ACE_Timer_Hash_Iterator_T
<TYPE
, FUNCTOR
, ACE_LOCK
, BUCKET
, TIME_POLICY
>;
173 /// Type inherited from
174 typedef ACE_Timer_Queue_T
<TYPE
, FUNCTOR
, ACE_LOCK
, TIME_POLICY
> Base_Timer_Queue
;
177 * Default constructor. @a table_size determines the size of the
178 * hash table. @a upcall_functor is the instance of the FUNCTOR
179 * to be used by the buckets. If @a upcall_functor is 0, a default
180 * FUNCTOR will be created.
182 ACE_Timer_Hash_T (size_t table_size
,
183 FUNCTOR
*upcall_functor
= 0,
184 ACE_Free_List
<ACE_Timer_Node_T
<TYPE
> > *freelist
= 0,
185 TIME_POLICY
const & time_policy
= TIME_POLICY());
188 * Default constructor. @a upcall_functor is the instance of the
189 * FUNCTOR to be used by the queue. If @a upcall_functor is 0, Timer
190 * Hash will create a default FUNCTOR. @a freelist the freelist of
191 * timer nodes. If 0, then a default freelist will be created. The default
192 * size will be ACE_DEFAULT_TIMERS and there will be no preallocation.
194 ACE_Timer_Hash_T (FUNCTOR
*upcall_functor
= 0,
195 ACE_Free_List
<ACE_Timer_Node_T
<TYPE
> > *freelist
= 0,
196 TIME_POLICY
const & time_policy
= TIME_POLICY());
199 virtual ~ACE_Timer_Hash_T ();
201 /// True if queue is empty, else false.
202 virtual bool is_empty () const;
204 /// Returns the time of the earlier node in the <ACE_Timer_Hash>.
205 /// Must be called on a non-empty queue.
206 virtual const ACE_Time_Value
&earliest_time () const;
209 * Resets the interval of the timer represented by @a timer_id to
210 * @a interval, which is specified in relative time to the current
211 * <gettimeofday>. If @a interval is equal to
212 * ACE_Time_Value::zero, the timer will become a non-rescheduling
213 * timer. Returns 0 if successful, -1 if not.
215 virtual int reset_interval (long timer_id
,
216 const ACE_Time_Value
&interval
);
219 * Cancel all timer associated with @a type. If <dont_call> is 0
220 * then the <functor> will be invoked. Returns number of timers
221 * cancelled. If any valid timer is not cancelled before destruction
222 * of this instance of ACE_Timer_Hash_T then user will get a memory
225 virtual int cancel (const TYPE
&type
,
226 int dont_call_handle_close
= 1);
229 * Cancel the single timer that matches the @a timer_id value (which
230 * was returned from the <schedule> method). If act is non-NULL
231 * then it will be set to point to the ``magic cookie'' argument
232 * passed in when the timer was registered. This makes it possible
233 * to free up the memory and avoid memory leaks. If
234 * @a dont_call_handle_close is 0 then the <functor> will be invoked.
235 * Returns 1 if cancellation succeeded and 0 if the @a timer_id wasn't
236 * found. If any valid timer is not cancelled before destruction of
237 * this instance of ACE_Timer_Hash_T then user will get a memory leak.
239 virtual int cancel (long timer_id
,
240 const void **act
= 0,
241 int dont_call_handle_close
= 1);
244 * Destroy timer queue. Cancels all timers.
246 virtual int close ();
249 * Run the <functor> for all timers whose values are <=
250 * gettimeofday. Also accounts for <timer_skew>. Returns
251 * the number of timers canceled.
253 virtual int expire ();
256 * Run the <functor> for all timers whose values are <= @a current_time.
257 * This does not account for <timer_skew>. Returns the number of
260 virtual int expire (const ACE_Time_Value
¤t_time
);
262 /// Returns a pointer to this ACE_Timer_Queue's iterator.
263 virtual ACE_Timer_Queue_Iterator_T
<TYPE
> &iter ();
265 /// Removes the earliest node from the queue and returns it
266 virtual ACE_Timer_Node_T
<TYPE
> *remove_first ();
268 /// Dump the state of an object.
269 virtual void dump () const;
271 /// Reads the earliest node from the queue and returns it.
272 virtual ACE_Timer_Node_T
<TYPE
> *get_first ();
275 /// Factory method that frees a previously allocated node.
276 virtual void free_node (ACE_Timer_Node_T
<TYPE
> *);
280 * Schedule @a type that will expire at @a future_time,
281 * which is specified in absolute time. If it expires then @a act is
282 * passed in as the value to the <functor>. If @a interval is != to
283 * ACE_Time_Value::zero then it is used to reschedule the @a type
284 * automatically, using relative time to the current <gettimeofday>.
285 * This method returns a <timer_id> that is a pointer to a token
286 * which stores information about the event. This <timer_id> can be
287 * used to cancel the timer before it expires. Returns -1 on
290 virtual long schedule_i (const TYPE
&type
,
292 const ACE_Time_Value
&future_time
,
293 const ACE_Time_Value
&interval
);
295 /// Non-locking version of dispatch_info ()
296 virtual int dispatch_info_i (const ACE_Time_Value
¤t_time
,
297 ACE_Timer_Node_Dispatch_Info_T
<TYPE
> &info
);
299 /// Reschedule an "interval" ACE_Timer_Node.
300 virtual void reschedule (ACE_Timer_Node_T
<TYPE
> *);
302 /// Finds the earliest node
303 void find_new_earliest ();
305 /// Keeps track of the size of the queue
311 /// Keeps track of the size of table_
314 /// Functor used for the table's timer queues
315 ACE_Timer_Hash_Upcall
<TYPE
, FUNCTOR
, ACE_LOCK
> table_functor_
;
317 /// Index to the position with the earliest entry
318 size_t earliest_position_
;
320 /// Iterator used to expire timers.
321 HASH_ITERATOR
*iterator_
;
323 #if defined (ACE_WIN64)
324 /// Part of a hack... see comments in schedule().
325 /// This is, essentially, the upper 32 bits of a 64-bit pointer on Win64.
326 ptrdiff_t pointer_base_
;
329 /// Hash_Token is usually allocated in schedule but its
330 /// deallocation is problematic and token_list_ helps with this.
331 ACE_Locked_Free_List
<Hash_Token
<TYPE
>, ACE_Null_Mutex
> token_list_
;
333 // = Don't allow these operations for now.
334 ACE_Timer_Hash_T (const ACE_Timer_Hash_T
<TYPE
, FUNCTOR
, ACE_LOCK
, BUCKET
> &) = delete;
335 void operator= (const ACE_Timer_Hash_T
<TYPE
, FUNCTOR
, ACE_LOCK
, BUCKET
> &) = delete;
338 ACE_END_VERSIONED_NAMESPACE_DECL
340 #include "ace/Timer_Hash_T.cpp"
342 #include /**/ "ace/post.h"
343 #endif /* ACE_TIMER_HASH_T_H */