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