注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

Code@Pig Home

喜欢背着一袋Code傻笑的Pig .. 忧美.欢笑.记忆.忘却 .之. 角落

 
 
 

日志

 
 

[ACE] Timer_Queue(1) - 关于Upcall  

2010-02-07 07:44:21|  分类: net_ACE |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
ACE 通过 Timer_Queue 来管理一个 timer 的列表,其提供了:
  1. 向 Timer_Queue 注册我们的 timer
  2. 取消一个已经注册的 timer
  3. 从 Timer_Queue 得到当前有哪些 timer 应该 expire 了

类的关系如下:
Timer_Queue, 容器类,决定了 timer 列表内部的结构,可以是 list, hash table ...
Timer_Queue_Iterator, 遍历容器类的迭代起了
XXX_Upcall, Timer_Queue 与 timer_handler 之间的桥梁

template <TYPE, FUNCTOR, ACE_LOCK>
class Timer_Queue_T;
其中 TYPE 一般就是 timer_handler 的函数指针。ACE 中有个 class ACE_Event_Handler_Handle_Timeout_Upcall (Timer_Queue_T.h),其中的 TYPE 就是 ACE_Event_Handler *。

Timer_Queue 在一些事件点(如:schedule, expire, cancel...),去触发 XXX_Upcall 上的一些函数,从而出发了具体的 timer_handler。
简单说来就是:Timer_Queue ==> XXX_Upcall ==> timer_handler

其中 XXX_Upcall 要提供:
registration(), 当一个 timer 被注册时调用,如:Timer_Queue.schedule()
preinvoke(), timeout(), postinvoke(), 当一个 timer 被触发时调用,如:Timer_Queue.expire()
cancel_type(), cancel_timer(), 当 timer 被删除时,如:Timer_Queue.cancel()
deletion(), 当 Timer_Queue 析构时,对所有还在 Timer_Queue 中的 timer 调用。

下面手工打造了一个 MyHandler_Upcall,可以看看 Timer_Queue 和 XXX_Upcall 是如何协作的。
-------------------------------- MyUpcall.h --------------------------------------
#ifndef KCODE_MY_TIMERQUEUE_H
#define KCODE_MY_TIMERQUEUE_H

#include <ace/Timer_Queue_T.h>

// ----------------------
typedef int MyType;

template <class ACE_LOCK>
class MyHandler_Upcall
{
public:
    typedef ACE_Timer_Queue_T<MyType,
                              MyHandler_Upcall<ACE_LOCK>,
                              ACE_LOCK>
            TIMER_QUEUE;

    MyHandler_Upcall(void);
    ~MyHandler_Upcall(void);
    // register
    int registration(TIMER_QUEUE &timer_queue,
                     MyType type,
                     const void *arg);

    // timeout
    // upcall_act - take sth from preinvoke() to postinvoke()
    int preinvoke(TIMER_QUEUE &timer_queue,
                  MyType type,
                  const void *arg,
                  int recurring_timer,
                  const ACE_Time_Value &cur_time,
                  const void *&upcall_act);

    int timeout(TIMER_QUEUE &timer_queue,
                MyType type,
                const void *arg,
                int recurring_timer,
                const ACE_Time_Value &cur_time);

    int postinvoke(TIMER_QUEUE &timer_queue,
                   MyType type,
                   const void *arg,
                   int recurring_timer,
                   const ACE_Time_Value &cur_time,
                   const void *upcall_act);

    // delete
    // dont_call - don't call close handler
    // cookie    - may take sth from cancel_type() to cancel_timer()
    int cancel_type(TIMER_QUEUE &timer_queue,
                    MyType type,
                    int dont_call,
                    int &cookie);

    int cancel_timer(TIMER_QUEUE &timer_queue,
                    MyType type,
                    int dont_call,
                    int cookie);

    int deletion(TIMER_QUEUE &timer_queue,
                 MyType type,
                 const void *arg);

private:
    MyHandler_Upcall(const MyHandler_Upcall<ACE_LOCK>&);
    void operator=(const MyHandler_Upcall<ACE_LOCK>&);
};

#include "MyTimerQueue.cpp"

#endif
-------------------------------- MyUpcall.cpp -----------------------------------
#include "MyUpcall.h"
#include <stdio.h>

template <class ACE_LOCK>
MyHandler_Upcall<ACE_LOCK>::MyHandler_Upcall(void)
{
}

template <class ACE_LOCK>
MyHandler_Upcall<ACE_LOCK>::~MyHandler_Upcall(void)
{
}

template <class ACE_LOCK>
int MyHandler_Upcall<ACE_LOCK>::registration(
        TIMER_QUEUE &timer_queue,
        MyType type,
        const void *arg)
{
    printf("registration,type=%d\n", type);
    return 0;
}

template <class ACE_LOCK>
int MyHandler_Upcall<ACE_LOCK>::preinvoke(
    TIMER_QUEUE &timer_queue,
    MyType type,
    const void *arg,
    int recurring_timer,
    const ACE_Time_Value &cur_time,
    const void *&upcall_act)
{
    printf("preinvoke,type=%d,t=%lu\n", type, cur_time.msec());
    upcall_act = (void *)111;
    return 0;
}

template <class ACE_LOCK>
int MyHandler_Upcall<ACE_LOCK>::timeout(
    TIMER_QUEUE &timer_queue,
    MyType type,
    const void *arg,
    int recurring_timer,
    const ACE_Time_Value &cur_time)
{
    printf("timeout,type=%d,t=%lu\n", type, cur_time.msec());
    return 0;
}

template <class ACE_LOCK>
int MyHandler_Upcall<ACE_LOCK>::postinvoke(
    TIMER_QUEUE &timer_queue,
    MyType type,
    const void *arg,
    int recurring_timer,
    const ACE_Time_Value &cur_time,
    const void *upcall_act)
{
    printf("postinvoke,type=%d,t=%lu,upcall_act=%d\n",
        type, cur_time.msec(), (int)upcall_act);
    return 0;
}

template <class ACE_LOCK>
int MyHandler_Upcall<ACE_LOCK>::cancel_type(
    TIMER_QUEUE &timer_queue,
    MyType type,
    int dont_call,
    int &cookie)
{
    printf("cancel_type,type=%d\n", type);
    cookie = 222;
    return 0;
}

template <class ACE_LOCK>
int MyHandler_Upcall<ACE_LOCK>::cancel_timer(
    TIMER_QUEUE &timer_queue,
    MyType type,
    int dont_call,
    int cookie)
{
    printf("cancel_timer,type=%d,cookie=%d\n", type, cookie);
    return 0;
}

template <class ACE_LOCK>
int MyHandler_Upcall<ACE_LOCK>::deletion(
    TIMER_QUEUE &timer_queue,
    MyType type,
    const void *arg)
{
    printf("deletion,type=%d\n", type);
    return 0;
}
----------------------------------- Main.cpp --------------------------------------
#include <ace/Timer_Queue_T.h>
#include <ace/Timer_List_T.h>
#include "MyTimerQueue.h"

typedef ACE_Timer_List_T<MyType,
    MyHandler_Upcall<ACE_SYNCH_NULL_MUTEX>,
    ACE_SYNCH_NULL_MUTEX>
    My_Timer_List;

int main()
{
    My_Timer_List tlist;
    long id;

    // timer10, once timer
    // timer20, interval timer
    printf("---- register ----\n");
    tlist.schedule(10, NULL, ACE_Time_Value(3));
    tlist.schedule(20, NULL, ACE_Time_Value(3), ACE_Time_Value(2));
    tlist.schedule(30, NULL, ACE_Time_Value(10));

    // timer10 / 20, expire
    printf("---- expire(3) ----\n");
    tlist.expire(ACE_Time_Value(3));

    // timer20, expire
    printf("---- expire(5) ----\n");
    tlist.expire(ACE_Time_Value(5));

    printf("---- cancel ----\n");
    id = tlist.schedule(40, NULL, ACE_Time_Value(20));
    tlist.cancel(id);

    printf("---- finish ----\n");
    return 0;
}
------------------------------------------------------------------------------------------
$ ./a.out
---- register ----
registration,type=10
registration,type=20
registration,type=30
---- expire(3) ----
preinvoke,type=10,t=3000
timeout,type=10,t=3000
postinvoke,type=10,t=3000,upcall_act=111
preinvoke,type=20,t=3000
timeout,type=20,t=3000
postinvoke,type=20,t=3000,upcall_act=111
---- expire(5) ----
preinvoke,type=20,t=5000
timeout,type=20,t=5000
postinvoke,type=20,t=5000,upcall_act=111
---- cancel ----
registration,type=40
cancel_type,type=40
cancel_timer,type=40,cookie=222
---- finish ----
deletion,type=20
deletion,type=30
------------------------------------------------------------------------------------------

  评论这张
 
阅读(1547)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017