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