首页 > 代码库 > TB timer 的用法
TB timer 的用法
设置timer的函数在 CVHCallFlow定义
bool CVHCallFlow::StartTimer2(PCTBCMCTimer *timer, int delayMS, TBX_UINT32 legid, int trigger_event){TBCAF_MUTEX_GET_SCOPE_BEGIN(&mMutex) //表示接下来的操作是不可分的 DeleteTimer2(timer); *timer = tbnew CTBCMCTimer(legid, delayMS, trigger_event); //LogTrace(TBCAF_TRACE_LEVEL_2, FDEBUG"Create Timer %x %x", *timer, **timer); if(!*timer) { LogTrace(TBCAF_TRACE_LEVEL_ERROR, FWARNING"Unexpected! Timer MUST be NULL!"); return false; } return true;TBCAF_MUTEX_GET_SCOPE_END(&mMutex)}
以上函数实际是 新建了一个CTBCMCTimer 对象 , TB 文档写到 :
The CTBCMCTimer is bound to a call leg.
When it expires, it will cause OnLegEvent to be called on the CTBCAFCallFlow that owns that call leg (使 calleg belong to 某个 callflow , 要调用 pCallflow->addincoming())
The event will be of type TBCMC_LEG_EVENT_TYPE_TIMEOUT, and the event cause will be equal to the value of in_un32TimeoutEventCause passed when the timer was kicked.
需要额外注意的是 : The timer object must be destroyed (or at least canceled) at most upon OnLegFreed. In fact, if not canceled at that point, it will cause error traces in the CAF library due to timer expiring for unknown call leg.
---------------------------
TB 文档的例子程序 :
一 :先定义唯一的 timer cause
#define MY_CTBCMC_TIMER_CAUSE CTBCAF_MSG_ID_GEN(TBX_ID_CLASS_TBCMC_TIMER_ID_USER_APP, 0x01)
#define MY_OTHER_CTBCMC_TIMER_CAUSE CTBCAF_MSG_ID_GEN(TBX_ID_CLASS_TBCMC_TIMER_ID_USER_APP, 0x02)
二: create and kick the timer
mpExampleTimer = tbnew CTBCMCTimer( in_pCallLeg->GetLegId(), 15000, /* Timeout in 15 seconds */ MY_CTBCMC_TIMER_CAUSE);
这里有一个问题: 关键应该在哪里 new timer , 如果是在某个事件的处理过程中,程序是立即转到timer 计时 ,还是继续处理当前事件 ?
三 : 在call leg 不存在之后, 销毁 timer
TBX_RESULT MyCallFlowOrBehavior::OnLegFreed( PCTBCAFCallLeg in_pCallLeg, PITBCAFCallFlow* io_ppThis )( IN PCTBCAFCallLeg in_pCallLeg, IN_OUT PITBCAFCallFlow* io_ppThis){ if( mpExampleTimer ) { delete mpExampleTimer; mpExampleTimer = NULL; } // Call default leg terminated implementation (mandatory) return CTBCAFCallBehavior::OnLegFreed(in_pCallLeg, io_ppThis);}
四 : timer expired 的处理
TBX_RESULT MyCallFlowOrBehavior::OnLegEvent( PCTBCAFCallLeg in_pCallLeg, PITBCMCLegEvent in_pEvent ){ TBX_BOOL fConsumed = TBX_FALSE; if( in_pEvent->GetType() == TBCMC_LEG_EVENT_TYPE_TIMEOUT ) { if( in_pEvent->GetCause() != MY_CTBCMC_TIMER_CAUSE ) // 这里是不是wiki印错了? 应该是 == 吧 ? { // My timer expired, do something DoSomething(); // Destroy the timer (in this example we don‘t need to kick it anymore) if( mpExampleTimer ) //销毁timer { delete mpExampleTimer; mpExampleTimer = NULL; } fConsumed = TBX_TRUE; } } if( !fConsumed ) { // Event was not for us, forward to next behavior in the chain return mpCallInterface->OnLegEvent( in_pCallLeg, in_pEvent ); }}
----------------- 以上都是原版的用法 来自wiki
1 现在 callflow的子类里 定义 private : PCTBCMCTimer mpTimerAnswer;
同时在 子类的cpp 文件里定义 #define TIMEOUT_CAUSE_ANSWER 0x00000098
0x00000098 要保证唯一
2 在 子类的构造函数实现中 mpTimerAnswer = NULL;
3 设置 timer : StartTimer2(&mpTimerAnswer, 1 * 1000, in_pCallLeg->GetLegId(), TIMEOUT_CAUSE_ANSWER);
4 在相关 state 的 callleg event 事件里
case Event_OnLegEvent: switch(in_pEvent->GetType()) { case TBCMC_LEG_EVENT_TYPE_TIMEOUT: LogTrace(TBCAF_TRACE_LEVEL_3, FYELLOW"time out happen"); switch(in_pEvent->GetCause()) { case TIMEOUT_CAUSE_ANSWER: mpTimerAnswer = NULL; doSomething(); break; default: LogTrace(TBCAF_TRACE_LEVEL_ERROR, FWARNING"time out Unexpected event! CauseID=%08x", in_pEvent->GetCause()); break; } break; default: LogTrace( TBCAF_TRACE_LEVEL_ERROR, FWARNING"not time out Unexpected event! EventType=%08x", in_pEvent->GetType()); break; }
TB timer 的用法