6. Use the ID whenever possible to cancel the ACE_Event_Handler timer.
ACE Reactor provides two methods to cancel the Timer:
Virtual int cancel_timer (ACE_Event_Handler * event_handler,
Int dont_call_handle_close = 1 );
Virtual int cancel_timer (long timer_id,
Const void ** arg = 0,
Int dont_call_handle_close = 1 );
One is to use the timer ID to cancel the timer, which is the return value of the timer, and the other is to use the corresponding ACE_Event_Handler pointer to cancel the timer. Generally, using the ACE_Event_Handler pointer to cancel the timer is undoubtedly the easiest method, but this method is not an efficient implementation. Therefore, if your program has a large number of timer settings to cancel the operation, we recommend that you use the ID to cancel the timer as much as possible. We use two Timer_Queue methods, ACE_Timer_Heap and ACE_Timer_Has, to analyze them.
6.1 how to cancel ACE_Timer_Heap according to Event_handler
First, select the most common example of Time_Queue ACE_Timer_Heap. The code for disabling the timer using ACE_Event_Handler is:
Template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Heap_T <TYPE, FUNCTOR, ACE_LOCK >:: cancel (const TYPE & type,
Int dont_call)
{
// Try to locate the ACE_Timer_Node that matches the timer_id.
// Compare all ACE_Event_Handler pointers cyclically
For (size_t I = 0; I <this-> cur_size _;)
{
If (this-> heap _ [I]-> get_type () = type)
{
..................
}
}
The code for disabling TIMER_ID is as follows, which uses the array subscript for locating.
Template <class TYPE, class FUNCTOR, class ACE_LOCK> int
ACE_Timer_Heap_T <TYPE, FUNCTOR, ACE_LOCK >:: cancel (long timer_id,
Const void ** act,
Int dont_call)
{
// The array subscript operation makes the speed extremely fast.
Ssize_t timer_node_slot = this-> timer_ids _ [timer_id];
......
// Follow up the array ID for operations
Else
{
ACE_Timer_Node_T <TYPE> * temp =
This-> remove (timer_node_slot );
}
}
For ACE_Timer_Heap, the average time complexity of canceling the timer using the ACE_Event_Handler pointer should be O (N ). Because one Event_handler of ACE may correspond to multiple timers, you must check all the related timers to cancel them.
6.2 how to cancel ACE_Timer_Hash according to Event_handler
For Timer_Hash, the code for disabling the timer through ACE_Event_Handler is:
Template <class TYPE, class FUNCTOR, class ACE_LOCK, class BUCKET> int
ACE_Timer_Hash_T <TYPE, FUNCTOR, ACE_LOCK, BUCKET >:: cancel (const TYPE & type,
Int dont_call)
{
Hash_Token <TYPE> ** timer_ids = 0;
// According to Event Handler, there is a timer new array.
ACE_NEW_RETURN (timer_ids,
Hash_Token <TYPE> * [this-> size _],
-1 );
Size_t pos = 0;
// Cancel the task based on the number of timers
For (I = 0;
I <this-> table_size _;
++ I)
{
ACE_Timer_Queue_Iterator_T <TYPE,
ACE_Timer_Hash_Upcall <TYPE, FUNCTOR, ACE_LOCK>,
ACE_Null_Mutex> & iter =
This-> table _ [I]-> iter ();
We can see that the cancel of Timer_Hash is a little better than the cancel (Event_Handler) of ACE_Timer_Heap. However, there are also new and delete operations, which are not efficient operations.
Therefore, we recommend that you use the ID of the timer to cancel the timer more efficiently.