1
// Timer_Heap_T.cpp,v 4.70 2003/11/05 23:30:47 shuston Exp
3
#ifndef ACE_TIMER_HEAP_T_C
4
#define ACE_TIMER_HEAP_T_C
6
#include "ace/Timer_Heap_T.h"
7
#include "ace/Log_Msg.h"
8
#include "ace/Guard_T.h"
9
#include "ace/OS_NS_string.h"
11
#if !defined (ACE_LACKS_PRAGMA_ONCE)
13
#endif /* ACE_LACKS_PRAGMA_ONCE */
15
ACE_RCSID(ace, Timer_Heap_T, "Timer_Heap_T.cpp,v 4.70 2003/11/05 23:30:47 shuston Exp")
17
// Define some simple macros to clarify the code.
18
#define ACE_HEAP_PARENT(X) (X == 0 ? 0 : (((X) - 1) / 2))
19
#define ACE_HEAP_LCHILD(X) (((X)+(X))+1)
21
// Constructor that takes in an <ACE_Timer_Heap_T> to iterate over.
23
template <class TYPE, class FUNCTOR, class ACE_LOCK>
24
ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_Iterator_T (ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK> &heap)
27
ACE_TRACE ("ACE_Timer_Heap_Iterator_T::ACE_Timer_Heap_Iterator");
31
template <class TYPE, class FUNCTOR, class ACE_LOCK>
32
ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Heap_Iterator_T (void)
36
// Positions the iterator at the first node in the heap array
38
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
39
ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::first (void)
44
// Positions the iterator at the next node in the heap array
46
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
47
ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
49
if (this->position_ != this->timer_heap_.cur_size_)
53
// Returns true the <position_> is at the end of the heap array
55
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
56
ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::isdone (void) const
58
return this->position_ == this->timer_heap_.cur_size_;
61
// Returns the node at the current position in the heap or 0 if at the end
63
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
64
ACE_Timer_Heap_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
66
if (this->position_ != this->timer_heap_.cur_size_)
67
return this->timer_heap_.heap_[this->position_];
72
// Note that timer_ids_curr_ and timer_ids_min_free_ both start at 0.
73
// Since timer IDs are assigned by first incrementing the timer_ids_curr_
74
// value, the first ID assigned will be 1 (just as in the previous design).
75
// When it's time to wrap, the next ID given out will be 0.
76
template <class TYPE, class FUNCTOR, class ACE_LOCK>
77
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_T (size_t size,
79
FUNCTOR *upcall_functor,
80
ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
81
: ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK> (upcall_functor, freelist),
86
timer_ids_min_free_ (0),
87
preallocated_nodes_ (0),
88
preallocated_nodes_freelist_ (0)
90
ACE_TRACE ("ACE_Timer_Heap_T::ACE_Timer_Heap_T");
92
// Create the heap array.
94
ACE_Timer_Node_T<TYPE> *[size]);
96
// Create the parallel
97
ACE_NEW (this->timer_ids_,
100
// Initialize the "freelist," which uses negative values to
101
// distinguish freelist elements from "pointers" into the <heap_>
103
for (size_t i = 0; i < size; i++)
104
this->timer_ids_[i] = -1;
108
ACE_NEW (this->preallocated_nodes_,
109
ACE_Timer_Node_T<TYPE>[size]);
111
// Add allocated array to set of such arrays for deletion on
113
this->preallocated_node_set_.insert (this->preallocated_nodes_);
115
// Form the freelist by linking the next_ pointers together.
116
for (size_t j = 1; j < size; j++)
117
this->preallocated_nodes_[j - 1].set_next (&this->preallocated_nodes_[j]);
119
// NULL-terminate the freelist.
120
this->preallocated_nodes_[size - 1].set_next (0);
122
// Assign the freelist pointer to the front of the list.
123
this->preallocated_nodes_freelist_ =
124
&this->preallocated_nodes_[0];
128
HEAP_ITERATOR (*this));
131
// Note that timer_ids_curr_ and timer_ids_min_free_ both start at 0.
132
// Since timer IDs are assigned by first incrementing the timer_ids_curr_
133
// value, the first ID assigned will be 1 (just as in the previous design).
134
// When it's time to wrap, the next ID given out will be 0.
135
template <class TYPE, class FUNCTOR, class ACE_LOCK>
136
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Heap_T (FUNCTOR *upcall_functor,
137
ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
138
: ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK> (upcall_functor, freelist),
139
max_size_ (ACE_DEFAULT_TIMERS),
143
timer_ids_min_free_ (0),
144
preallocated_nodes_ (0),
145
preallocated_nodes_freelist_ (0)
147
ACE_TRACE ("ACE_Timer_Heap_T::ACE_Timer_Heap_T");
149
// Create the heap array.
150
#if defined (__IBMCPP__) && (__IBMCPP__ >= 400) && defined (_WINDOWS)
151
ACE_NEW (this->heap_,
152
ACE_Timer_Node_T<TYPE> *[ACE_DEFAULT_TIMERS]);
154
ACE_NEW (this->heap_,
155
ACE_Timer_Node_T<TYPE> *[this->max_size_]);
156
#endif /* defined (__IBMCPP__) && (__IBMCPP__ >= 400) && defined (_WINDOWS) */
158
// Create the parallel array.
159
ACE_NEW (this->timer_ids_,
160
ssize_t[this->max_size_]);
162
// Initialize the "freelist," which uses negative values to
163
// distinguish freelist elements from "pointers" into the <heap_>
165
for (size_t i = 0; i < this->max_size_; i++)
166
this->timer_ids_[i] = -1;
169
HEAP_ITERATOR (*this));
172
template <class TYPE, class FUNCTOR, class ACE_LOCK>
173
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Heap_T (void)
175
ACE_TRACE ("ACE_Timer_Heap_T::~ACE_Timer_Heap_T");
179
size_t current_size =
182
// Clean up all the nodes still in the queue
183
for (size_t i = 0; i < current_size; i++)
185
this->upcall_functor ().deletion (*this,
186
this->heap_[i]->get_type (),
187
this->heap_[i]->get_act ());
188
this->free_node (this->heap_[i]);
191
delete [] this->heap_;
192
delete [] this->timer_ids_;
194
// clean up any preallocated timer nodes
195
if (preallocated_nodes_ != 0)
197
ACE_Unbounded_Set_Iterator<ACE_Timer_Node_T<TYPE> *>
198
set_iterator (this->preallocated_node_set_);
200
for (ACE_Timer_Node_T<TYPE> **entry = 0;
201
set_iterator.next (entry) !=0;
202
set_iterator.advance ())
207
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
208
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::pop_freelist (void)
210
ACE_TRACE ("ACE_Timer_Heap_T::pop_freelist");
212
// Scan for a free timer ID. Note that since this function is called
213
// _after_ the check for a full timer heap, we are guaranteed to find
214
// a free ID, even if we need to wrap around and start reusing freed IDs.
215
// On entry, the curr_ index is at the previous ID given out; start
216
// up where we left off last time.
217
// NOTE - a timer_ids_ slot with -2 is out of the heap, but not freed.
218
// It must be either freed (free_node) or rescheduled (reschedule).
219
++this->timer_ids_curr_;
220
while (this->timer_ids_curr_ < this->max_size_ &&
221
(this->timer_ids_[this->timer_ids_curr_] >= 0 ||
222
this->timer_ids_[this->timer_ids_curr_] == -2 ))
223
++this->timer_ids_curr_;
224
if (this->timer_ids_curr_ == this->max_size_)
226
ACE_ASSERT (this->timer_ids_min_free_ < this->max_size_);
227
this->timer_ids_curr_ = this->timer_ids_min_free_;
228
// We restarted the free search at min. Since min won't be
229
// free anymore, and curr_ will just keep marching up the list
230
// on each successive need for an ID, reset min_free_ to the
231
// size of the list until an ID is freed that curr_ has already
232
// gone past (see push_freelist).
233
this->timer_ids_min_free_ = this->max_size_;
236
// We need to truncate this to <int> for backwards compatibility.
237
int new_id = ACE_static_cast (int,
238
this->timer_ids_curr_);
242
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
243
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::push_freelist (int old_id)
245
ACE_TRACE ("ACE_Timer_Heap_T::push_freelist");
247
// Since this ID has already been checked by one of the public
248
// functions, it's safe to cast it here.
249
size_t oldid = size_t (old_id);
251
// The freelist values in the <timer_ids_> are negative, so set the
252
// freed entry back to 'free'. If this is the new lowest value free
253
// timer ID that curr_ won't see on it's normal march through the list,
255
ACE_ASSERT (this->timer_ids_[oldid] >= 0 || this->timer_ids_[oldid] == -2);
256
if (this->timer_ids_[oldid] == -2)
260
this->timer_ids_[oldid] = -1;
261
if (oldid < this->timer_ids_min_free_ && oldid <= this->timer_ids_curr_)
262
this->timer_ids_min_free_ = oldid;
266
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
267
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::timer_id (void)
269
ACE_TRACE ("ACE_Timer_Heap_T::timer_id");
271
// Return the next item off the freelist and use it as the timer id.
272
return this->pop_freelist ();
275
// Checks if queue is empty.
277
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
278
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
280
ACE_TRACE ("ACE_Timer_Heap_T::is_empty");
281
return this->cur_size_ == 0;
284
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
285
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
287
this->iterator_->first ();
288
return *this->iterator_;
291
// Returns earliest time in a non-empty queue.
293
template <class TYPE, class FUNCTOR, class ACE_LOCK> const ACE_Time_Value &
294
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
296
ACE_TRACE ("ACE_Timer_Heap_T::earliest_time");
297
return this->heap_[0]->get_timer_value ();
300
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
301
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
303
#if defined (ACE_HAS_DUMP)
304
ACE_TRACE ("ACE_Timer_Heap_T::dump");
305
ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
307
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nmax_size_ = %d"), this->max_size_));
308
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncur_size_ = %d"), this->cur_size_));
309
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncur_limbo_= %d"), this->cur_limbo_));
310
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nids_curr_ = %d"),
311
this->timer_ids_curr_));
312
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nmin_free_ = %d"),
313
this->timer_ids_min_free_));
315
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nheap_ = \n")));
317
for (size_t i = 0; i < this->cur_size_; i++)
319
ACE_DEBUG ((LM_DEBUG,
320
ACE_LIB_TEXT ("%d\n"),
322
this->heap_[i]->dump ();
325
ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntimer_ids_ = \n")));
327
for (size_t j = 0; j < this->max_size_; j++)
328
ACE_DEBUG ((LM_DEBUG,
329
ACE_LIB_TEXT ("%d\t%d\n"),
331
this->timer_ids_[j]));
333
ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
334
#endif /* ACE_HAS_DUMP */
337
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
338
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::copy (size_t slot,
339
ACE_Timer_Node_T<TYPE> *moved_node)
341
// Insert <moved_node> into its new location in the heap.
342
this->heap_[slot] = moved_node;
344
ACE_ASSERT (moved_node->get_timer_id () >= 0
345
&& moved_node->get_timer_id () < (int) this->max_size_);
347
// Update the corresponding slot in the parallel <timer_ids_> array.
348
this->timer_ids_[moved_node->get_timer_id ()] = slot;
351
// Remove the slot'th timer node from the heap, but do not reclaim its
352
// timer ID or change the size of this timer heap object. The caller of
353
// this function must call either free_node (to reclaim the timer ID
354
// and the timer node memory, as well as decrement the size of the queue)
355
// or reschedule (to reinsert the node in the heap at a new time).
356
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
357
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::remove (size_t slot)
359
ACE_Timer_Node_T<TYPE> *removed_node =
362
// NOTE - the cur_size_ is being decremented since the queue has one
363
// less active timer in it. However, this ACE_Timer_Node is not being
364
// freed, and there is still a place for it in timer_ids_ (the timer ID
365
// is not being relinquished). The node can still be rescheduled, or
366
// it can be freed via free_node.
369
// Only try to reheapify if we're not deleting the last entry.
371
if (slot < this->cur_size_)
373
ACE_Timer_Node_T<TYPE> *moved_node =
374
this->heap_[this->cur_size_];
376
// Move the end node to the location being removed and update
377
// the corresponding slot in the parallel <timer_ids> array.
378
this->copy (slot, moved_node);
380
// If the <moved_node->time_value_> is great than or equal its
381
// parent it needs be moved down the heap.
382
size_t parent = ACE_HEAP_PARENT (slot);
384
if (moved_node->get_timer_value ()
385
>= this->heap_[parent]->get_timer_value ())
386
this->reheap_down (moved_node,
388
ACE_HEAP_LCHILD (slot));
390
this->reheap_up (moved_node,
395
this->timer_ids_[removed_node->get_timer_id ()] = -2;
400
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
401
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reheap_down (ACE_Timer_Node_T<TYPE> *moved_node,
405
// Restore the heap property after a deletion.
407
while (child < this->cur_size_)
409
// Choose the smaller of the two children.
410
if (child + 1 < this->cur_size_
411
&& this->heap_[child + 1]->get_timer_value ()
412
< this->heap_[child]->get_timer_value ())
415
// Perform a <copy> if the child has a larger timeout value than
417
if (this->heap_[child]->get_timer_value ()
418
< moved_node->get_timer_value ())
423
child = ACE_HEAP_LCHILD (child);
426
// We've found our location in the heap.
430
this->copy (slot, moved_node);
433
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
434
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reheap_up (ACE_Timer_Node_T<TYPE> *moved_node,
438
// Restore the heap property after an insertion.
442
// If the parent node is greater than the <moved_node> we need
444
if (moved_node->get_timer_value ()
445
< this->heap_[parent]->get_timer_value ())
447
this->copy (slot, this->heap_[parent]);
449
parent = ACE_HEAP_PARENT (slot);
455
// Insert the new node into its proper resting place in the heap and
456
// update the corresponding slot in the parallel <timer_ids> array.
461
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
462
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::insert (ACE_Timer_Node_T<TYPE> *new_node)
464
if (this->cur_size_ + this->cur_limbo_ + 2 >= this->max_size_)
467
this->reheap_up (new_node,
469
ACE_HEAP_PARENT (this->cur_size_));
473
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
474
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::grow_heap (void)
476
// All the containers will double in size from max_size_
477
size_t new_size = this->max_size_ * 2;
479
// First grow the heap itself.
481
ACE_Timer_Node_T<TYPE> **new_heap = 0;
483
#if defined (__IBMCPP__) && (__IBMCPP__ >= 400) && defined (_WINDOWS)
485
ACE_Timer_Node_T<TYPE> *[1024]);
488
ACE_Timer_Node_T<TYPE> *[new_size]);
489
#endif /* defined (__IBMCPP__) && (__IBMCPP__ >= 400) && defined (_WINDOWS) */
490
ACE_OS::memcpy (new_heap,
492
this->max_size_ * sizeof *new_heap);
493
delete [] this->heap_;
494
this->heap_ = new_heap;
496
// Grow the array of timer ids.
498
ssize_t *new_timer_ids = 0;
500
ACE_NEW (new_timer_ids,
503
ACE_OS::memcpy (new_timer_ids,
505
this->max_size_ * sizeof (ssize_t));
507
delete [] timer_ids_;
508
this->timer_ids_ = new_timer_ids;
510
// And add the new elements to the end of the "freelist".
511
for (size_t i = this->max_size_; i < new_size; i++)
512
this->timer_ids_[i] = -(ACE_static_cast (ssize_t, i) + 1);
514
// Grow the preallocation array (if using preallocation)
515
if (this->preallocated_nodes_ != 0)
517
// Create a new array with max_size elements to link in to
519
#if defined (__IBMCPP__) && (__IBMCPP__ >= 400) && defined (_WINDOWS)
520
ACE_NEW (this->preallocated_nodes_,
521
ACE_Timer_Node_T<TYPE>[88]);
523
ACE_NEW (this->preallocated_nodes_,
524
ACE_Timer_Node_T<TYPE>[this->max_size_]);
525
#endif /* defined (__IBMCPP__) && (__IBMCPP__ >= 400) && defined (_WINDOWS) */
527
// Add it to the set for later deletion
528
this->preallocated_node_set_.insert (this->preallocated_nodes_);
530
// Link new nodes together (as for original list).
531
for (size_t k = 1; k < this->max_size_; k++)
532
this->preallocated_nodes_[k - 1].set_next (&this->preallocated_nodes_[k]);
534
// NULL-terminate the new list.
535
this->preallocated_nodes_[this->max_size_ - 1].set_next (0);
537
// Link new array to the end of the existling list.
538
if (this->preallocated_nodes_freelist_ == 0)
539
this->preallocated_nodes_freelist_ =
540
&preallocated_nodes_[0];
543
ACE_Timer_Node_T<TYPE> *previous =
544
this->preallocated_nodes_freelist_;
546
for (ACE_Timer_Node_T<TYPE> *current = this->preallocated_nodes_freelist_->get_next ();
548
current = current->get_next ())
551
previous->set_next (&this->preallocated_nodes_[0]);
555
this->max_size_ = new_size;
558
// Reschedule a periodic timer. This function must be called with the
561
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
562
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (ACE_Timer_Node_T<TYPE> *expired)
564
ACE_TRACE ("ACE_Timer_Heap_T::reschedule");
566
// If we are rescheduling, then the most recent call was to
567
// remove_first (). That called remove () to remove the node from the
568
// heap, but did not free the timer ID. The ACE_Timer_Node still has
569
// its assigned ID - just needs to be inserted at the new proper
570
// place, and the heap restored properly.
571
if (this->timer_ids_[expired->get_timer_id ()] == -2)
573
this->insert (expired);
576
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
577
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::alloc_node (void)
579
ACE_Timer_Node_T<TYPE> *temp = 0;
581
// Only allocate a node if we are *not* using the preallocated heap.
582
if (this->preallocated_nodes_ == 0)
583
ACE_NEW_RETURN (temp,
584
ACE_Timer_Node_T<TYPE>,
588
// check to see if the heap needs to grow
589
if (this->preallocated_nodes_freelist_ == 0)
592
temp = this->preallocated_nodes_freelist_;
594
// Remove the first element from the freelist.
595
this->preallocated_nodes_freelist_ =
596
this->preallocated_nodes_freelist_->get_next ();
601
template <class TYPE, class FUNCTOR, class ACE_LOCK> void
602
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::free_node (ACE_Timer_Node_T<TYPE> *node)
604
// Return this timer id to the freelist.
605
this->push_freelist (node->get_timer_id ());
607
// Only free up a node if we are *not* using the preallocated heap.
608
if (this->preallocated_nodes_ == 0)
612
node->set_next (this->preallocated_nodes_freelist_);
613
this->preallocated_nodes_freelist_ = node;
617
// Insert a new timer that expires at time future_time; if interval is
618
// > 0, the handler will be reinvoked periodically.
620
template <class TYPE, class FUNCTOR, class ACE_LOCK> long
621
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (const TYPE &type,
623
const ACE_Time_Value &future_time,
624
const ACE_Time_Value &interval)
626
ACE_TRACE ("ACE_Timer_Heap_T::schedule_i");
628
if ((this->cur_size_ + this->cur_limbo_) < this->max_size_)
630
// Obtain the next unique sequence number.
631
int timer_id = this->timer_id ();
633
// Obtain the memory to the new node.
634
ACE_Timer_Node_T<TYPE> *temp = 0;
636
ACE_ALLOCATOR_RETURN (temp,
653
// Locate and remove the single timer with a value of <timer_id> from
656
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
657
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
661
ACE_TRACE ("ACE_Timer_Heap_T::cancel");
662
ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
664
// Locate the ACE_Timer_Node that corresponds to the timer_id.
666
// Check to see if the timer_id is out of range
668
|| (size_t) timer_id > this->max_size_)
671
ssize_t timer_node_slot = this->timer_ids_[timer_id];
673
// Check to see if timer_id is still valid.
674
if (timer_node_slot < 0)
677
if (timer_id != this->heap_[timer_node_slot]->get_timer_id ())
679
ACE_ASSERT (timer_id == this->heap_[timer_node_slot]->get_timer_id ());
684
ACE_Timer_Node_T<TYPE> *temp =
685
this->remove (timer_node_slot);
687
// Call the close hooks.
690
// cancel_type() called once per <type>.
691
this->upcall_functor ().cancel_type (*this,
696
// cancel_timer() called once per <timer>.
697
this->upcall_functor ().cancel_timer (*this,
703
*act = temp->get_act ();
705
this->free_node (temp);
710
// Locate and update the inteval on the timer_id
712
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
713
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
714
const ACE_Time_Value &interval)
716
ACE_TRACE ("ACE_Timer_Heap_T::reset_interval");
717
ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
719
// Locate the ACE_Timer_Node that corresponds to the timer_id.
721
// Check to see if the timer_id is out of range
723
|| (size_t) timer_id > this->max_size_)
726
ssize_t timer_node_slot = this->timer_ids_[timer_id];
728
// Check to see if timer_id is still valid.
729
if (timer_node_slot < 0)
732
if (timer_id != this->heap_[timer_node_slot]->get_timer_id ())
734
ACE_ASSERT (timer_id == this->heap_[timer_node_slot]->get_timer_id ());
739
// Reset the timer interval
740
this->heap_[timer_node_slot]->set_interval (interval);
745
// Locate and remove all values of <type> from the timer queue.
747
template <class TYPE, class FUNCTOR, class ACE_LOCK> int
748
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE &type,
751
ACE_TRACE ("ACE_Timer_Heap_T::cancel");
752
ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
754
int number_of_cancellations = 0;
756
// Try to locate the ACE_Timer_Node that matches the timer_id.
758
for (size_t i = 0; i < this->cur_size_; )
760
if (this->heap_[i]->get_type () == type)
762
ACE_Timer_Node_T<TYPE> *temp = this->remove (i);
764
number_of_cancellations++;
766
this->free_node (temp);
772
// Call the close hooks.
775
// cancel_type() called once per <type>.
776
this->upcall_functor ().cancel_type (*this,
782
j < number_of_cancellations;
785
// cancel_timer() called once per <timer>.
786
this->upcall_functor ().cancel_timer (*this,
792
return number_of_cancellations;
795
// Returns the earliest node or returns 0 if the heap is empty.
797
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T <TYPE> *
798
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
800
ACE_TRACE ("ACE_Timer_Heap_T::remove_first");
802
if (this->cur_size_ == 0)
805
return this->remove (0);
808
template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T <TYPE> *
809
ACE_Timer_Heap_T<TYPE, FUNCTOR, ACE_LOCK>::get_first (void)
811
ACE_TRACE ("ACE_Timer_Heap_T::get_first");
813
return this->cur_size_ == 0 ? 0 : this->heap_[0];
816
#endif /* ACE_TIMER_HEAP_T_C */