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