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