#include #include #include #include VOID IrdaTimerExpFunc(struct CTEEvent *Event, void *Arg); void IrdaTimerInitialize(PIRDA_TIMER pTimer, VOID (*ExpFunc)(PVOID Context), UINT Timeout, PVOID Context, PIRDA_LINK_CB pIrdaLinkCb) { #if DBG DEBUGMSG(DBG_TIMER, (TEXT("%hs timer initialized, context %x\n"), pTimer->pName, pTimer)); #endif CTEInitTimer(&pTimer->CteTimer); CTEInitEvent(&pTimer->CteEvent, IrdaTimerExpFunc); pTimer->ExpFunc = ExpFunc; pTimer->Context = Context; pTimer->Timeout = Timeout; pTimer->pIrdaLinkCb = pIrdaLinkCb; } void TimerFuncAtDpcLevel(CTEEvent *Event, void *Arg) { PIRDA_TIMER pIrdaTimer = (PIRDA_TIMER) Arg; #if DBG DEBUGMSG(DBG_TIMER, (TEXT("%hs timer expired at DPC, context %x\n"), pIrdaTimer->pName, pIrdaTimer)); #endif CTEScheduleEvent(&pIrdaTimer->CteEvent, Arg); return; } VOID IrdaTimerExpFunc(struct CTEEvent *Event, void *Arg) { PIRDA_TIMER pIrdaTimer = (PIRDA_TIMER) Arg; PIRDA_LINK_CB pIrdaLinkCb; #if DBG DEBUGMSG(DBG_TIMER, (TEXT("%hs timer expired, context %x\n"), pIrdaTimer->pName, pIrdaTimer)); #endif pIrdaLinkCb = pIrdaTimer->pIrdaLinkCb; if (pIrdaLinkCb) LOCK_LINK(pIrdaLinkCb); if (pIrdaTimer->Late != TRUE) pIrdaTimer->ExpFunc(pIrdaTimer->Context); else { DEBUGMSG(DBG_WARN | DBG_TIMER, (TEXT("IRDA TIMER LATE, ignoring\n"))); pIrdaTimer->Late = FALSE; } if (pIrdaLinkCb) { UNLOCK_LINK(pIrdaLinkCb); REFDEL(&pIrdaLinkCb->RefCnt,'RMIT'); } return; } VOID IrdaTimerStart(PIRDA_TIMER pIrdaTimer) { if (pIrdaTimer->pIrdaLinkCb) REFADD(&pIrdaTimer->pIrdaLinkCb->RefCnt, 'RMIT'); pIrdaTimer->Late = FALSE; CTEStartTimer(&pIrdaTimer->CteTimer, pIrdaTimer->Timeout, TimerFuncAtDpcLevel, (PVOID) pIrdaTimer); #if DBG DEBUGMSG(DBG_TIMER, (TEXT("Start timer %hs (%dms) context %x\n"), pIrdaTimer->pName, pIrdaTimer->Timeout, pIrdaTimer)); #endif return; } VOID IrdaTimerStop(PIRDA_TIMER pIrdaTimer) { if (pIrdaTimer->pIrdaLinkCb) LOCK_LINK(pIrdaTimer->pIrdaLinkCb); if (CTEStopTimer(&pIrdaTimer->CteTimer) == 0) { pIrdaTimer->Late = TRUE; } else { if (pIrdaTimer->pIrdaLinkCb) REFDEL(&pIrdaTimer->pIrdaLinkCb->RefCnt,'RMIT'); } #if DBG DEBUGMSG(DBG_TIMER, (TEXT("Timer %hs stopped, late %d\n"), pIrdaTimer->pName, pIrdaTimer->Late)); #endif if (pIrdaTimer->pIrdaLinkCb) { UNLOCK_LINK(pIrdaTimer->pIrdaLinkCb); } return; } VOID IrdaTimerRestart(PIRDA_TIMER pIrdaTimer) { IrdaTimerStop(pIrdaTimer); IrdaTimerStart(pIrdaTimer); }