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