Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

Timer_Queue_T.cpp

Go to the documentation of this file.
00001 // $Id: Timer_Queue_T.cpp,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $
00002 
00003 #ifndef ACE_TIMER_QUEUE_T_C
00004 #define ACE_TIMER_QUEUE_T_C
00005 
00006 #include "ace/Synch.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif /* ACE_LACKS_PRAGMA_ONCE */
00011 
00012 #include "ace/Signal.h"
00013 #include "ace/Timer_Queue_T.h"
00014 #include "ace/Log_Msg.h"
00015 
00016 #if !defined (__ACE_INLINE__)
00017 #include "ace/Timer_Queue_T.i"
00018 #endif /* __ACE_INLINE__ */
00019 
00020 ACE_RCSID(ace, Timer_Queue_T, "$Id: Timer_Queue_T.cpp,v 1.1.1.4 2003/02/21 18:36:32 chad Exp $")
00021 
00022 template <class TYPE> void
00023 ACE_Timer_Node_T<TYPE>::dump (void) const
00024 {
00025   ACE_TRACE ("ACE_Timer_Node_T::dump");
00026   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00027   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nact_ = %x"), this->act_));
00028   this->timer_value_.dump ();
00029   this->interval_.dump ();
00030   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nprev_ = %x"), this->prev_));
00031   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nnext_ = %x"), this->next_));
00032   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntimer_id_ = %d\n"), this->timer_id_));
00033   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00034 }
00035 
00036 template <class TYPE>
00037 ACE_Timer_Node_T<TYPE>::ACE_Timer_Node_T (void)
00038 {
00039   ACE_TRACE ("ACE_Timer_Node_T::ACE_Timer_Node_T");
00040 }
00041 
00042 template <class TYPE>
00043 ACE_Timer_Node_T<TYPE>::~ACE_Timer_Node_T (void)
00044 {
00045   ACE_TRACE ("ACE_Timer_Node_T::~ACE_Timer_Node_T");
00046 }
00047 
00048 
00049 
00050 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00051 ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Queue_Iterator_T (void)
00052 {
00053 }
00054 
00055 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00056 ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Queue_Iterator_T (void)
00057 {
00058 }
00059 
00060 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Time_Value *
00061 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *max_wait_time)
00062 {
00063   ACE_TRACE ("ACE_Timer_Queue_T::calculate_timeout");
00064   ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, max_wait_time));
00065 
00066   if (this->is_empty ())
00067     // Nothing on the Timer_Queue, so use whatever the caller gave us.
00068     return max_wait_time;
00069   else
00070     {
00071       ACE_Time_Value cur_time = this->gettimeofday ();
00072 
00073       if (this->earliest_time () > cur_time)
00074         {
00075           // The earliest item on the Timer_Queue is still in the
00076           // future.  Therefore, use the smaller of (1) caller's wait
00077           // time or (2) the delta time between now and the earliest
00078           // time on the Timer_Queue.
00079 
00080           this->timeout_ = this->earliest_time () - cur_time;
00081           if (max_wait_time == 0 || *max_wait_time > timeout_)
00082             return &this->timeout_;
00083           else
00084             return max_wait_time;
00085         }
00086       else
00087         {
00088           // The earliest item on the Timer_Queue is now in the past.
00089           // Therefore, we've got to "poll" the Reactor, i.e., it must
00090           // just check the descriptors and then dispatch timers, etc.
00091           this->timeout_ = ACE_Time_Value::zero;
00092           return &this->timeout_;
00093         }
00094     }
00095 }
00096 
00097 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Time_Value *
00098 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *max_wait_time,
00099                                                                ACE_Time_Value *the_timeout)
00100 {
00101   ACE_TRACE ("ACE_Timer_Queue_T::calculate_timeout");
00102 
00103   if (the_timeout == 0)
00104     return 0;
00105 
00106   if (this->is_empty ())
00107     {
00108       // Nothing on the Timer_Queue, so use whatever the caller gave us.
00109       if (max_wait_time)
00110         *the_timeout = *max_wait_time;
00111       else
00112         return 0;
00113     }
00114   else
00115     {
00116       ACE_Time_Value cur_time = this->gettimeofday ();
00117 
00118       if (this->earliest_time () > cur_time)
00119         {
00120           // The earliest item on the Timer_Queue is still in the
00121           // future.  Therefore, use the smaller of (1) caller's wait
00122           // time or (2) the delta time between now and the earliest
00123           // time on the Timer_Queue.
00124 
00125           *the_timeout = this->earliest_time () - cur_time;
00126           if (!(max_wait_time == 0 || *max_wait_time > *the_timeout))
00127             *the_timeout = *max_wait_time;
00128         }
00129       else
00130         {
00131           // The earliest item on the Timer_Queue is now in the past.
00132           // Therefore, we've got to "poll" the Reactor, i.e., it must
00133           // just check the descriptors and then dispatch timers, etc.
00134           *the_timeout = ACE_Time_Value::zero;
00135         }
00136     }
00137   return the_timeout;
00138 }
00139 
00140 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00141 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
00142 {
00143   ACE_TRACE ("ACE_Timer_Queue_T::dump");
00144   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00145   this->timeout_.dump ();
00146   this->timer_skew_.dump ();
00147   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00148 }
00149 
00150 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00151 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Queue_T (FUNCTOR *upcall_functor,
00152                                                            ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
00153   : gettimeofday_ (ACE_OS::gettimeofday),
00154     delete_upcall_functor_ (upcall_functor == 0),
00155     delete_free_list_ (freelist == 0),
00156     timer_skew_ (0, ACE_TIMER_SKEW)
00157 {
00158   ACE_TRACE ("ACE_Timer_Queue_T::ACE_Timer_Queue_T");
00159 
00160   if (!freelist)
00161     ACE_NEW (free_list_,
00162              (ACE_Locked_Free_List<ACE_Timer_Node_T<TYPE>,ACE_Null_Mutex>));
00163   else
00164     free_list_ = freelist;
00165 
00166   if (!upcall_functor)
00167     ACE_NEW (upcall_functor_,
00168              FUNCTOR);
00169   else
00170     upcall_functor_ = upcall_functor;
00171 }
00172 
00173 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00174 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Queue_T (void)
00175 {
00176   ACE_TRACE ("ACE_Timer_Queue_T::~ACE_Timer_Queue_T");
00177 
00178   // Cleanup the functor and free_list on the way out
00179   if (this->delete_upcall_functor_)
00180     delete this->upcall_functor_;
00181 
00182   if (this->delete_free_list_)
00183     delete this->free_list_;
00184 }
00185 
00186 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
00187 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::alloc_node (void)
00188 {
00189   return this->free_list_->remove ();
00190 }
00191 
00192 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00193 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::free_node (ACE_Timer_Node_T<TYPE> *node)
00194 {
00195   this->free_list_->add (node);
00196 }
00197 
00198 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_LOCK &
00199 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::mutex (void)
00200 {
00201   return this->mutex_;
00202 }
00203 
00204 
00205 // Run the <handle_timeout> method for all Timers whose values are <=
00206 // <cur_time>.
00207 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00208 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value &cur_time)
00209 {
00210   ACE_TRACE ("ACE_Timer_Queue_T::expire");
00211   ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00212 
00213   // Keep looping while there are timers remaining and the earliest
00214   // timer is <= the <cur_time> passed in to the method.
00215 
00216   if (this->is_empty ())
00217     return 0;
00218 
00219   int number_of_timers_expired = 0;
00220   int result = 0;
00221 
00222   ACE_Timer_Node_Dispatch_Info_T<TYPE> info;
00223 
00224   while ((result = this->dispatch_info_i (cur_time,
00225                                           info)) != 0)
00226     {
00227       // call the functor
00228       this->upcall (info.type_, info.act_, cur_time);
00229 
00230       number_of_timers_expired++;
00231 
00232     }
00233 
00234   ACE_UNUSED_ARG (result);
00235   return number_of_timers_expired;
00236 }
00237 
00238 
00239 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00240 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dispatch_info_i (const ACE_Time_Value &cur_time,
00241                                                              ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
00242 {
00243   ACE_TRACE ("ACE_Timer_Queue_T::dispatch_info_i");
00244 
00245   if (this->is_empty ())
00246     return 0;
00247 
00248   ACE_Timer_Node_T<TYPE> *expired = 0;
00249 
00250   if (this->earliest_time () <= cur_time)
00251     {
00252       expired = this->remove_first ();
00253 
00254       // Get the dispatch info
00255       expired->get_dispatch_info (info);
00256 
00257       // Check if this is an interval timer.
00258       if (expired->get_interval () > ACE_Time_Value::zero)
00259         {
00260           // Make sure that we skip past values that have already
00261           // "expired".
00262           do
00263             expired->set_timer_value (expired->get_timer_value () + expired->get_interval ());
00264           while (expired->get_timer_value () <= cur_time);
00265 
00266           // Since this is an interval timer, we need to reschedule
00267           // it.
00268           this->reschedule (expired);
00269         }
00270       else
00271         {
00272           // Call the factory method to free up the node.
00273           this->free_node (expired);
00274         }
00275 
00276       return 1;
00277     }
00278 
00279   return 0;
00280 }
00281 
00282 
00283 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00284 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::return_node (ACE_Timer_Node_T<TYPE> *node)
00285 {
00286   ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));
00287   this->free_node (node);
00288 }
00289 
00290 
00291 template <class ACE_LOCK>
00292 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::ACE_Event_Handler_Handle_Timeout_Upcall (void)
00293 {
00294 }
00295 
00296 template <class ACE_LOCK>
00297 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::~ACE_Event_Handler_Handle_Timeout_Upcall (void)
00298 {
00299 }
00300 
00301 template <class ACE_LOCK> int
00302 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::timeout (TIMER_QUEUE &timer_queue,
00303                                                             ACE_Event_Handler *handler,
00304                                                             const void *act,
00305                                                             const ACE_Time_Value &cur_time)
00306 {
00307   // Upcall to the <handler>s handle_timeout() method.
00308   if (handler->handle_timeout (cur_time, act) == -1)
00309     {
00310 #if 0
00311       // Commented out until we figure out how to break the coupling that results...
00312       if (handler->reactor ())
00313         // Call the reactor's cancel_timer() method to minimize locking.
00314         handler->reactor ()->cancel_timer (handler, 0); // 0 means "call handle_close()".
00315       else
00316 #endif
00317         // Upcall to the handler's handle_timeout method.
00318         timer_queue.cancel (handler, 0); 
00319     }
00320 
00321   return 0;
00322 }
00323 
00324 template <class ACE_LOCK> int
00325 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::cancellation (TIMER_QUEUE &timer_queue,
00326                                                                  ACE_Event_Handler *handler)
00327 {
00328   ACE_UNUSED_ARG (timer_queue);
00329 
00330   // Upcall to the <handler>s handle_close method
00331   handler->handle_close (ACE_INVALID_HANDLE,
00332                          ACE_Event_Handler::TIMER_MASK);
00333   return 0;
00334 }
00335 
00336 template <class ACE_LOCK> int
00337 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::deletion (TIMER_QUEUE &timer_queue,
00338                                                              ACE_Event_Handler *handler,
00339                                                              const void *arg)
00340 {
00341   ACE_UNUSED_ARG (timer_queue);
00342   ACE_UNUSED_ARG (handler);
00343   ACE_UNUSED_ARG (arg);
00344 
00345   // Does nothing
00346 
00347   return 0;
00348 }
00349 
00350 #endif /* ACE_TIMER_QUEUE_T_C*/

Generated on Mon Jun 16 11:21:52 2003 for ACE by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002