Initial Patch of Auction House bot rev. 135
[auctionmangos.git] / dep / ACE_wrappers / ace / Timer_List_T.cpp
blobc3b837bb2899da462a0fadfac65a8c28a3a2658d
1 // $Id: Timer_List_T.cpp 80826 2008-03-04 14:51:23Z wotte $
3 #ifndef ACE_TIMER_LIST_T_C
4 #define ACE_TIMER_LIST_T_C
6 #include "ace/Timer_List_T.h"
7 #include "ace/Guard_T.h"
8 #include "ace/Log_Msg.h"
10 #if !defined (ACE_LACKS_PRAGMA_ONCE)
11 # pragma once
12 #endif /* ACE_LACKS_PRAGMA_ONCE */
14 ACE_RCSID(ace, Timer_List_T, "$Id: Timer_List_T.cpp 80826 2008-03-04 14:51:23Z wotte $")
16 // Default Constructor
18 template <class TYPE, class FUNCTOR, class ACE_LOCK>
19 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_List_Iterator_T (List& lst)
20 : list_ (lst)
22 this->first();
25 template <class TYPE, class FUNCTOR, class ACE_LOCK>
26 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_List_Iterator_T (void)
30 // Positions the iterator at the node right after the dummy node
32 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
33 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::first (void)
35 this->current_node_ = this->list_.get_first();
38 // Positions the iterator at the next node in the Timer Queue
40 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
41 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
43 // Make sure that if we are at the end, we don't wrap around
44 if (! this->isdone())
45 this->current_node_ = this->current_node_->get_next ();
46 if (this->current_node_ == this->list_.head_)
47 this->current_node_ = 0;
50 // Returns true when we are at <head_>
52 template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
53 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::isdone (void) const
55 return this->current_node_ == 0;
58 // Returns the node at <position_> or 0 if we are at the end
60 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
61 ACE_Timer_List_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
63 if (! this->isdone())
64 return this->current_node_;
65 return 0;
68 ///////////////////////////////////////////////////////////////////////////////
69 ///////////////////////////////////////////////////////////////////////////////
71 // Return our instance of the iterator
73 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
74 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
76 this->iterator_->first ();
77 return *this->iterator_;
80 // Create an empty list.
82 template <class TYPE, class FUNCTOR, class ACE_LOCK>
83 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_List_T (FUNCTOR* uf, FreeList* fl)
84 : Base(uf, fl)
85 , head_ (new ACE_Timer_Node_T<TYPE>)
86 , id_counter_ (0)
88 ACE_TRACE ("ACE_Timer_List_T::ACE_Timer_List_T");
90 this->head_->set_next (this->head_);
91 this->head_->set_prev (this->head_);
93 ACE_NEW (iterator_, Iterator(*this));
97 // Checks if list is empty.
99 template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
100 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
102 ACE_TRACE ("ACE_Timer_List_T::is_empty");
103 return this->get_first_i() == 0;
107 // Returns earliest time in a non-empty list.
109 template <class TYPE, class FUNCTOR, class ACE_LOCK> const ACE_Time_Value &
110 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
112 ACE_TRACE ("ACE_Timer_List_T::earliest_time");
113 ACE_Timer_Node_T<TYPE>* first = this->get_first_i();
114 if (first != 0)
115 return first->get_timer_value ();
116 return ACE_Time_Value::zero;
120 // Remove all remaining items in the list.
122 template <class TYPE, class FUNCTOR, class ACE_LOCK>
123 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_List_T (void)
125 ACE_TRACE ("ACE_Timer_List_T::~ACE_Timer_List_T");
126 ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));
128 delete iterator_;
130 if (!this->is_empty())
132 for (ACE_Timer_Node_T<TYPE>* n = this->get_first();
133 n != this->head_;
136 this->upcall_functor ().deletion (*this,
137 n->get_type(),
138 n->get_act());
140 ACE_Timer_Node_T<TYPE> *next =
141 n->get_next ();
143 this->free_node (n);
145 n = next;
149 // delete the dummy node
150 delete this->head_;
153 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
154 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
156 #if defined (ACE_HAS_DUMP)
157 ACE_TRACE ("ACE_Timer_List_T::dump");
158 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
160 int count = 0;
162 ACE_Timer_Node_T<TYPE>* n = this->get_first_i();
163 if (n != 0) {
164 for (; n != this->head_; n = n->get_next()) {
165 ++count;
169 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nsize_ = %d"), count));
170 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
171 #endif /* ACE_HAS_DUMP */
175 // Reschedule a periodic timer. This function must be called with the
176 // lock held.
178 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
179 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (ACE_Timer_Node_T<TYPE>* n)
181 ACE_TRACE ("ACE_Timer_List_T::reschedule");
182 this->schedule_i(n, n->get_timer_value());
186 // Insert a new handler that expires at time future_time; if interval
187 // is > 0, the handler will be reinvoked periodically.
189 template <class TYPE, class FUNCTOR, class ACE_LOCK> long
190 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (const TYPE &type,
191 const void *act,
192 const ACE_Time_Value &future_time,
193 const ACE_Time_Value &interval)
195 ACE_TRACE ("ACE_Timer_List_T::schedule_i");
197 ACE_Timer_Node_T<TYPE>* n = this->alloc_node();
199 if (n != 0)
201 long id = this->id_counter_++;
203 if (id != -1) {
204 n->set (type, act, future_time, interval, 0, 0, id);
205 this->schedule_i (n, future_time);
207 return id;
210 // Failure return
211 errno = ENOMEM;
212 return -1;
215 /// The shared scheduling functionality between schedule() and reschedule()
216 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
217 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (ACE_Timer_Node_T<TYPE>* n,
218 const ACE_Time_Value& expire)
220 if (this->is_empty()) {
221 n->set_prev(this->head_);
222 n->set_next(this->head_);
223 this->head_->set_prev(n);
224 this->head_->set_next(n);
225 return;
228 // We always want to search backwards from the tail of the list, because
229 // this minimizes the search in the extreme case when lots of timers are
230 // scheduled for exactly the same time, and it also assumes that most of
231 // the timers will be scheduled later than existing timers.
232 ACE_Timer_Node_T<TYPE>* p = this->head_->get_prev();
233 while (p != this->head_ && p->get_timer_value() > expire)
234 p = p->get_prev();
236 // insert after
237 n->set_prev(p);
238 n->set_next(p->get_next());
239 p->get_next()->set_prev(n);
240 p->set_next(n);
243 template <class TYPE, class FUNCTOR, class ACE_LOCK>
244 ACE_Timer_Node_T<TYPE>*
245 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::find_node (long timer_id) const
247 ACE_Timer_Node_T<TYPE>* n = this->get_first_i();
248 if (n == 0)
249 return 0;
251 for (; n != this->head_; n = n->get_next()) {
252 if (n->get_timer_id() == timer_id) {
253 return n;
256 return 0;
259 // Locate and update the inteval on the timer_id
260 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
261 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
262 const ACE_Time_Value &interval)
264 ACE_TRACE ("ACE_Timer_List_T::reset_interval");
265 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
266 ACE_Timer_Node_T<TYPE>* n = this->find_node(timer_id);
267 if (n != 0) {
268 n->set_interval(interval); // The interval will take effect the next time this node is expired.
269 return 0;
271 return -1;
274 // Locate and remove the single <ACE_Event_Handler> with a value of
275 // @a timer_id from the timer queue.
276 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
277 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
278 const void **act,
279 int skip_close)
281 ACE_TRACE ("ACE_Timer_List_T::cancel");
282 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
283 ACE_Timer_Node_T<TYPE>* n = this->find_node(timer_id);
284 if (n != 0)
286 if (act != 0)
287 *act = n->get_act ();
289 // Call the close hooks.
290 int cookie = 0;
292 // cancel_type() called once per <type>.
293 this->upcall_functor ().cancel_type (*this,
294 n->get_type (),
295 skip_close,
296 cookie);
298 // cancel_timer() called once per <timer>.
299 this->upcall_functor ().cancel_timer (*this,
300 n->get_type (),
301 skip_close,
302 cookie);
304 this->cancel_i (n);
306 return 1;
309 return 0;
312 // Locate and remove all values of <handler> from the timer queue.
313 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
314 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE &type, int skip_close)
316 ACE_TRACE ("ACE_Timer_List_T::cancel");
318 int num_canceled = 0; // Note : Technically this can overflow.
320 int cookie = 0;
322 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
324 if (!this->is_empty ())
326 for (ACE_Timer_Node_T<TYPE>* n = this->get_first();
327 n != this->head_;
330 if (n->get_type() == type) // Note: Typically Type is an ACE_Event_Handler*
332 ++num_canceled;
334 ACE_Timer_Node_T<TYPE>* tmp = n;
335 n = n->get_next();
337 this->cancel_i (tmp);
339 else
341 n = n->get_next();
346 // Call the close hooks.
348 // cancel_type() called once per <type>.
349 this->upcall_functor ().cancel_type (*this,
350 type,
351 skip_close,
352 cookie);
354 for (int i = 0;
355 i < num_canceled;
356 ++i)
358 // cancel_timer() called once per <timer>.
359 this->upcall_functor ().cancel_timer (*this,
360 type,
361 skip_close,
362 cookie);
365 return num_canceled;
368 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
369 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::unlink (ACE_Timer_Node_T<TYPE>* n)
371 n->get_prev()->set_next(n->get_next());
372 n->get_next()->set_prev(n->get_prev());
373 n->set_prev(0);
374 n->set_next(0);
377 /// Shared subset of the two cancel() methods.
378 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
379 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
381 this->unlink (n);
382 this->free_node (n);
385 // Reads the first node on the list and returns it.
386 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
387 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::get_first (void)
389 ACE_TRACE ("ACE_Timer_List_T::get_first");
390 return this->get_first_i();
393 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
394 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
396 ACE_TRACE ("ACE_Timer_List_T::get_first_i");
397 ACE_Timer_Node_T<TYPE>* first = this->head_->get_next();
398 if (first != this->head_) // Note : is_empty() uses get_first()
399 return first;
400 return 0;
404 // Removes the first node on the list and returns it.
406 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
407 ACE_Timer_List_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
409 ACE_TRACE ("ACE_Timer_List_T::remove_first");
410 ACE_Timer_Node_T<TYPE>* first = this->get_first();
411 if (first != 0) {
412 this->unlink(first);
413 return first;
415 return 0;
418 #endif /* ACE_TIMER_LIST_T_C */