00001
00002
00003 #ifndef ACE_TIMER_HASH_T_CPP
00004 #define ACE_TIMER_HASH_T_CPP
00005
00006 #include "ace/Timer_Hash_T.h"
00007
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif
00011
00012 #include "ace/OS_NS_sys_time.h"
00013 #include "ace/Guard_T.h"
00014 #include "ace/Log_Msg.h"
00015
00016 ACE_RCSID(ace,
00017 Timer_Hash_T,
00018 "$Id: Timer_Hash_T.cpp 89254 2010-02-25 22:10:39Z cleeland $")
00019
00020 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00021
00022 template <class TYPE>
00023 class Hash_Token
00024 {
00025 public:
00026
00027 Hash_Token (void)
00028 {}
00029
00030 Hash_Token<TYPE> *get_next (void)
00031 {
00032 return this->next_;
00033 }
00034
00035 void set_next (Hash_Token<TYPE> *next)
00036 {
00037 this->next_ = next;
00038 }
00039
00040 void set (const void *act,
00041 size_t pos,
00042 long orig_id,
00043 const TYPE &type)
00044 {
00045 this->act_ = act;
00046 this->pos_ = pos;
00047 this->orig_id_ = orig_id;
00048 this->type_ = type;
00049 this->next_ = 0;
00050 }
00051
00052 const void *act_;
00053 size_t pos_;
00054 long orig_id_;
00055 TYPE type_;
00056
00057 Hash_Token<TYPE> *next_;
00058 };
00059
00060
00061
00062 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00063 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Hash_Upcall (void)
00064 : timer_hash_ (0)
00065 {
00066
00067 }
00068
00069
00070
00071 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00072 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Hash_Upcall (
00073 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> *timer_hash)
00074 : timer_hash_ (timer_hash)
00075 {
00076
00077 }
00078
00079 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00080 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::registration (
00081 TIMER_QUEUE &,
00082 ACE_Event_Handler *,
00083 const void *)
00084 {
00085
00086
00087 return 0;
00088 }
00089
00090 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00091 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::preinvoke (TIMER_QUEUE &,
00092 ACE_Event_Handler *,
00093 const void *,
00094 int,
00095 const ACE_Time_Value &,
00096 const void *&)
00097 {
00098
00099
00100 ACE_ASSERT (0);
00101 return 0;
00102 }
00103
00104 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00105 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::postinvoke (
00106 TIMER_QUEUE &,
00107 ACE_Event_Handler *,
00108 const void *,
00109 int,
00110 const ACE_Time_Value &,
00111 const void *)
00112 {
00113
00114
00115 ACE_ASSERT (0);
00116 return 0;
00117 }
00118
00119
00120 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00121 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::timeout (
00122 TIMER_QUEUE &,
00123 ACE_Event_Handler *,
00124 const void *,
00125 int,
00126 const ACE_Time_Value &)
00127 {
00128
00129
00130 ACE_ASSERT (0);
00131 return 0;
00132 }
00133
00134 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00135 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::cancel_type (
00136 TIMER_QUEUE &,
00137 ACE_Event_Handler *,
00138 int,
00139 int &)
00140 {
00141
00142
00143 return 0;
00144 }
00145
00146 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00147 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::cancel_timer (
00148 TIMER_QUEUE &,
00149 ACE_Event_Handler *,
00150 int,
00151 int)
00152 {
00153
00154
00155 return 0;
00156 }
00157
00158 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00159 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>::deletion (
00160 TIMER_QUEUE &,
00161 ACE_Event_Handler *event_handler,
00162 const void *arg)
00163 {
00164
00165
00166 Hash_Token<TYPE> *h =
00167 reinterpret_cast<Hash_Token<TYPE> *> (const_cast<void *> (arg));
00168
00169 int result =
00170 this->timer_hash_->upcall_functor ().
00171 deletion (*this->timer_hash_,
00172 event_handler,
00173 h->act_);
00174
00175 return result;
00176 }
00177
00178 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00179 ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::ACE_Timer_Hash_Iterator_T (ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET> &hash)
00180 : timer_hash_ (hash)
00181 {
00182 this->first ();
00183
00184 }
00185
00186
00187
00188 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
00189 ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::first (void)
00190 {
00191 for (this->position_ = 0;
00192 this->position_ < this->timer_hash_.table_size_;
00193 ++this->position_)
00194 {
00195
00196 if (!this->timer_hash_.table_[this->position_]->is_empty ())
00197 {
00198 this->iter_ = &this->timer_hash_.table_[this->position_]->iter ();
00199 this->iter_->first ();
00200 return;
00201 }
00202 }
00203
00204
00205 this->iter_ = 0;
00206 }
00207
00208
00209
00210
00211 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
00212 ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::next (void)
00213 {
00214 if (this->isdone ())
00215 return;
00216
00217
00218 if (this->iter_->isdone ())
00219 {
00220 for (++this->position_;
00221 this->position_ < this->timer_hash_.table_size_;
00222 ++this->position_)
00223 {
00224
00225 if (!this->timer_hash_.table_[this->position_]->is_empty ())
00226 {
00227 this->iter_ = &this->timer_hash_.table_[this->position_]->iter ();
00228 this->iter_->first ();
00229 return;
00230 }
00231 }
00232
00233
00234 this->iter_ = 0;
00235 }
00236 else
00237 this->iter_->next ();
00238 }
00239
00240
00241
00242 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> bool
00243 ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::isdone (void) const
00244 {
00245 return this->iter_ == 0;
00246 }
00247
00248
00249
00250 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00251 ACE_Timer_Node_T<TYPE> *
00252 ACE_Timer_Hash_Iterator_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::item (void)
00253 {
00254 if (this->isdone ())
00255 return 0;
00256
00257 return this->iter_->item ();
00258 }
00259
00260 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00261 ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK> &
00262 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::iter (void)
00263 {
00264 this->iterator_->first ();
00265 return *this->iterator_;
00266 }
00267
00268
00269
00270 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00271 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::ACE_Timer_Hash_T (
00272 size_t table_size,
00273 FUNCTOR *upcall_functor,
00274 ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
00275 : ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> (upcall_functor, freelist),
00276 size_ (0),
00277 table_size_ (table_size),
00278 table_functor_ (this),
00279 earliest_position_ (0)
00280 #if defined (ACE_WIN64)
00281 , pointer_base_ (0)
00282 #endif
00283 , token_list_ ()
00284 {
00285 ACE_TRACE ("ACE_Timer_Hash_T::ACE_Timer_Hash_T");
00286
00287 ACE_NEW (table_,
00288 BUCKET *[table_size]);
00289
00290 this->gettimeofday (ACE_OS::gettimeofday);
00291
00292 for (size_t i = 0;
00293 i < table_size;
00294 ++i)
00295 {
00296 ACE_NEW (this->table_[i],
00297 BUCKET (&this->table_functor_,
00298 this->free_list_));
00299 this->table_[i]->gettimeofday (ACE_OS::gettimeofday);
00300 }
00301
00302 ACE_NEW (iterator_,
00303 HASH_ITERATOR (*this));
00304 }
00305
00306
00307 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00308 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::ACE_Timer_Hash_T (
00309 FUNCTOR *upcall_functor,
00310 ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
00311 : ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK> (upcall_functor, freelist),
00312 size_ (0),
00313 table_size_ (ACE_DEFAULT_TIMER_HASH_TABLE_SIZE),
00314 table_functor_ (this),
00315 earliest_position_ (0)
00316 #if defined (ACE_WIN64)
00317 , pointer_base_ (0)
00318 #endif
00319 , token_list_ ()
00320 {
00321 ACE_TRACE ("ACE_Timer_Hash_T::ACE_Timer_Hash_T");
00322
00323 ACE_NEW (table_,
00324 BUCKET *[ACE_DEFAULT_TIMER_HASH_TABLE_SIZE]);
00325
00326
00327 this->gettimeofday (ACE_OS::gettimeofday);
00328
00329 for (size_t i = 0;
00330 i < this->table_size_;
00331 ++i)
00332 {
00333 ACE_NEW (this->table_[i],
00334 BUCKET (&this->table_functor_,
00335 this->free_list_));
00336 this->table_[i]->gettimeofday (ACE_OS::gettimeofday);
00337 }
00338
00339 ACE_NEW (iterator_,
00340 HASH_ITERATOR (*this));
00341 }
00342
00343
00344
00345 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00346 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::~ACE_Timer_Hash_T (void)
00347 {
00348 ACE_TRACE ("ACE_Timer_Hash_T::~ACE_Timer_Hash_T");
00349 ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));
00350
00351 delete iterator_;
00352
00353 for (size_t i = 0;
00354 i < this->table_size_;
00355 ++i)
00356 delete this->table_[i];
00357
00358 delete [] this->table_;
00359 }
00360
00361
00362
00363 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> bool
00364 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::is_empty (void) const
00365 {
00366 ACE_TRACE ("ACE_Timer_Hash_T::is_empty");
00367 return this->table_[this->earliest_position_]->is_empty ();
00368 }
00369
00370
00371
00372 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00373 const ACE_Time_Value &
00374 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::earliest_time (void) const
00375 {
00376 ACE_TRACE ("ACE_Timer_Hash_T::earliest_time");
00377 return this->table_[this->earliest_position_]->earliest_time ();
00378 }
00379
00380 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
00381 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::dump (void) const
00382 {
00383 #if defined (ACE_HAS_DUMP)
00384 ACE_TRACE ("ACE_Timer_Hash_T::dump");
00385 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00386 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\ntable_size_ = %d"), this->table_size_));
00387 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nearliest_position_ = %d"), this->earliest_position_));
00388
00389 for (size_t i = 0; i < this->table_size_; ++i)
00390 if (!this->table_[i]->is_empty ())
00391 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\nBucket %d contains nodes"), i));
00392
00393 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("\n")));
00394 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00395 #endif
00396 }
00397
00398
00399
00400
00401 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00402 void
00403 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::reschedule (
00404 ACE_Timer_Node_T<TYPE> *expired)
00405 {
00406 ACE_TRACE ("ACE_Timer_Hash_T::reschedule");
00407
00408 Hash_Token<TYPE> *h =
00409 reinterpret_cast<Hash_Token<TYPE> *> (
00410 const_cast<void *> (expired->get_act ()));
00411
00412
00413
00414
00415 size_t const secs_hash_input =
00416 static_cast<size_t> (expired->get_timer_value ().sec ());
00417 h->pos_ = secs_hash_input % this->table_size_;
00418
00419 h->orig_id_ =
00420 this->table_[h->pos_]->schedule (expired->get_type (),
00421 h,
00422 expired->get_timer_value (),
00423 expired->get_interval ());
00424 ACE_ASSERT (h->orig_id_ != -1);
00425
00426 #if 0
00427 ACE_DEBUG ((LM_DEBUG, "Hash::reschedule() resets %d in slot %d where it's id is %d and token is %x\n",
00428 expired->get_timer_value ().msec (),
00429 h->pos_,
00430 h->orig_id_,
00431 h));
00432 #endif
00433
00434
00435
00436
00437
00438 ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::free_node (expired);
00439
00440 if (this->table_[this->earliest_position_]->is_empty ()
00441 || this->table_[h->pos_]->earliest_time ()
00442 < this->table_[this->earliest_position_]->earliest_time ())
00443 this->earliest_position_ = h->pos_;
00444 }
00445
00446
00447
00448
00449 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00450 long
00451 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::schedule_i (
00452 const TYPE &type,
00453 const void *act,
00454 const ACE_Time_Value &future_time,
00455 const ACE_Time_Value &interval)
00456 {
00457 ACE_TRACE ("ACE_Timer_Hash_T::schedule_i");
00458
00459
00460
00461
00462 size_t const secs_hash_input = static_cast<size_t> (future_time.sec ());
00463 size_t const position = secs_hash_input % this->table_size_;
00464
00465
00466
00467 Hash_Token<TYPE> *h = this->token_list_.remove ();
00468 h->set (act, position, 0, type);
00469
00470 h->orig_id_ =
00471 this->table_[position]->schedule (type,
00472 h,
00473 future_time,
00474 interval);
00475 ACE_ASSERT (h->orig_id_ != -1);
00476
00477 #if 0
00478 ACE_DEBUG ((LM_DEBUG, "Hash::schedule() placing %d in slot %d where it's id is %d and token is %x\n",
00479 future_time.msec (),
00480 position,
00481 h->orig_id_,
00482 h));
00483 #endif
00484
00485 if (this->table_[this->earliest_position_]->is_empty ()
00486 || this->table_[position]->earliest_time ()
00487 < this->table_[this->earliest_position_]->earliest_time ())
00488 this->earliest_position_ = position;
00489
00490 ++this->size_;
00491
00492 #if defined (ACE_WIN64)
00493
00494
00495
00496
00497
00498
00499
00500
00501 intptr_t hi = reinterpret_cast<intptr_t> (h);
00502 if (this->pointer_base_ == 0)
00503 this->pointer_base_ = hi & 0xffffffff00000000;
00504 return static_cast<long> (hi & 0xffffffff);
00505 #else
00506 return reinterpret_cast<long> (h);
00507 #endif
00508 }
00509
00510
00511
00512 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00513 int
00514 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::reset_interval (
00515 long timer_id,
00516 const ACE_Time_Value & interval)
00517 {
00518 ACE_TRACE ("ACE_Timer_Hash_T::reset_interval");
00519
00520
00521
00522 if (timer_id == -1)
00523 return -1;
00524
00525 #if defined (ACE_WIN64)
00526 unsigned long const timer_offset =
00527 static_cast<unsigned long> (timer_id);
00528
00529 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00530
00531 Hash_Token<TYPE> * const h =
00532 reinterpret_cast<Hash_Token<TYPE> *> (this->pointer_base_ + timer_offset);
00533 #else
00534 Hash_Token<TYPE> * const h =
00535 reinterpret_cast<Hash_Token<TYPE> *> (timer_id);
00536
00537
00538
00539 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00540 #endif
00541
00542 return this->table_[h->pos_]->reset_interval (h->orig_id_,
00543 interval);
00544 }
00545
00546
00547
00548
00549 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00550 int
00551 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::cancel (long timer_id,
00552 const void **act,
00553 int dont_call)
00554 {
00555 ACE_TRACE ("ACE_Timer_Hash_T::cancel");
00556
00557
00558
00559 if (timer_id == -1)
00560 return 0;
00561
00562 #if defined (ACE_WIN64)
00563 unsigned long const timer_offset =
00564 static_cast<unsigned long> (timer_id);
00565
00566 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00567
00568 Hash_Token<TYPE> * const h =
00569 reinterpret_cast<Hash_Token<TYPE> *> (this->pointer_base_ + timer_offset);
00570 #else
00571 Hash_Token<TYPE> * const h =
00572 reinterpret_cast<Hash_Token<TYPE> *> (timer_id);
00573
00574
00575
00576 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00577 #endif
00578
00579 int const result = this->table_[h->pos_]->cancel (h->orig_id_,
00580 0,
00581 dont_call);
00582
00583 if (result == 1)
00584 {
00585
00586 int cookie = 0;
00587
00588
00589 this->upcall_functor ().cancel_type (*this,
00590 h->type_,
00591 dont_call,
00592 cookie);
00593
00594
00595 this->upcall_functor ().cancel_timer (*this,
00596 h->type_,
00597 dont_call,
00598 cookie);
00599
00600 if (h->pos_ == this->earliest_position_)
00601 this->find_new_earliest ();
00602
00603 if (act != 0)
00604 *act = h->act_;
00605
00606
00607
00608
00609 this->token_list_.add (h);
00610
00611 --this->size_;
00612 }
00613
00614 return result;
00615 }
00616
00617
00618
00619 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET>
00620 int
00621 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::cancel (const TYPE &type,
00622 int dont_call)
00623 {
00624 ACE_TRACE ("ACE_Timer_Hash_T::cancel");
00625
00626 size_t i;
00627
00628 Hash_Token<TYPE> **timer_ids = 0;
00629 size_t pos = 0;
00630
00631 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00632
00633 ACE_NEW_RETURN (timer_ids,
00634 Hash_Token<TYPE> *[this->size_],
00635 -1);
00636
00637 for (i = 0;
00638 i < this->table_size_;
00639 ++i)
00640 {
00641 ACE_Timer_Queue_Iterator_T<TYPE,
00642 ACE_Timer_Hash_Upcall<TYPE, FUNCTOR, ACE_LOCK>,
00643 ACE_Null_Mutex> &iter =
00644 this->table_[i]->iter ();
00645
00646 for (iter.first ();
00647 !iter.isdone ();
00648 iter.next ())
00649 if (iter.item ()->get_type () == type)
00650 timer_ids[pos++] =
00651 reinterpret_cast<Hash_Token<TYPE> *> (
00652 const_cast<void *> (iter.item ()->get_act ()));
00653 }
00654
00655 if (pos > this->size_)
00656 return -1;
00657
00658 for (i = 0; i < pos; ++i)
00659 {
00660 int const result =
00661 this->table_[timer_ids[i]->pos_]->cancel (timer_ids[i]->orig_id_,
00662 0,
00663 dont_call);
00664 ACE_ASSERT (result == 1);
00665 ACE_UNUSED_ARG (result);
00666
00667
00668
00669 this->token_list_.add (timer_ids[i]);
00670
00671 --this->size_;
00672 }
00673
00674 delete [] timer_ids;
00675
00676 this->find_new_earliest ();
00677
00678
00679 int cookie = 0;
00680
00681
00682 this->upcall_functor ().cancel_type (*this,
00683 type,
00684 dont_call,
00685 cookie);
00686
00687 for (i = 0;
00688 i < pos;
00689 ++i)
00690 {
00691
00692 this->upcall_functor ().cancel_timer (*this,
00693 type,
00694 dont_call,
00695 cookie);
00696 }
00697
00698 return static_cast<int> (pos);
00699 }
00700
00701
00702
00703 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> ACE_Timer_Node_T<TYPE> *
00704 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::remove_first (void)
00705 {
00706 if (this->is_empty ())
00707 return 0;
00708
00709 ACE_Timer_Node_T<TYPE> *temp =
00710 this->table_[this->earliest_position_]->remove_first ();
00711
00712 this->find_new_earliest ();
00713
00714 --this->size_;
00715
00716 return temp;
00717 }
00718
00719
00720
00721 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
00722 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::find_new_earliest (void)
00723 {
00724 for (size_t i = 0; i < this->table_size_; ++i)
00725 if (!this->table_[i]->is_empty ())
00726 if (this->table_[this->earliest_position_]->is_empty ()
00727 || this->earliest_time () == ACE_Time_Value::zero
00728 || this->table_[i]->earliest_time () <= this->earliest_time ())
00729 this->earliest_position_ = i;
00730 }
00731
00732
00733
00734 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> ACE_Timer_Node_T<TYPE> *
00735 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::get_first (void)
00736 {
00737 ACE_TRACE ("ACE_Timer_Hash_T::get_first");
00738
00739 if (this->is_empty ())
00740 return 0;
00741
00742 return this->table_[this->earliest_position_]->get_first ();
00743 }
00744
00745 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> void
00746 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::free_node (ACE_Timer_Node_T<TYPE> *node)
00747 {
00748 ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::free_node (node);
00749
00750 Hash_Token<TYPE> *h =
00751 reinterpret_cast<Hash_Token<TYPE> *> (const_cast<void *> (node->get_act ()));
00752 this->token_list_.add (h);
00753 }
00754
00755 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> int
00756 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::dispatch_info_i (const ACE_Time_Value &cur_time,
00757 ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
00758 {
00759 int const result =
00760 ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::dispatch_info_i (cur_time,
00761 info);
00762
00763 if (result == 1)
00764 {
00765 Hash_Token<TYPE> *h =
00766 reinterpret_cast<Hash_Token<TYPE> *> (const_cast<void *> (info.act_));
00767
00768 info.act_ = h->act_;
00769 }
00770
00771 return result;
00772 }
00773
00774
00775
00776 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> int
00777 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::expire ()
00778 {
00779 return ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::expire();
00780 }
00781
00782
00783
00784 template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> int
00785 ACE_Timer_Hash_T<TYPE, FUNCTOR, ACE_LOCK, BUCKET>::expire (const ACE_Time_Value &cur_time)
00786 {
00787 ACE_TRACE ("ACE_Timer_Hash_T::expire");
00788
00789 int number_of_timers_expired = 0;
00790
00791 ACE_Timer_Node_T<TYPE> *expired = 0;
00792
00793 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00794
00795
00796
00797 for (size_t i = 0;
00798 i < this->table_size_;
00799 ++i)
00800 {
00801 while (!this->table_[i]->is_empty ()
00802 && this->table_[i]->earliest_time () <= cur_time)
00803 {
00804 expired = this->table_[i]->remove_first ();
00805 const void *act = expired->get_act ();
00806 bool reclaim = true;
00807
00808 Hash_Token<TYPE> *h =
00809 reinterpret_cast<Hash_Token<TYPE> *> (const_cast<void *> (act));
00810
00811 ACE_ASSERT (h->pos_ == i);
00812
00813 #if 0
00814 ACE_DEBUG ((LM_DEBUG, "Hash::expire() expiring %d in slot %d where it's id is %d and token is %x\n",
00815 expired->get_timer_value ().msec (),
00816 h->pos_,
00817 h->orig_id_,
00818 h));
00819 #endif
00820
00821
00822 if (expired->get_interval () > ACE_Time_Value::zero)
00823 {
00824
00825
00826 this->recompute_next_abs_interval_time (expired, cur_time);
00827
00828
00829
00830 this->reschedule (expired);
00831 reclaim = false;
00832 }
00833 else
00834 {
00835 this->free_node (expired);
00836 }
00837
00838 ACE_Timer_Node_Dispatch_Info_T<TYPE> info;
00839
00840
00841 expired->get_dispatch_info (info);
00842
00843 info.act_ = h->act_;
00844
00845 const void *upcall_act = 0;
00846
00847 this->preinvoke (info, cur_time, upcall_act);
00848
00849 this->upcall (info, cur_time);
00850
00851 this->postinvoke (info, cur_time, upcall_act);
00852
00853 if (reclaim)
00854 {
00855 --this->size_;
00856 }
00857
00858 ++number_of_timers_expired;
00859 }
00860 }
00861
00862 if (number_of_timers_expired > 0)
00863 this->find_new_earliest ();
00864
00865 return number_of_timers_expired;
00866 }
00867
00868 ACE_END_VERSIONED_NAMESPACE_DECL
00869
00870 #endif