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_ + this->spoke_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> int
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   ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00514 
00515   int num_canceled = 0; 
00516 
00517   if (!this->is_empty ())
00518     {
00519       ACE_Timer_Node_T<TYPE>* first = this->get_first ();
00520       ACE_Time_Value last = first->get_timer_value ();
00521       int recalc = 0;
00522 
00523       for (u_int i = 0; i < this->spoke_count_; ++i)
00524         {
00525           ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
00526           for (ACE_Timer_Node_T<TYPE>* n = root->get_next (); n != root; )
00527             {
00528               if (n->get_type () == type)
00529                 {
00530                   ++num_canceled;
00531                   if (n == first)
00532                     recalc = 1;
00533 
00534                   ACE_Timer_Node_T<TYPE>* tmp = n;
00535                   n = n->get_next ();
00536 
00537                   this->cancel_i (tmp);
00538                 }
00539               else
00540                 {
00541                   n = n->get_next ();
00542                 }
00543             }
00544         }
00545 
00546       if (recalc)
00547         this->recalc_earliest (last);
00548     }
00549 
00550   
00551   int cookie = 0;
00552 
00553   
00554   this->upcall_functor ().cancel_type (*this,
00555                                        type,
00556                                        skip_close,
00557                                        cookie);
00558 
00559   for (int i = 0;
00560        i < num_canceled;
00561        ++i)
00562     {
00563       
00564       this->upcall_functor ().cancel_timer (*this,
00565                                             type,
00566                                             skip_close,
00567                                             cookie);
00568     }
00569 
00570   return num_canceled;
00571 }
00572 
00573 
00574 
00575 
00576 
00577 
00578 
00579 
00580 
00581 
00582 
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00592 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel (long timer_id,
00593                                                     const void **act,
00594                                                     int skip_close)
00595 {
00596   ACE_TRACE ("ACE_Timer_Wheel_T::cancel");
00597   ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00598   ACE_Timer_Node_T<TYPE>* n = this->find_node (timer_id);
00599   if (n != 0)
00600     {
00601       ACE_Time_Value last = n->get_timer_value ();
00602 
00603       int recalc = (this->get_first_i () == n);
00604 
00605       
00606       int cookie = 0;
00607 
00608       
00609       this->upcall_functor ().cancel_type (*this,
00610                                            n->get_type (),
00611                                            skip_close,
00612                                            cookie);
00613 
00614       
00615       this->upcall_functor ().cancel_timer (*this,
00616                                             n->get_type (),
00617                                             skip_close,
00618                                             cookie);
00619       if (act != 0)
00620         *act = n->get_act ();
00621 
00622       this->cancel_i (n);
00623 
00624       if (recalc)
00625         this->recalc_earliest (last);
00626 
00627       return 1;
00628     }
00629   return 0;
00630 }
00631 
00632 
00633 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00634 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::cancel_i (ACE_Timer_Node_T<TYPE>* n)
00635 {
00636   this->unlink (n);
00637   this->free_node (n);
00638 }
00639 
00640 
00641 
00642 
00643 
00644 
00645 
00646 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00647 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::recalc_earliest
00648   (const ACE_Time_Value& last)
00649 {
00650   
00651   if (this->is_empty ())
00652     return;
00653 
00654   ACE_Time_Value et = ACE_Time_Value::zero;
00655   u_int es = 0;
00656   u_int spoke = this->earliest_spoke_;
00657 
00658   
00659   for (u_int i = 0; i < this->spoke_count_; ++i)
00660     {
00661       ACE_Timer_Node_T<TYPE>* root = this->spokes_[spoke];
00662       ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00663       if (n != root)
00664         {
00665           ACE_Time_Value t = n->get_timer_value ();
00666           if (t < last + this->wheel_time_)
00667             {
00668               this->earliest_spoke_ = spoke;
00669               return;
00670             }
00671           else if (et == ACE_Time_Value::zero || t < et)
00672             {
00673               et = t;
00674               es = spoke;
00675             }
00676         }
00677       if (++spoke >= this->spoke_count_)
00678         spoke = 0;
00679     }
00680 
00681   this->earliest_spoke_ = es;
00682   
00683 }
00684 
00685 
00686 
00687 
00688 
00689 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00690 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
00691 {
00692 #if defined (ACE_HAS_DUMP)
00693   ACE_TRACE ("ACE_Timer_Wheel_T::dump");
00694   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00695 
00696   ACE_DEBUG ((LM_DEBUG,
00697     ACE_LIB_TEXT ("\nspoke_count_ = %d"), this->spoke_count_));
00698   ACE_DEBUG ((LM_DEBUG,
00699     ACE_LIB_TEXT ("\nresolution_ = %d"), 1 << this->res_bits_));
00700   ACE_DEBUG ((LM_DEBUG,
00701     ACE_LIB_TEXT ("\nwheel_ = \n")));
00702 
00703   for (u_int i = 0; i < this->spoke_count_; ++i)
00704     {
00705       ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("%d\n"), i));
00706       ACE_Timer_Node_T<TYPE>* root = this->spokes_[i];
00707       for (ACE_Timer_Node_T<TYPE>* n = root->get_next ();
00708            n != root;
00709            n = n->get_next ())
00710         {
00711           n->dump ();
00712         }
00713     }
00714 
00715   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00716 #endif 
00717 }
00718 
00719 
00720 
00721 
00722 
00723 
00724 
00725 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
00726 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first (void)
00727 {
00728   ACE_TRACE ("ACE_Timer_Wheel_T::remove_first");
00729   return remove_first_expired (ACE_Time_Value::max_time);
00730 }
00731 
00732 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00733 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::unlink (ACE_Timer_Node_T<TYPE>* n)
00734 {
00735   ACE_TRACE ("ACE_Timer_Wheel_T::unlink");
00736   --timer_count_;
00737   n->get_prev ()->set_next (n->get_next ());
00738   n->get_next ()->set_prev (n->get_prev ());
00739   n->set_prev (0);
00740   n->set_next (0);
00741 }
00742 
00743 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
00744 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::remove_first_expired (const ACE_Time_Value& now)
00745 {
00746   ACE_Timer_Node_T<TYPE>* n = this->get_first ();
00747   if (n != 0 && n->get_timer_value() <= now)
00748     {
00749       this->unlink (n);
00750       this->recalc_earliest (n->get_timer_value ());
00751       return n;
00752     }
00753   return 0;
00754 }
00755 
00756 
00757 
00758 
00759 
00760 
00761 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00762 ACE_Timer_Node_T<TYPE>*
00763 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first (void)
00764 {
00765   ACE_TRACE ("ACE_Timer_Wheel_T::get_first");
00766   return this->get_first_i ();
00767 }
00768 
00769 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00770 ACE_Timer_Node_T<TYPE>*
00771 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::get_first_i (void) const
00772 {
00773   ACE_Timer_Node_T<TYPE>* root = this->spokes_[this->earliest_spoke_];
00774   ACE_Timer_Node_T<TYPE>* first = root->get_next ();
00775   if (first != root)
00776     return first;
00777   return 0;
00778 }
00779 
00780 
00781 
00782 
00783 
00784 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00785 ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>&
00786 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::iter (void)
00787 {
00788   this->iterator_->first ();
00789   return *this->iterator_;
00790 }
00791 
00792 
00793 
00794 
00795 
00796 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00797 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire ()
00798 {
00799   return ACE_Timer_Queue_T<TYPE,FUNCTOR,ACE_LOCK>::expire ();
00800 }
00801 
00802 
00803 
00804 
00805 
00806 
00807 
00808 
00809 
00810 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00811 ACE_Timer_Wheel_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value& cur_time)
00812 {
00813   ACE_TRACE ("ACE_Timer_Wheel_T::expire");
00814   ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00815 
00816   int expcount = 0;
00817   ACE_Timer_Node_T<TYPE>* n = this->remove_first_expired (cur_time);
00818 
00819   while (n != 0)
00820     {
00821       ++expcount;
00822 
00823       
00824 
00825       ACE_Timer_Node_Dispatch_Info_T<TYPE> info;
00826 
00827       
00828       n->get_dispatch_info (info);
00829 
00830       if (n->get_interval () > ACE_Time_Value::zero)
00831         {
00832           
00833           
00834           do
00835             n->set_timer_value (n->get_timer_value () +
00836                                 n->get_interval ());
00837           while (n->get_timer_value () <= 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> int
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