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