00001 
00002 
00003 #ifndef ACE_TIMER_QUEUE_ADAPTERS_CPP
00004 #define ACE_TIMER_QUEUE_ADAPTERS_CPP
00005 
00006 #include "ace/Timer_Queue_Adapters.h"
00007 
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif 
00011 
00012 # if !defined (__ACE_INLINE__)
00013 #  include "ace/Timer_Queue_Adapters.inl"
00014 # endif 
00015 
00016 #include "ace/OS_NS_unistd.h"
00017 #include "ace/OS_NS_sys_time.h"
00018 
00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00020 
00021 template <class TQ> TQ &
00022 ACE_Async_Timer_Queue_Adapter<TQ>::timer_queue (void)
00023 {
00024   return this->timer_queue_;
00025 }
00026 
00027 template <class TQ> int
00028 ACE_Async_Timer_Queue_Adapter<TQ>::cancel (long timer_id,
00029                                            const void **act)
00030 {
00031   
00032   ACE_Sig_Guard sg (&this->mask_);
00033   ACE_UNUSED_ARG (sg);
00034 
00035   return this->timer_queue_.cancel (timer_id, act);
00036 }
00037 
00038 template <class TQ> int
00039 ACE_Async_Timer_Queue_Adapter<TQ>::expire (void)
00040 {
00041   
00042   ACE_Sig_Guard sg (&this->mask_);
00043   ACE_UNUSED_ARG (sg);
00044 
00045   return this->timer_queue_.expire ();
00046 }
00047 
00048 template <class TQ> int
00049 ACE_Async_Timer_Queue_Adapter<TQ>::schedule_ualarm (void)
00050 {
00051   ACE_Time_Value tv = this->timer_queue_.earliest_time ()
00052     - ACE_OS::gettimeofday ();
00053 
00054   
00055   
00056   if (tv < ACE_Time_Value::zero)
00057     tv = ACE_Time_Value (0, 1);
00058 
00059   
00060   
00061   
00062   ACE_OS::ualarm (tv);
00063   return 0;
00064 }
00065 
00066 template <class TQ> long
00067 ACE_Async_Timer_Queue_Adapter<TQ>::schedule (ACE_Event_Handler *eh,
00068                                              const void *act,
00069                                              const ACE_Time_Value &future_time,
00070                                              const ACE_Time_Value &interval)
00071 {
00072   ACE_UNUSED_ARG (act);
00073   ACE_UNUSED_ARG (interval);
00074 
00075   
00076   ACE_Sig_Guard sg (&this->mask_);
00077   ACE_UNUSED_ARG (sg);
00078 
00079   
00080   long tid = this->timer_queue_.schedule (eh, act, future_time);
00081 
00082   if (tid == -1)
00083     ACE_ERROR_RETURN ((LM_ERROR,
00084                        ACE_LIB_TEXT ("%p\n"),
00085                        ACE_LIB_TEXT ("schedule_timer")),
00086                       -1);
00087 
00088   if (this->schedule_ualarm () == -1)
00089     return 0;
00090 
00091   return tid;
00092 }
00093 
00094 template <class TQ>
00095 ACE_Async_Timer_Queue_Adapter<TQ>::ACE_Async_Timer_Queue_Adapter (ACE_Sig_Set *mask)
00096   
00097   
00098   : mask_ (mask)
00099 {
00100   
00101   
00102   
00103 
00104   ACE_Sig_Action sa ((ACE_SignalHandler) 0,
00105                      this->mask_,
00106                      SA_RESTART);
00107 
00108   if (this->sig_handler_.register_handler (SIGALRM, this, &sa) == -1)
00109     ACE_ERROR ((LM_ERROR,
00110                 ACE_LIB_TEXT ("%p\n"),
00111                 ACE_LIB_TEXT ("register_handler")));
00112 }
00113 
00114 
00115 
00116 
00117 
00118 template <class TQ> int
00119 ACE_Async_Timer_Queue_Adapter<TQ>::handle_signal (int signum,
00120                                                   siginfo_t *,
00121                                                   ucontext_t *)
00122 {
00123   switch (signum)
00124     {
00125     case SIGALRM:
00126       {
00127         
00128 
00129         
00130         
00131         this->timer_queue_.expire ();
00132 
00133         
00134 
00135         
00136         
00137         if (this->timer_queue_.is_empty () == 0)
00138           return this->schedule_ualarm ();
00139         else
00140           return 0;
00141         
00142       }
00143     default:
00144       ACE_ERROR_RETURN ((LM_ERROR,
00145                          "unexpected signal %S\n",
00146                          signum),
00147                         -1);
00148       
00149     }
00150 }
00151 
00152 template<class TQ>
00153 ACE_Thread_Timer_Queue_Adapter<TQ>::ACE_Thread_Timer_Queue_Adapter (ACE_Thread_Manager *tm,
00154                                                                     TQ* timer_queue)
00155   : ACE_Task_Base (tm),
00156     timer_queue_(timer_queue),
00157     delete_timer_queue_(0),
00158     condition_ (mutex_),
00159     active_ (1), 
00160     thr_id_ (ACE_OS::NULL_thread)
00161 {
00162   if (timer_queue_ == 0)
00163     {
00164       ACE_NEW (this->timer_queue_,
00165                TQ);
00166       this->delete_timer_queue_ = 1;
00167     }
00168 }
00169 
00170 template<class TQ>
00171 ACE_Thread_Timer_Queue_Adapter<TQ>::~ACE_Thread_Timer_Queue_Adapter (void)
00172 {
00173   if (this->delete_timer_queue_)
00174     {
00175       delete this->timer_queue_;
00176       this->timer_queue_ = 0;
00177       this->delete_timer_queue_ = 0;
00178     }
00179 }
00180 
00181 template<class TQ> ACE_SYNCH_RECURSIVE_MUTEX &
00182 ACE_Thread_Timer_Queue_Adapter<TQ>::mutex (void)
00183 {
00184   return this->mutex_;
00185 }
00186 
00187 template<class TQ> long
00188 ACE_Thread_Timer_Queue_Adapter<TQ>::schedule
00189     (ACE_Event_Handler* handler,
00190      const void *act,
00191      const ACE_Time_Value &future_time,
00192      const ACE_Time_Value &interval)
00193 {
00194   ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1);
00195 
00196   long result = this->timer_queue_->schedule (handler, act, future_time, interval);
00197   this->condition_.signal ();
00198   return result;
00199 }
00200 
00201 template<class TQ> int
00202 ACE_Thread_Timer_Queue_Adapter<TQ>::cancel (long timer_id,
00203                                             const void **act)
00204 {
00205   ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1);
00206 
00207   int result = this->timer_queue_->cancel (timer_id, act);
00208   condition_.signal ();
00209   return result;
00210 }
00211 
00212 template<class TQ> void
00213 ACE_Thread_Timer_Queue_Adapter<TQ>::deactivate (void)
00214 {
00215   ACE_GUARD (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_);
00216 
00217   this->active_ = 0;
00218   this->condition_.signal ();
00219 }
00220 
00221 template<class TQ> int
00222 ACE_Thread_Timer_Queue_Adapter<TQ>::svc (void)
00223 {
00224   ACE_GUARD_RETURN (ACE_SYNCH_RECURSIVE_MUTEX, guard, this->mutex_, -1);
00225 
00226   this->thr_id_ = ACE_Thread::self ();
00227 
00228   
00229   
00230   
00231   
00232   
00233   
00234 # if !defined (ACE_LACKS_PTHREAD_CANCEL)
00235   ACE_PTHREAD_CLEANUP_PUSH (&this->condition_.mutex ().get_nesting_mutex ());
00236 # endif 
00237 
00238   while (this->active_)
00239     {
00240 # if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
00241       
00242       
00243       
00244       
00245       
00246       mutex_.release ();
00247       this->dispatch_commands ();
00248 
00249       
00250       
00251       mutex_.acquire ();
00252 # endif 
00253 
00254       
00255       if (this->timer_queue_->is_empty ())
00256         this->condition_.wait ();
00257       else
00258         {
00259           
00260           
00261           const ACE_Time_Value tv_curr = this->timer_queue_->gettimeofday ();
00262           const ACE_Time_Value tv_earl = this->timer_queue_->earliest_time ();
00263  
00264           if (tv_earl > tv_curr)
00265             {
00266               
00267               
00268               
00269               const ACE_Time_Value tv = ACE_OS::gettimeofday () + (tv_earl - tv_curr);  
00270               
00271               
00272               this->condition_.wait (&tv);
00273             }
00274         }
00275 
00276       
00277       this->timer_queue_->expire ();
00278     }
00279 
00280    
00281 # if !defined (ACE_LACKS_PTHREAD_CANCEL)
00282   ACE_PTHREAD_CLEANUP_POP (0);
00283 # endif 
00284 
00285   return 0;
00286 }
00287 
00288 template<class TQ> int
00289 ACE_Thread_Timer_Queue_Adapter<TQ>::activate (long flags,
00290                                               int ,
00291                                               int ,
00292                                               long priority,
00293                                               int grp_id,
00294                                               ACE_Task_Base *task,
00295                                               ACE_hthread_t thread_handles[],
00296                                               void *stack[],
00297                                               size_t stack_size[],
00298                                               ACE_thread_t thread_names[])
00299 {
00300   
00301   ACE_UNUSED_ARG (thread_handles);
00302 
00303   
00304   this->active_ = 1;
00305 
00306   
00307   
00308   return ACE_Task_Base::activate (flags, 1, 0, priority, grp_id, task, 0,
00309                                   stack, stack_size, thread_names);
00310 }
00311 
00312 # if defined (ACE_HAS_DEFERRED_TIMER_COMMANDS)
00313 
00314 
00315 
00316 
00317 
00318 
00319 
00320 template<class TQ> int
00321 ACE_Thread_Timer_Queue_Adapter<TQ>::enqueue_command (ACE_Command_Base *cmd,
00322                                                      COMMAND_ENQUEUE_POSITION pos)
00323 {
00324   
00325   ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, this->command_mutex_, -1);
00326 
00327   if (pos == ACE_Thread_Timer_Queue_Adapter<TQ>::TAIL)
00328     return command_queue_.enqueue_tail (cmd);
00329   else
00330     return command_queue_.enqueue_head (cmd);
00331 }
00332 
00333 
00334 
00335 
00336 template<class TQ> int
00337 ACE_Thread_Timer_Queue_Adapter<TQ>::dispatch_commands (void)
00338 {
00339   
00340   ACE_GUARD_RETURN (ACE_SYNCH_MUTEX, guard, this->command_mutex_, -1);
00341 
00342   
00343   ACE_Command_Base *cmd = 0;
00344   while (command_queue_.dequeue_head (cmd) == 0)
00345     if (cmd)
00346       {
00347         cmd->execute ();
00348         delete cmd;
00349       }
00350 
00351   return 0;
00352 }
00353 
00354 # endif 
00355 
00356 ACE_END_VERSIONED_NAMESPACE_DECL
00357 
00358 #endif