00001
00002
00003 #ifndef ACE_TIMER_QUEUE_T_CPP
00004 #define ACE_TIMER_QUEUE_T_CPP
00005
00006 #include "ace/config-all.h"
00007
00008 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00009 # pragma once
00010 #endif
00011
00012 #include "ace/Timer_Queue_T.h"
00013 #include "ace/Guard_T.h"
00014 #include "ace/Log_Msg.h"
00015 #include "ace/Reactor_Timer_Interface.h"
00016 #include "ace/Null_Mutex.h"
00017 #include "ace/OS_NS_sys_time.h"
00018
00019 #if !defined (__ACE_INLINE__)
00020 #include "ace/Timer_Queue_T.inl"
00021 #endif
00022
00023 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00024
00025
00026
00027
00028 #if !defined (ACE_TIMER_SKEW)
00029 # define ACE_TIMER_SKEW 0
00030 #endif
00031
00032 template <class TYPE> void
00033 ACE_Timer_Node_T<TYPE>::dump (void) const
00034 {
00035 #if defined (ACE_HAS_DUMP)
00036 ACE_TRACE ("ACE_Timer_Node_T::dump");
00037 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00038 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nact_ = %x"), this->act_));
00039 this->timer_value_.dump ();
00040 this->interval_.dump ();
00041 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nprev_ = %x"), this->prev_));
00042 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\nnext_ = %x"), this->next_));
00043 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ntimer_id_ = %d\n"), this->timer_id_));
00044 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00045 #endif
00046 }
00047
00048 template <class TYPE>
00049 ACE_Timer_Node_T<TYPE>::ACE_Timer_Node_T (void)
00050 {
00051 ACE_TRACE ("ACE_Timer_Node_T::ACE_Timer_Node_T");
00052 }
00053
00054 template <class TYPE>
00055 ACE_Timer_Node_T<TYPE>::~ACE_Timer_Node_T (void)
00056 {
00057 ACE_TRACE ("ACE_Timer_Node_T::~ACE_Timer_Node_T");
00058 }
00059
00060 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00061 ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Queue_Iterator_T (void)
00062 {
00063 }
00064
00065 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00066 ACE_Timer_Queue_Iterator_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Queue_Iterator_T (void)
00067 {
00068 }
00069
00070 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Time_Value *
00071 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *max_wait_time)
00072 {
00073 ACE_TRACE ("ACE_Timer_Queue_T::calculate_timeout");
00074 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, max_wait_time));
00075
00076 if (this->is_empty ())
00077
00078 return max_wait_time;
00079 else
00080 {
00081 ACE_Time_Value cur_time = this->gettimeofday ();
00082
00083 if (this->earliest_time () > cur_time)
00084 {
00085
00086
00087
00088
00089
00090 this->timeout_ = this->earliest_time () - cur_time;
00091 if (max_wait_time == 0 || *max_wait_time > timeout_)
00092 return &this->timeout_;
00093 else
00094 return max_wait_time;
00095 }
00096 else
00097 {
00098
00099
00100
00101 this->timeout_ = ACE_Time_Value::zero;
00102 return &this->timeout_;
00103 }
00104 }
00105 }
00106
00107 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Time_Value *
00108 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::calculate_timeout (ACE_Time_Value *max_wait_time,
00109 ACE_Time_Value *the_timeout)
00110 {
00111 ACE_TRACE ("ACE_Timer_Queue_T::calculate_timeout");
00112
00113 if (the_timeout == 0)
00114 return 0;
00115
00116 if (this->is_empty ())
00117 {
00118
00119 if (max_wait_time)
00120 *the_timeout = *max_wait_time;
00121 else
00122 return 0;
00123 }
00124 else
00125 {
00126 ACE_Time_Value cur_time = this->gettimeofday ();
00127
00128 if (this->earliest_time () > cur_time)
00129 {
00130
00131
00132
00133
00134
00135 *the_timeout = this->earliest_time () - cur_time;
00136 if (!(max_wait_time == 0 || *max_wait_time > *the_timeout))
00137 *the_timeout = *max_wait_time;
00138 }
00139 else
00140 {
00141
00142
00143
00144 *the_timeout = ACE_Time_Value::zero;
00145 }
00146 }
00147 return the_timeout;
00148 }
00149
00150 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00151 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dump (void) const
00152 {
00153 #if defined (ACE_HAS_DUMP)
00154 ACE_TRACE ("ACE_Timer_Queue_T::dump");
00155 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00156 this->timeout_.dump ();
00157 this->timer_skew_.dump ();
00158 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00159 #endif
00160 }
00161
00162 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00163 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::ACE_Timer_Queue_T (FUNCTOR *upcall_functor,
00164 ACE_Free_List<ACE_Timer_Node_T <TYPE> > *freelist)
00165 : gettimeofday_ (ACE_OS::gettimeofday),
00166 delete_upcall_functor_ (upcall_functor == 0),
00167 delete_free_list_ (freelist == 0),
00168 timer_skew_ (0, ACE_TIMER_SKEW)
00169 {
00170 ACE_TRACE ("ACE_Timer_Queue_T::ACE_Timer_Queue_T");
00171
00172 if (!freelist)
00173 ACE_NEW (free_list_,
00174 (ACE_Locked_Free_List<ACE_Timer_Node_T<TYPE>,ACE_Null_Mutex>));
00175 else
00176 free_list_ = freelist;
00177
00178 if (!upcall_functor)
00179 ACE_NEW (upcall_functor_,
00180 FUNCTOR);
00181 else
00182 upcall_functor_ = upcall_functor;
00183 }
00184
00185 template <class TYPE, class FUNCTOR, class ACE_LOCK>
00186 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::~ACE_Timer_Queue_T (void)
00187 {
00188 ACE_TRACE ("ACE_Timer_Queue_T::~ACE_Timer_Queue_T");
00189
00190
00191 if (this->delete_upcall_functor_)
00192 delete this->upcall_functor_;
00193
00194 if (this->delete_free_list_)
00195 delete this->free_list_;
00196 }
00197
00198 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_Timer_Node_T<TYPE> *
00199 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::alloc_node (void)
00200 {
00201 return this->free_list_->remove ();
00202 }
00203
00204 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00205 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::free_node (ACE_Timer_Node_T<TYPE> *node)
00206 {
00207 this->free_list_->add (node);
00208 }
00209
00210 template <class TYPE, class FUNCTOR, class ACE_LOCK> ACE_LOCK &
00211 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::mutex (void)
00212 {
00213 return this->mutex_;
00214 }
00215
00216 template <class TYPE, class FUNCTOR, class ACE_LOCK> long
00217 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::schedule (const TYPE &type,
00218 const void *act,
00219 const ACE_Time_Value &future_time,
00220 const ACE_Time_Value &interval)
00221 {
00222 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00223
00224
00225 long const result =
00226 this->schedule_i (type,
00227 act,
00228 future_time,
00229 interval);
00230
00231
00232 if (result == -1)
00233 return result;
00234
00235
00236 this->upcall_functor ().registration (*this,
00237 type,
00238 act);
00239
00240
00241 return result;
00242 }
00243
00244
00245
00246 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00247 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::expire (const ACE_Time_Value &cur_time)
00248 {
00249 ACE_TRACE ("ACE_Timer_Queue_T::expire");
00250 ACE_MT (ACE_GUARD_RETURN (ACE_LOCK, ace_mon, this->mutex_, -1));
00251
00252
00253
00254
00255 if (this->is_empty ())
00256 return 0;
00257
00258 int number_of_timers_expired = 0;
00259 int result = 0;
00260
00261 ACE_Timer_Node_Dispatch_Info_T<TYPE> info;
00262
00263 while ((result = this->dispatch_info_i (cur_time,
00264 info)) != 0)
00265 {
00266 const void *upcall_act = 0;
00267
00268 this->preinvoke (info, cur_time, upcall_act);
00269
00270 this->upcall (info, cur_time);
00271
00272 this->postinvoke (info, cur_time, upcall_act);
00273
00274 ++number_of_timers_expired;
00275
00276 }
00277
00278 ACE_UNUSED_ARG (result);
00279 return number_of_timers_expired;
00280 }
00281
00282 template <class TYPE, class FUNCTOR, class ACE_LOCK> int
00283 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::dispatch_info_i (const ACE_Time_Value &cur_time,
00284 ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
00285 {
00286 ACE_TRACE ("ACE_Timer_Queue_T::dispatch_info_i");
00287
00288 if (this->is_empty ())
00289 return 0;
00290
00291 ACE_Timer_Node_T<TYPE> *expired = 0;
00292
00293 if (this->earliest_time () <= cur_time)
00294 {
00295 expired = this->remove_first ();
00296
00297
00298 expired->get_dispatch_info (info);
00299
00300
00301 if (expired->get_interval () > ACE_Time_Value::zero)
00302 {
00303
00304
00305 do
00306 expired->set_timer_value (expired->get_timer_value () +
00307 expired->get_interval ());
00308 while (expired->get_timer_value () <= cur_time);
00309
00310
00311
00312 this->reschedule (expired);
00313 }
00314 else
00315 {
00316
00317 this->free_node (expired);
00318 }
00319
00320 return 1;
00321 }
00322
00323 return 0;
00324 }
00325
00326 template <class TYPE, class FUNCTOR, class ACE_LOCK> void
00327 ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK>::return_node (ACE_Timer_Node_T<TYPE> *node)
00328 {
00329 ACE_MT (ACE_GUARD (ACE_LOCK, ace_mon, this->mutex_));
00330 this->free_node (node);
00331 }
00332
00333
00334 template <class ACE_LOCK>
00335 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::ACE_Event_Handler_Handle_Timeout_Upcall (void)
00336 {
00337 }
00338
00339 template <class ACE_LOCK>
00340 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::~ACE_Event_Handler_Handle_Timeout_Upcall (void)
00341 {
00342 }
00343
00344 template <class ACE_LOCK> int
00345 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::registration (TIMER_QUEUE &,
00346 ACE_Event_Handler *event_handler,
00347 const void *)
00348 {
00349 event_handler->add_reference ();
00350 return 0;
00351 }
00352
00353 template <class ACE_LOCK> int
00354 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::preinvoke (TIMER_QUEUE & ,
00355 ACE_Event_Handler *event_handler,
00356 const void * ,
00357 int ,
00358 const ACE_Time_Value & ,
00359 const void *&upcall_act)
00360 {
00361 int requires_reference_counting =
00362 event_handler->reference_counting_policy ().value () ==
00363 ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
00364
00365 if (requires_reference_counting)
00366 {
00367 event_handler->add_reference ();
00368
00369 upcall_act = &this->requires_reference_counting_;
00370 }
00371
00372 return 0;
00373 }
00374
00375 template <class ACE_LOCK> int
00376 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::postinvoke (TIMER_QUEUE & ,
00377 ACE_Event_Handler *event_handler,
00378 const void * ,
00379 int ,
00380 const ACE_Time_Value & ,
00381 const void *upcall_act)
00382 {
00383 if (upcall_act == &this->requires_reference_counting_)
00384 {
00385 event_handler->remove_reference ();
00386 }
00387
00388 return 0;
00389 }
00390
00391 template <class ACE_LOCK> int
00392 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::timeout (TIMER_QUEUE &timer_queue,
00393 ACE_Event_Handler *event_handler,
00394 const void *act,
00395 int recurring_timer,
00396 const ACE_Time_Value &cur_time)
00397 {
00398 int requires_reference_counting = 0;
00399
00400 if (!recurring_timer)
00401 {
00402 requires_reference_counting =
00403 event_handler->reference_counting_policy ().value () ==
00404 ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
00405 }
00406
00407
00408 if (event_handler->handle_timeout (cur_time, act) == -1)
00409 {
00410 if (event_handler->reactor ())
00411 event_handler->reactor_timer_interface ()->cancel_timer (event_handler, 0);
00412 else
00413 timer_queue.cancel (event_handler, 0);
00414 }
00415
00416 if (!recurring_timer &&
00417 requires_reference_counting)
00418 {
00419 event_handler->remove_reference ();
00420 }
00421
00422 return 0;
00423 }
00424
00425 template <class ACE_LOCK> int
00426 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::cancel_type (TIMER_QUEUE &,
00427 ACE_Event_Handler *event_handler,
00428 int dont_call,
00429 int &requires_reference_counting)
00430 {
00431 requires_reference_counting =
00432 event_handler->reference_counting_policy ().value () ==
00433 ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
00434
00435
00436 if (dont_call == 0)
00437 event_handler->handle_close (ACE_INVALID_HANDLE,
00438 ACE_Event_Handler::TIMER_MASK);
00439
00440 return 0;
00441 }
00442
00443 template <class ACE_LOCK> int
00444 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::cancel_timer (TIMER_QUEUE &,
00445 ACE_Event_Handler *event_handler,
00446 int,
00447 int requires_reference_counting)
00448 {
00449 if (requires_reference_counting)
00450 event_handler->remove_reference ();
00451
00452 return 0;
00453 }
00454
00455 template <class ACE_LOCK> int
00456 ACE_Event_Handler_Handle_Timeout_Upcall<ACE_LOCK>::deletion (TIMER_QUEUE &timer_queue,
00457 ACE_Event_Handler *event_handler,
00458 const void *)
00459 {
00460 int requires_reference_counting = 0;
00461
00462 this->cancel_type (timer_queue,
00463 event_handler,
00464 0,
00465 requires_reference_counting);
00466
00467 this->cancel_timer (timer_queue,
00468 event_handler,
00469 0,
00470 requires_reference_counting);
00471
00472 return 0;
00473 }
00474
00475 ACE_END_VERSIONED_NAMESPACE_DECL
00476
00477 #endif