00001
00002
00003 #ifndef ACE_TIMER_WHEEL_T_CPP
00004 #define ACE_TIMER_WHEEL_T_CPP
00005
00006 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00007 # pragma once
00008 #endif
00009
00010 #include "ace/OS_NS_sys_time.h"
00011 #include "ace/Guard_T.h"
00012 #include "ace/Timer_Wheel_T.h"
00013 #include "ace/Log_Msg.h"
00014
00015 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00045 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Wheel_T
00046 (FUNCTOR* upcall_functor
00047 , FreeList* freelist
00048 )
00049 : Base (upcall_functor, freelist)
00050 , spokes_(0)
00051 , spoke_count_(0)
00052 , spoke_bits_(0)
00053 , res_bits_ (0)
00054 , earliest_spoke_ (0)
00055 , iterator_(0)
00056 , timer_count_(0)
00057 {
00058 ACE_TRACE ("ACE_Timer_Wheel_T::ACE_Timer_Wheel_T");
00059 this->open_i (0,
00060 ACE_DEFAULT_TIMER_WHEEL_SIZE,
00061 ACE_DEFAULT_TIMER_WHEEL_RESOLUTION);
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00075 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Wheel_T
00076 (u_int spoke_count,
00077 u_int resolution,
00078 size_t prealloc,
00079 FUNCTOR* upcall_functor,
00080 FreeList* freelist)
00081 : Base (upcall_functor, freelist)
00082 , spokes_ (0)
00083 , spoke_count_ (0)
00084 , spoke_bits_ (0)
00085 , res_bits_ (0)
00086 , earliest_spoke_ (0)
00087 , iterator_ (0)
00088 , timer_count_ (0)
00089 {
00090 ACE_TRACE ("ACE_Timer_Wheel_T::ACE_Timer_Wheel_T");
00091 this->open_i (prealloc, spoke_count, resolution);
00092 }
00093
00094 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00095 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::power2bits (int n,
00096 int min_bits,
00097 int max_bits)
00098 {
00099 int max = (1 << max_bits) - 1;
00100 if (n > max)
00101 return max_bits;
00102
00103
00104 int i = 0;
00105 int tmp = n;
00106 do
00107 {
00108 tmp >>= 1;
00109 ++i;
00110 }
00111 while (tmp != 0);
00112
00113 if (i <= min_bits)
00114 return min_bits;
00115
00116
00117 int a = (1 << i) - n;
00118 int b = (1 << (i - 1)) - n;
00119 if (b < 0)
00120 b = -b;
00121 if (b < a)
00122 return i - 1;
00123 return i;
00124 }
00125
00126
00127
00128
00129
00130 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00131 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::open_i
00132 (size_t prealloc, u_int spokes, u_int res)
00133 {
00134 ACE_TRACE ("ACE_Timer_Wheel_T::open_i");
00135
00136 this->gettimeofday (ACE_OS::gettimeofday);
00137
00138
00139
00140 const int MIN_SPOKE_BITS = 3;
00141 const int MAX_SPOKE_BITS = 12;
00142 const int MAX_RES_BITS = 20;
00143
00144 this->spoke_bits_ = power2bits (spokes, MIN_SPOKE_BITS, MAX_SPOKE_BITS);
00145 this->res_bits_ = power2bits (res, 1, MAX_RES_BITS);
00146
00147 this->spoke_count_ = 1 << this->spoke_bits_;
00148
00149 this->free_list_->resize (prealloc + this->spoke_count_);
00150
00151 this->wheel_time_.msec (1 << (this->res_bits_));
00152
00153 ACE_NEW (this->spokes_, ACE_Timer_Node_T<TYPE>* [this->spoke_count_]);
00154
00155
00156 for (u_int i = 0; i < this->spoke_count_; ++i)
00157 {
00158 ACE_Timer_Node_T<TYPE>* root = this->alloc_node ();
00159 root->set (0, 0, ACE_Time_Value::zero, ACE_Time_Value::zero, root, root, 0);
00160 this->spokes_[i] = root;
00161 }
00162
00163 ACE_NEW (iterator_, Iterator (*this));
00164 }
00165
00166
00167 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00168 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Wheel_T (void)
00169 {
00170 ACE_TRACE ("ACE_Timer_Wheel_T::~ACE_Timer_Wheel_T");
00171
00172 delete iterator_;
00173
00174 for (u_int i = 0; i < this->spoke_count_; ++i)
00175 {
00176
00177 ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
00178 for (ACE_Timer_Node_T<TYPE>* n = root->get_next (); n != root;)
00179 {
00180 ACE_Timer_Node_T<TYPE>* next = n->get_next ();
00181 this->upcall_functor ().deletion (*this,
00182 n->get_type (),
00183 n->get_act ());
00184 this->free_node (n);
00185 n = next;
00186 }
00187 delete root;
00188 }
00189 delete[] this->spokes_;
00190 }
00191
00192
00193 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00194 ACE_Timer_Node_T<TYPE>*
00195 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::find_spoke_node
00196 (u_int spoke, long timer_id) const
00197 {
00198 ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00199 for (ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00200 n != root;
00201 n = n->get_next ())
00202 {
00203 if (n->get_timer_id () == timer_id)
00204 return n;
00205 }
00206 return 0;
00207 }
00208
00209
00210
00211 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00212 ACE_Timer_Node_T<TYPE>*
00213 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::find_node (long timer_id) const
00214 {
00215 if (timer_id == -1)
00216 return 0;
00217
00218
00219 u_int spoke_mask = this->spoke_count_ - 1;
00220 u_int start = timer_id & spoke_mask;
00221 ACE_Timer_Node_T<TYPE>* n = this->find_spoke_node (start, timer_id);
00222 if (n != 0)
00223 return n;
00224
00225
00226
00227
00228 for (u_int i = 0; i < this->spoke_count_; ++i)
00229 {
00230 if (i != start)
00231 {
00232 n = this->find_spoke_node (i, timer_id);
00233 if (n != 0)
00234 return n;
00235 }
00236 }
00237
00238
00239 return 0;
00240 }
00241
00242
00243
00244
00245
00246
00247 template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
00248 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::is_empty (void) const
00249 {
00250 ACE_TRACE ("ACE_Timer_Wheel_T::is_empty");
00251 return timer_count_ == 0;
00252 }
00253
00254
00255
00256
00257
00258 template <class TYPE, class FUNCTOR, class ACE_LOCK> const ACE_Time_Value &
00259 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::earliest_time (void) const
00260 {
00261 ACE_TRACE ("ACE_Timer_Wheel_T::earliest_time");
00262 ACE_Timer_Node_T<TYPE>* n = this->get_first_i ();
00263 if (n != 0)
00264 return n->get_timer_value ();
00265 return ACE_Time_Value::zero;
00266 }
00267
00268
00269
00270
00271 template <class TYPE, class FUNCTOR, class ACE_LOCK> u_int
00272 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_spoke
00273 (const ACE_Time_Value& t) const
00274 {
00275 return static_cast<u_int> ((t.msec () >> this->res_bits_) & (this->spoke_count_ - 1));
00276 }
00277
00278
00279
00280
00281
00282
00283 template <class TYPE, class FUNCTOR, class ACE_LOCK> long
00284 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::generate_timer_id (u_int spoke)
00285 {
00286
00287 int cnt_bits = sizeof (long) * 8 - this->spoke_bits_;
00288 long max_cnt = ((long)1 << cnt_bits) - 1;
00289 if (spoke == this->spoke_count_)
00290 --max_cnt;
00291
00292 ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00293
00294 if (root == root->get_next ())
00295 root->set_act(0);
00296
00297
00298
00299
00300 #if defined (ACE_WIN64)
00301
00302
00303 # pragma warning(push)
00304 # pragma warning(disable : 4311)
00305 #endif
00306 long next_cnt = reinterpret_cast<long> (root->get_act ());
00307 #if defined (ACE_WIN64)
00308 # pragma warning(pop)
00309 #endif
00310
00311
00312 long cnt = root->get_timer_id ();
00313
00314 if (cnt >= max_cnt && root == root->get_next ())
00315 {
00316
00317
00318
00319
00320 root->set_timer_id (1);
00321 return spoke;
00322 }
00323 else if (cnt >= max_cnt)
00324 {
00325 cnt = 0;
00326 }
00327 else if (next_cnt == 0 || cnt < next_cnt)
00328 {
00329 root->set_timer_id (cnt + 1);
00330 return (cnt << this->spoke_bits_) | spoke;
00331 }
00332
00333
00334
00335
00336
00337
00338
00339
00340 for (; cnt < max_cnt - 1; ++cnt)
00341 {
00342 long id = (cnt << this->spoke_bits_) | spoke;
00343 ACE_Timer_Node_T<TYPE>* n = this->find_spoke_node (spoke, id);
00344 if (n == 0)
00345 {
00346 root->set_timer_id (cnt + 1);
00347
00348 next_cnt = 0;
00349 for (; n != root; n = n->get_next ())
00350 {
00351 long tmp = n->get_timer_id () >> this->spoke_bits_;
00352 if (tmp > cnt && (tmp < next_cnt || next_cnt == 0))
00353 next_cnt = tmp;
00354 }
00355 #if defined (ACE_WIN64)
00356
00357
00358 # pragma warning(push)
00359 # pragma warning(disable : 4312)
00360 #endif
00361 root->set_act (reinterpret_cast<void*> (next_cnt));
00362 #if defined (ACE_WIN64)
00363 # pragma warning(pop)
00364 #endif
00365 return id;
00366 }
00367 }
00368
00369 return -1;
00370 }
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 template <class TYPE, class FUNCTOR, class ACE_LOCK> long
00386 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i (const TYPE& type,
00387 const void* act,
00388 const ACE_Time_Value& future_time,
00389 const ACE_Time_Value& interval)
00390 {
00391 ACE_TRACE ("ACE_Timer_Wheel_T::schedule_i");
00392
00393 ACE_Timer_Node_T<TYPE>* n = this->alloc_node ();
00394
00395 if (n != 0)
00396 {
00397 u_int spoke = calculate_spoke (future_time);
00398 long id = generate_timer_id (spoke);
00399
00400
00401
00402 if (id != -1)
00403 {
00404 n->set (type, act, future_time, interval, 0, 0, id);
00405 this->schedule_i (n, spoke, future_time);
00406 }
00407 return id;
00408 }
00409
00410
00411 errno = ENOMEM;
00412 return -1;
00413 }
00414
00415
00416
00417
00418
00419
00420
00421 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00422 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::reschedule (ACE_Timer_Node_T<TYPE>* n)
00423 {
00424 ACE_TRACE ("ACE_Timer_Wheel_T::reschedule");
00425 const ACE_Time_Value& expire = n->get_timer_value ();
00426 u_int spoke = calculate_spoke (expire);
00427 this->schedule_i (n, spoke, expire);
00428 }
00429
00430
00431 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00432 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::schedule_i
00433 (ACE_Timer_Node_T<TYPE>* n,
00434 u_int spoke,
00435 const ACE_Time_Value& expire)
00436 {
00437
00438 if (this->is_empty() || expire < this->earliest_time ())
00439 this->earliest_spoke_ = spoke;
00440
00441 ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00442 ACE_Timer_Node_T<TYPE>* last = root->get_prev ();
00443
00444 ++timer_count_;
00445
00446
00447 if (last == root) {
00448 n->set_prev (root);
00449 n->set_next (root);
00450 root->set_prev (n);
00451 root->set_next (n);
00452 return;
00453 }
00454
00455
00456
00457
00458 ACE_Timer_Node_T<TYPE>* p = root->get_prev ();
00459 while (p != root && p->get_timer_value () > expire)
00460 p = p->get_prev ();
00461
00462
00463 n->set_prev (p);
00464 n->set_next (p->get_next ());
00465 p->get_next ()->set_prev (n);
00466 p->set_next (n);
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00480 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::reset_interval (long timer_id,
00481 const ACE_Time_Value &interval
00482 )
00483 {
00484 ACE_TRACE ("ACE_Timer_Wheel_T::reset_interval");
00485 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00486 ACE_Timer_Node_T<TYPE>* n = this->find_node (timer_id);
00487 if (n != 0)
00488 {
00489
00490 n->set_interval (interval);
00491 return 0;
00492 }
00493 return -1;
00494 }
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00510 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (const TYPE& type, int skip_close)
00511 {
00512 ACE_TRACE ("ACE_Timer_Wheel_T::cancel");
00513
00514 int num_canceled = 0;
00515 int cookie = 0;
00516
00517 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00518
00519 if (!this->is_empty ())
00520 {
00521 ACE_Timer_Node_T<TYPE>* first = this->get_first ();
00522 ACE_Time_Value last = first->get_timer_value ();
00523 int recalc = 0;
00524
00525 for (u_int i = 0; i < this->spoke_count_; ++i)
00526 {
00527 ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
00528 for (ACE_Timer_Node_T<TYPE>* n = root->get_next (); n != root; )
00529 {
00530 if (n->get_type () == type)
00531 {
00532 ++num_canceled;
00533 if (n == first)
00534 recalc = 1;
00535
00536 ACE_Timer_Node_T<TYPE>* tmp = n;
00537 n = n->get_next ();
00538
00539 this->cancel_i (tmp);
00540 }
00541 else
00542 {
00543 n = n->get_next ();
00544 }
00545 }
00546 }
00547
00548 if (recalc)
00549 this->recalc_earliest (last);
00550 }
00551
00552
00553
00554
00555 this->upcall_functor ().cancel_type (*this,
00556 type,
00557 skip_close,
00558 cookie);
00559
00560 for (int i = 0;
00561 i < num_canceled;
00562 ++i)
00563 {
00564
00565 this->upcall_functor ().cancel_timer (*this,
00566 type,
00567 skip_close,
00568 cookie);
00569 }
00570
00571 return num_canceled;
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00593 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
00594 const void **act,
00595 int skip_close)
00596 {
00597 ACE_TRACE ("ACE_Timer_Wheel_T::cancel");
00598 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00599 ACE_Timer_Node_T<TYPE>* n = this->find_node (timer_id);
00600 if (n != 0)
00601 {
00602 ACE_Time_Value last = n->get_timer_value ();
00603
00604 int recalc = (this->get_first_i () == n);
00605
00606
00607 int cookie = 0;
00608
00609
00610 this->upcall_functor ().cancel_type (*this,
00611 n->get_type (),
00612 skip_close,
00613 cookie);
00614
00615
00616 this->upcall_functor ().cancel_timer (*this,
00617 n->get_type (),
00618 skip_close,
00619 cookie);
00620 if (act != 0)
00621 *act = n->get_act ();
00622
00623 this->cancel_i (n);
00624
00625 if (recalc)
00626 this->recalc_earliest (last);
00627
00628 return 1;
00629 }
00630 return 0;
00631 }
00632
00633
00634 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00635 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
00636 {
00637 this->unlink (n);
00638 this->free_node (n);
00639 }
00640
00641
00642
00643
00644
00645
00646
00647 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00648 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::recalc_earliest
00649 (const ACE_Time_Value& last)
00650 {
00651
00652 if (this->is_empty ())
00653 return;
00654
00655 ACE_Time_Value et = ACE_Time_Value::zero;
00656 u_int es = 0;
00657 u_int spoke = this->earliest_spoke_;
00658
00659
00660 for (u_int i = 0; i < this->spoke_count_; ++i)
00661 {
00662 ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00663 ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00664 if (n != root)
00665 {
00666 ACE_Time_Value t = n->get_timer_value ();
00667 if (t < last + this->wheel_time_)
00668 {
00669 this->earliest_spoke_ = spoke;
00670 return;
00671 }
00672 else if (et == ACE_Time_Value::zero || t < et)
00673 {
00674 et = t;
00675 es = spoke;
00676 }
00677 }
00678 if (++spoke >= this->spoke_count_)
00679 spoke = 0;
00680 }
00681
00682 this->earliest_spoke_ = es;
00683
00684 }
00685
00686
00687
00688
00689
00690 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00691 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
00692 {
00693 #if defined (ACE_HAS_DUMP)
00694 ACE_TRACE ("ACE_Timer_Wheel_T::dump");
00695 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00696
00697 ACE_DEBUG ((LM_DEBUG,
00698 ACE_TEXT ("\nspoke_count_ = %d"), this->spoke_count_));
00699 ACE_DEBUG ((LM_DEBUG,
00700 ACE_TEXT ("\nresolution_ = %d"), 1 << this->res_bits_));
00701 ACE_DEBUG ((LM_DEBUG,
00702 ACE_TEXT ("\nwheel_ =\n")));
00703
00704 for (u_int i = 0; i < this->spoke_count_; ++i)
00705 {
00706 ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("%d\n"), i));
00707 ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
00708 for (ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00709 n != root;
00710 n = n->get_next ())
00711 {
00712 n->dump ();
00713 }
00714 }
00715
00716 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00717 #endif
00718 }
00719
00720
00721
00722
00723
00724
00725
00726 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
00727 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
00728 {
00729 ACE_TRACE ("ACE_Timer_Wheel_T::remove_first");
00730 return remove_first_expired (ACE_Time_Value::max_time);
00731 }
00732
00733 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00734 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::unlink (ACE_Timer_Node_T<TYPE>* n)
00735 {
00736 ACE_TRACE ("ACE_Timer_Wheel_T::unlink");
00737 --timer_count_;
00738 n->get_prev ()->set_next (n->get_next ());
00739 n->get_next ()->set_prev (n->get_prev ());
00740 n->set_prev (0);
00741 n->set_next (0);
00742 }
00743
00744 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
00745 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first_expired (const ACE_Time_Value& now)
00746 {
00747 ACE_Timer_Node_T<TYPE>* n = this->get_first ();
00748 if (n != 0 && n->get_timer_value() <= now)
00749 {
00750 this->unlink (n);
00751 this->recalc_earliest (n->get_timer_value ());
00752 return n;
00753 }
00754 return 0;
00755 }
00756
00757
00758
00759
00760
00761
00762 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00763 ACE_Timer_Node_T<TYPE>*
00764 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first (void)
00765 {
00766 ACE_TRACE ("ACE_Timer_Wheel_T::get_first");
00767 return this->get_first_i ();
00768 }
00769
00770 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00771 ACE_Timer_Node_T<TYPE>*
00772 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
00773 {
00774 ACE_Timer_Node_T<TYPE>* root = this->spokes_[this->earliest_spoke_];
00775 ACE_Timer_Node_T<TYPE>* first = root->get_next ();
00776 if (first != root)
00777 return first;
00778 return 0;
00779 }
00780
00781
00782
00783
00784
00785 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00786 ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>&
00787 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
00788 {
00789 this->iterator_->first ();
00790 return *this->iterator_;
00791 }
00792
00793
00794
00795
00796
00797 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00798 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire ()
00799 {
00800 return ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::expire ();
00801 }
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00812 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value& cur_time)
00813 {
00814 ACE_TRACE ("ACE_Timer_Wheel_T::expire");
00815
00816 int expcount = 0;
00817
00818 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00819
00820 ACE_Timer_Node_T<TYPE>* n = this->remove_first_expired (cur_time);
00821
00822 while (n != 0)
00823 {
00824 ++expcount;
00825
00826
00827
00828 ACE_Timer_Node_Dispatch_Info_T<TYPE> info;
00829
00830
00831 n->get_dispatch_info (info);
00832
00833 if (n->get_interval () > ACE_Time_Value::zero)
00834 {
00835
00836
00837 this->recompute_next_abs_interval_time (n, cur_time);
00838
00839 this->reschedule (n);
00840 }
00841 else
00842 {
00843 this->free_node (n);
00844 }
00845
00846 const void *upcall_act = 0;
00847
00848 this->preinvoke (info, cur_time, upcall_act);
00849
00850 this->upcall (info, cur_time);
00851
00852 this->postinvoke (info, cur_time, upcall_act);
00853
00854 n = this->remove_first_expired (cur_time);
00855 }
00856
00857 return expcount;
00858 }
00859
00860
00861
00862
00863
00864
00865
00866
00867
00868
00869 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00870 ACE_Timer_Wheel_Iterator_T<TYPE,FUNCTOR,ACE_LOCK>::ACE_Timer_Wheel_Iterator_T
00871 (Wheel& wheel)
00872 : timer_wheel_ (wheel)
00873 {
00874 this->first();
00875 }
00876
00877
00878
00879
00880
00881 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00882 ACE_Timer_Wheel_Iterator_T<TYPE,
00883 FUNCTOR,
00884 ACE_LOCK>::~ACE_Timer_Wheel_Iterator_T (void)
00885 {
00886 }
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00898 ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::first (void)
00899 {
00900 this->goto_next(0);
00901 }
00902
00903
00904
00905
00906
00907 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00908 ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::next (void)
00909 {
00910 if (this->isdone())
00911 return;
00912
00913 ACE_Timer_Node_T<TYPE>* n = this->current_node_->get_next ();
00914 ACE_Timer_Node_T<TYPE>* root = this->timer_wheel_.spokes_[this->spoke_];
00915 if (n == root)
00916 this->goto_next (this->spoke_ + 1);
00917 else
00918 this->current_node_ = n;
00919 }
00920
00921
00922 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00923 ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::goto_next (u_int start_spoke)
00924 {
00925
00926 u_int sc = this->timer_wheel_.spoke_count_;
00927 for (u_int i = start_spoke; i < sc; ++i)
00928 {
00929 ACE_Timer_Node_T<TYPE>* root = this->timer_wheel_.spokes_[i];
00930 ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00931 if (n != root)
00932 {
00933 this->spoke_ = i;
00934 this->current_node_ = n;
00935 return;
00936 }
00937 }
00938
00939 this->spoke_ = sc;
00940 this->current_node_ = 0;
00941 }
00942
00943
00944
00945
00946 template <class TYPE, class FUNCTOR, class ACE_LOCK> bool
00947 ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::isdone (void) const
00948 {
00949 return this->current_node_ == 0;
00950 }
00951
00952
00953
00954
00955
00956 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
00957 ACE_Timer_Wheel_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::item (void)
00958 {
00959 return this->current_node_;
00960 }
00961
00962 ACE_END_VERSIONED_NAMESPACE_DECL
00963
00964 #endif