Merge pull request #2309 from mitza-oci/warnings
[ACE_TAO.git] / ACE / ace / Timer_List_T.cpp
blob4935c1d821dc4f6476b99f413c238380bec23ed4
1 #ifndef ACE_TIMER_LIST_T_C
2 #define ACE_TIMER_LIST_T_C
4 #include "ace/Timer_List_T.h"
5 #include "ace/Guard_T.h"
6 #include "ace/Log_Category.h"
8 #if !defined (ACE_LACKS_PRAGMA_ONCE)
9 # pragma once
10 #endif /* ACE_LACKS_PRAGMA_ONCE */
13 // Default Constructor
15 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
16 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_List_Iterator_T (List& lst)
17 : list_ (lst)
19 this->first();
22 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
23 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_List_Iterator_T ()
27 // Positions the iterator at the node right after the dummy node
29 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
30 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::first ()
32 this->current_node_ = this->list_.get_first();
35 // Positions the iterator at the next node in the Timer Queue
37 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
38 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::next ()
40 // Make sure that if we are at the end, we don't wrap around
41 if (! this->isdone())
42 this->current_node_ = this->current_node_->get_next ();
43 if (this->current_node_ == this->list_.head_)
44 this->current_node_ = 0;
47 // Returns true when we are at <head_>
49 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> bool
50 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::isdone () const
52 return this->current_node_ == 0;
55 // Returns the node at <position_> or 0 if we are at the end
57 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
58 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::item ()
60 if (! this->isdone())
61 return this->current_node_;
62 return 0;
65 ///////////////////////////////////////////////////////////////////////////////
66 ///////////////////////////////////////////////////////////////////////////////
68 // Return our instance of the iterator
70 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Queue_Iterator_T<TYPE> &
71 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::iter ()
73 this->iterator_->first ();
74 return *this->iterator_;
77 // Create an empty list.
79 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
80 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::ACE_Timer_List_T (FUNCTOR* uf,
81 FreeList* fl,
82 TIME_POLICY const & time_policy)
83 : Base_Timer_Queue (uf, fl, time_policy)
84 , head_ (new ACE_Timer_Node_T<TYPE>)
85 , id_counter_ (0)
87 ACE_TRACE ("ACE_Timer_List_T::ACE_Timer_List_T");
89 this->head_->set_next (this->head_);
90 this->head_->set_prev (this->head_);
92 ACE_NEW (iterator_, Iterator(*this));
96 // Checks if list is empty.
98 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> bool
99 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::is_empty () const
101 ACE_TRACE ("ACE_Timer_List_T::is_empty");
102 return this->get_first_i() == 0;
106 // Returns earliest time in a non-empty list.
108 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> const ACE_Time_Value &
109 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::earliest_time () const
111 ACE_TRACE ("ACE_Timer_List_T::earliest_time");
112 ACE_Timer_Node_T<TYPE>* first = this->get_first_i();
113 if (first != 0)
114 return first->get_timer_value ();
115 return ACE_Time_Value::zero;
119 // Remove all remaining items in the list.
121 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
122 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::~ACE_Timer_List_T ()
124 ACE_TRACE ("ACE_Timer_List_T::~ACE_Timer_List_T");
125 ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));
127 delete iterator_;
129 this->close ();
131 // delete the dummy node
132 delete this->head_;
135 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
136 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::close ()
138 ACE_TRACE ("ACE_Timer_List_T::close");
139 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
141 // Remove all remaining items in the list.
142 if (!this->is_empty())
144 for (ACE_Timer_Node_T<TYPE>* n = this->get_first();
145 n != this->head_;
148 this->upcall_functor ().deletion (*this,
149 n->get_type(),
150 n->get_act());
152 ACE_Timer_Node_T<TYPE> *next =
153 n->get_next ();
155 this->free_node (n);
157 n = next;
161 // Leave rest to destructor
162 return 0;
165 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
166 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::dump () const
168 #if defined (ACE_HAS_DUMP)
169 ACE_TRACE ("ACE_Timer_List_T::dump");
170 ACELIB_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
172 int count = 0;
174 ACE_Timer_Node_T<TYPE>* n = this->get_first_i();
175 if (n != 0) {
176 for (; n != this->head_; n = n->get_next()) {
177 ++count;
181 ACELIB_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsize_ = %d"), count));
182 ACELIB_DEBUG ((LM_DEBUG, ACE_END_DUMP));
183 #endif /* ACE_HAS_DUMP */
187 // Reschedule a periodic timer. This function must be called with the
188 // lock held.
190 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
191 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reschedule (ACE_Timer_Node_T<TYPE>* n)
193 ACE_TRACE ("ACE_Timer_List_T::reschedule");
194 this->schedule_i(n, n->get_timer_value());
198 // Insert a new handler that expires at time future_time; if interval
199 // is > 0, the handler will be reinvoked periodically.
201 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> long
202 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule_i (const TYPE &type,
203 const void *act,
204 const ACE_Time_Value &future_time,
205 const ACE_Time_Value &interval)
207 ACE_TRACE ("ACE_Timer_List_T::schedule_i");
209 ACE_Timer_Node_T<TYPE>* n = this->alloc_node();
211 if (n != 0)
213 long id = this->id_counter_++;
215 if (id != -1) {
216 n->set (type, act, future_time, interval, 0, 0, id);
217 this->schedule_i (n, future_time);
219 return id;
222 // Failure return
223 errno = ENOMEM;
224 return -1;
227 /// The shared scheduling functionality between schedule() and reschedule()
228 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
229 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::schedule_i (ACE_Timer_Node_T<TYPE>* n,
230 const ACE_Time_Value& expire)
232 if (this->is_empty()) {
233 n->set_prev(this->head_);
234 n->set_next(this->head_);
235 this->head_->set_prev(n);
236 this->head_->set_next(n);
237 return;
240 // We always want to search backwards from the tail of the list, because
241 // this minimizes the search in the extreme case when lots of timers are
242 // scheduled for exactly the same time, and it also assumes that most of
243 // the timers will be scheduled later than existing timers.
244 ACE_Timer_Node_T<TYPE>* p = this->head_->get_prev();
245 while (p != this->head_ && p->get_timer_value() > expire)
246 p = p->get_prev();
248 // insert after
249 n->set_prev(p);
250 n->set_next(p->get_next());
251 p->get_next()->set_prev(n);
252 p->set_next(n);
255 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY>
256 ACE_Timer_Node_T<TYPE>*
257 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::find_node (long timer_id) const
259 ACE_Timer_Node_T<TYPE>* n = this->get_first_i();
260 if (n == 0)
261 return 0;
263 for (; n != this->head_; n = n->get_next()) {
264 if (n->get_timer_id() == timer_id) {
265 return n;
268 return 0;
271 // Locate and update the inteval on the timer_id
272 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
273 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::reset_interval (long timer_id,
274 const ACE_Time_Value &interval)
276 ACE_TRACE ("ACE_Timer_List_T::reset_interval");
277 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
278 ACE_Timer_Node_T<TYPE>* n = this->find_node(timer_id);
279 if (n != 0) {
280 n->set_interval(interval); // The interval will take effect the next time this node is expired.
281 return 0;
283 return -1;
286 // Locate and remove the single <ACE_Event_Handler> with a value of
287 // @a timer_id from the timer queue.
288 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
289 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel (long timer_id,
290 const void **act,
291 int skip_close)
293 ACE_TRACE ("ACE_Timer_List_T::cancel");
294 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
295 ACE_Timer_Node_T<TYPE>* n = this->find_node(timer_id);
296 if (n != 0)
298 if (act != 0)
299 *act = n->get_act ();
301 // Call the close hooks.
302 int cookie = 0;
304 // cancel_type() called once per <type>.
305 this->upcall_functor ().cancel_type (*this,
306 n->get_type (),
307 skip_close,
308 cookie);
310 // cancel_timer() called once per <timer>.
311 this->upcall_functor ().cancel_timer (*this,
312 n->get_type (),
313 skip_close,
314 cookie);
316 this->cancel_i (n);
318 return 1;
321 return 0;
324 // Locate and remove all values of <handler> from the timer queue.
325 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
326 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel (const TYPE &type, int skip_close)
328 ACE_TRACE ("ACE_Timer_List_T::cancel");
330 int num_canceled = 0; // Note : Technically this can overflow.
332 int cookie = 0;
334 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
336 if (!this->is_empty ())
338 for (ACE_Timer_Node_T<TYPE>* n = this->get_first();
339 n != this->head_;
342 if (n->get_type() == type) // Note: Typically Type is an ACE_Event_Handler*
344 ++num_canceled;
346 ACE_Timer_Node_T<TYPE>* tmp = n;
347 n = n->get_next();
349 this->cancel_i (tmp);
351 else
353 n = n->get_next();
358 // Call the close hooks.
360 // cancel_type() called once per <type>.
361 this->upcall_functor ().cancel_type (*this,
362 type,
363 skip_close,
364 cookie);
366 for (int i = 0;
367 i < num_canceled;
368 ++i)
370 // cancel_timer() called once per <timer>.
371 this->upcall_functor ().cancel_timer (*this,
372 type,
373 skip_close,
374 cookie);
377 return num_canceled;
380 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
381 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::unlink (ACE_Timer_Node_T<TYPE>* n)
383 n->get_prev()->set_next(n->get_next());
384 n->get_next()->set_prev(n->get_prev());
385 n->set_prev(0);
386 n->set_next(0);
389 /// Shared subset of the two cancel() methods.
390 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> void
391 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
393 this->unlink (n);
394 this->free_node (n);
397 // Reads the first node on the list and returns it.
398 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
399 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::get_first ()
401 ACE_TRACE ("ACE_Timer_List_T::get_first");
402 return this->get_first_i();
405 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
406 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::get_first_i () const
408 ACE_TRACE ("ACE_Timer_List_T::get_first_i");
409 ACE_Timer_Node_T<TYPE>* first = this->head_->get_next();
410 if (first != this->head_) // Note : is_empty() uses get_first()
411 return first;
412 return 0;
416 // Removes the first node on the list and returns it.
418 template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_Timer_Node_T<TYPE> *
419 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::remove_first ()
421 ACE_TRACE ("ACE_Timer_List_T::remove_first");
422 ACE_Timer_Node_T<TYPE>* first = this->get_first();
423 if (first != 0) {
424 this->unlink(first);
425 return first;
427 return 0;
430 #endif /* ACE_TIMER_LIST_T_C */