基础组件
ACE_Abstract_Timer_Queue
模板类,定时器队列的抽象类
方法都为纯虚函数
ACE_Timer_Queue_Upcall_Base
模板类,继承ACE_Abstract_Timer_Queue,提供回调功能
FUNCTOR:是超时的处理函数,ACE_Event_Handler_Handle_Timeout_Upcall是其中的一个类型,其需要包含下面的方法
- int registration (ACE_Timer_Queue &timer_queue,ACE_Event_Handler *handler,const void *arg)
- int preinvoke (ACE_Timer_Queue &timer_queue, ACE_Event_Handler *handler, const void *arg,int recurring_timer,const ACE_Time_Value &cur_time,const void *&upcall_act)
- int timeout (ACE_Timer_Queue &timer_queue, ACE_Event_Handler *handler,const void *arg,int recurring_timer,const ACE_Time_Value &cur_time)
- int postinvoke(ACE_Timer_Queue &timer_queue, ACE_Event_Handler *handler, const void *arg,int recurring_timer,const ACE_Time_Value &cur_time,const void *&upcall_act)
- int cancel_type (ACE_Timer_Queue &timer_queue,ACE_Event_Handler *handler,int dont_call,int &requires_reference_counting)
- int cancel_timer(ACE_Timer_Queue &timer_queue,ACE_Event_Handler *handler,int dont_call,int requires_reference_counting)
- int deletion (ACE_Timer_Queue &timer_queue,ACE_Event_Handler *handler,const void *arg)
ACE_Timer_Queue_T
模板类,继承ACE_Timer_Queue_Upcall_Base,是其它定时器队列的实现基类。增加了同步机制,以及获取时间策略(主要是获取当前时间)
schedule_i 和reschedule纯虚函数,由具体的定时器队列子类实现
添加定时器
schedule:添加定时器节点,会调用schedule_i,以及调用this->upcall_functor ().registration (*this,type,act);
包含的子类有
- ACE_Timer_Heap_T:堆实现的定时器队列
- ACE_Timer_Hash_T:哈希表实现的定时器队列
- ACE_Timer_List_T:链表实现的定时器队列
- ACE_Timer_Wheel_T:时间轮实现的定时器队列
定时器超时
expire,expire_single是处理定时器超时
在expire方法中,会调用dispatch_info_i方法判断是否有超时的定时器,通过earliest_time看最早的时间是否小于当前时间,如果小于,则删除最早的节点,如果定时器是周期性的,则计算定时器的下一次超时时间,重新添加到队列中,如果不是周期性的,则直接释放定时器
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> int
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::dispatch_info_i (const ACE_Time_Value &cur_time,
ACE_Timer_Node_Dispatch_Info_T<TYPE> &info)
{
ACE_TRACE ("ACE_Timer_Queue_T::dispatch_info_i");
if (this->is_empty ())
return 0;
ACE_Timer_Node_T<TYPE> *expired = 0;
if (this->earliest_time () <= cur_time)
{
expired = this->remove_first ();
// Get the dispatch info
expired->get_dispatch_info (info);
// Check if this is an interval timer.
if (expired->get_interval () > ACE_Time_Value::zero)
{
// Make sure that we skip past values that have already
// "expired".
this->recompute_next_abs_interval_time (expired, cur_time);
// Since this is an interval timer, we need to reschedule
// it.
this->reschedule (expired);
}
else
{
// Call the factory method to free up the node.
this->free_node (expired);
}
return 1;
}
return 0;
}
如果有会调用upcall方法,内部会调用functior的timeout方法
template <class TYPE, class FUNCTOR, class ACE_LOCK, typename TIME_POLICY> ACE_INLINE void
ACE_Timer_Queue_T<TYPE, FUNCTOR, ACE_LOCK, TIME_POLICY>::upcall (ACE_Timer_Node_Dispatch_Info_T<TYPE> &info,
const ACE_Time_Value &cur_time)
{
this->upcall_functor ().timeout (*this,
info.type_,
info.act_,
info.recurring_timer_,
cur_time);
}
而ACE_Event_Handler_Handle_Timeout_Upcall的timeout方法会调用ACE_Event_Handler的handle_timeout方法触发超时操作
int
ACE_Event_Handler_Handle_Timeout_Upcall::
timeout (ACE_Timer_Queue &timer_queue,
ACE_Event_Handler *event_handler,
const void *act,
int recurring_timer,
const ACE_Time_Value &cur_time)
{
int requires_reference_counting = 0;
if (!recurring_timer)
{
requires_reference_counting =
event_handler->reference_counting_policy ().value () ==
ACE_Event_Handler::Reference_Counting_Policy::ENABLED;
}
// Upcall to the <handler>s handle_timeout method.
if (event_handler->handle_timeout (cur_time, act) == -1)
{
if (event_handler->reactor_timer_interface ())
event_handler->reactor_timer_interface ()->cancel_timer (event_handler, 0);
else
timer_queue.cancel (event_handler, 0); // 0 means "call handle_close()".
}
if (!recurring_timer &&
requires_reference_counting)
{
event_handler->remove_reference ();
}
return 0;
}
定时器的取消
cancel:是在其子类中实现
ACE_Timer_Heap_T
内部使用堆数据结构来管理定时器节点
ACE_Timer_Node_T<TYPE> **heap_
存储定时器节点
ssize_t *timer_ids_
定时器id数组,数组下标表示定时器id,存储的是定时器节点在heap中的索引
扩容策略为当定时器数达到堆大小时,会扩大到原来的2倍
ACE_Timer_Wheel_T
使用时间轮来管理定时器
ACE_Timer_Node_T<TYPE>** spokes_
表示时间轮的轮幅
u_int spoke_count_
表示时间轮幅的大小
int spoke_bits_
表示轮幅所在的位大小,最小3位,最大占12位
int res_bits_
表示时间分辨率所占的位数,最小1位,最大20位
其生成的timer_id为long类型,其中低位spoke_bits_表示属于哪个spoke,高位(32-spoke_bits_)表示定时器的id
使用
在Reactor的实现类使用,其作为实现类的成员
ACE_Timer_Queue *timer_queue_;
ACE_Timer_Queue是ACE_Abstract_Timer_Queue<ACE_Event_Handler*>
的别名
typedef ACE_Abstract_Timer_Queue<ACE_Event_Handler*> ACE_Timer_Queue;
Reactor的实现类有
- ACE_TP_Reactor
- ACE_Dev_Poll_Reactor
- ACE_Select_Reactor
- ACE_Msg_WFMO_Reactor
- ACE_WFMO_Reactor
在其对应的open方法中创建,默认是使用ACE_Timer_Heap
if (result != -1 && this->timer_queue_ == 0)
{
ACE_NEW_RETURN (this->timer_queue_,
ACE_Timer_Heap,
-1);
this->delete_timer_queue_ = true;
}