⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 wcetimer.c

📁 WinCE5.0部分核心源码
💻 C
📖 第 1 页 / 共 2 页
字号:
    TQ_ADDREF(pTimerQueue);    

    LeaveCriticalSection(&g_csTimerQueueList);

    return pTimerQueue;

}   //  FindAndLockTimerQueue()


///////////////////////////////////////////////////////////////////////////////
//	FindTimerQueueTimer()
//
//	Routine Description:
//
//		Find the pTQT in the given pTQ's TimerQueueTimerList.
//
//      
//	Return Value:
//
//		NULL if it's not found, PTIMER_QUEUE_TIMER if found.
//
//
//  Note:
//
//      Caller should hold TIMER_QUEUE lock.
//

PTIMER_QUEUE_TIMER
FindTimerQueueTimer(PTIMER_QUEUE  pTQ, PTIMER_QUEUE_TIMER pTargetTQT)
{
    PTIMER_QUEUE_TIMER  pTQT = (PTIMER_QUEUE_TIMER)(pTQ->TimerQueueTimerList.Flink);

    while((PLIST_ENTRY)pTQT != &(pTQ->TimerQueueTimerList))
    {
        if (pTQT == pTargetTQT)
            break;

        pTQT = (PTIMER_QUEUE_TIMER)pTQT->ListEntry.Flink;
    }

    if ((PLIST_ENTRY)pTQT == &pTQ->ListEntry)
        return NULL;

    return pTQT;
    
}   //  FindAndLockTimerQueue()



///////////////////////////////////////////////////////////////////////////////
//	CE_CreateTimerQueueTimer()
//
//	Routine Description:
//
//		Implement the CreateTimerQueueTimer() Win32 API.
//
//	Return Value:
//
//		TRUE if successful, FALSE otherwise..
//

BOOL 
CE_CreateTimerQueueTimer(
  PHANDLE               phNewTimer,     // handle to timer
  HANDLE                TimerQueue,     // handle to timer queue
  WAITORTIMERCALLBACK   Callback,       // timer callback function
  PVOID                 Parameter,      // callback parameter
  DWORD                 DueTime,        // timer due time
  DWORD                 Period,         // timer period
  ULONG                 Flags)          // options *Ignored*
{
    PTIMER_QUEUE_TIMER  pTimerQueueTimer;
    PTIMER_QUEUE        pTimerQueue;    

    DEBUGMSG (ZONE_TIMER,
        (TEXT("ZCF:: CE_CreateTimerQueueTimer(). Due[%d]s Period[%d]s\r\n"),
        DueTime/1000,
        Period/1000));

    pTimerQueueTimer = (PTIMER_QUEUE_TIMER) MALLOC(sizeof(TIMER_QUEUE_TIMER));    
    
    if (pTimerQueueTimer == NULL)
    {
        DEBUGMSG(
            ZONE_ERROR,
            (TEXT("ZCF:: Failed CE_CreateTimerQueueTimer() OOM.\r\n")));
        return FALSE;
    }

    memset(pTimerQueueTimer, 0x00, sizeof(TIMER_QUEUE_TIMER));

#ifdef DEBUG
    pTimerQueueTimer->dwSig       = CE_TIMERTIMER_SIG;
#endif
    pTimerQueueTimer->Callback    = Callback; 
    pTimerQueueTimer->Parameter   = Parameter;
    pTimerQueueTimer->DueTime     = 0x00;       //  <-- due time is good for one go only..
    pTimerQueueTimer->Period      = Period;

    InitializeCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);

    TQT_ADDREF(pTimerQueueTimer);       //  For deletion.
    TQT_ADDREF(pTimerQueueTimer);       //  For completion.


    CTEInitBlockStruc(&pTimerQueueTimer->TimerBlockStruc);

    //
    //  The TimerQueue better be in our list..
    //

    if (TimerQueue == NULL)
    {
        //
		//	Use default timer queue, create one if there isn't one.
		//

		if (g_hDefaultTimerQueue == NULL)
		{
		    g_hDefaultTimerQueue = CreateTimerQueue();			
			if (g_hDefaultTimerQueue == INVALID_HANDLE_VALUE)
				goto ErrorReturn;
		}

		TimerQueue = (HANDLE)g_hDefaultTimerQueue;	
    }

    //
    //  For each TimerQueueTimer, we'll take a ref in TimerQueue.
    //  We deref it in CE_DeleteTimerQueueTimer()
    //
    
    pTimerQueue = FindAndRefTimerQueue((PTIMER_QUEUE)TimerQueue);

    if (pTimerQueue == NULL)
        goto ErrorReturn;

    EnterCriticalSection(&pTimerQueue->csTimerQueue);

    ASSERT(pTimerQueue->dwSig == CE_TIMER_SIG);
    
    //
    //  Queue TimerQueueTimer..
    //

    InsertTailList(&pTimerQueue->TimerQueueTimerList, (PLIST_ENTRY)pTimerQueueTimer);

    LeaveCriticalSection(&pTimerQueue->csTimerQueue);

    //
    //  Start it..
    //

    *phNewTimer = (PHANDLE)pTimerQueueTimer;	

    DEBUGMSG (ZONE_TIMER,
        (TEXT("ZCF:: CE_CreateTimerQueueTimer() TQT[0x%x] created.   Due[%d]s Period[%d]s.   TotalTQT[%d]"),
        pTimerQueueTimer,
        DueTime/1000,
        Period/1000,
        InterlockedIncrement(&g_dwTotalTQT)));
    
    pTimerQueueTimer->bTimerRunning = TRUE;

    CTEStartTimer(
		&(pTimerQueueTimer->hTimer),
        DueTime,
		(CTEEventRtn)PerformCallback,
		pTimerQueueTimer);	

    return TRUE;

ErrorReturn:

    DEBUGMSG(ZONE_ERROR,
        (TEXT("ZCF:: Failed CE_CreateTimerQueueTimer().\r\n")));
        
    CTEDeinitBlockStruc(&pTimerQueueTimer->TimerBlockStruc);
    FREE(pTimerQueueTimer);
    return FALSE;

}   //  CE_CreateTimerQueueTimer()




///////////////////////////////////////////////////////////////////////////////
//	CE_DeleteTimerQueueTimer()
//
//	Routine Description:
//
//		Implement the CreateTimerQueueTimer() Win32 API.
//
//	Return Value:
//
//		TRUE if successful, FALSE otherwise..
//

BOOL CE_DeleteTimerQueueTimer(
  HANDLE TimerQueue,        // handle to timer queue
  HANDLE Timer,             // handle to timer
  HANDLE CompletionEvent)   // handle to completion event
{

    PTIMER_QUEUE        pTimerQueue;
    PTIMER_QUEUE_TIMER  pTimerQueueTimer;

    DEBUGMSG (ZONE_TIMER,
        (TEXT("ZCF:: CE_DeleteTimerQueueTimer() TQT[0x%x] TQ[0x%x]\r\n"),
        Timer,
        TimerQueue));         

    if (TimerQueue == NULL)
    {
        if (g_hDefaultTimerQueue == NULL)
        {
            DEBUGMSG (ZONE_TIMER,
                (TEXT("ZCF:: CE_ChangeTimerQueueTimer() Default Timer not started.\r\n")));

            return FALSE;
        }

        TimerQueue = g_hDefaultTimerQueue;
    }


    //
    //  FindAndRefTimerQueue() will ref TimerQueue in this function.
    //
    
    pTimerQueue =  FindAndRefTimerQueue(TimerQueue);

    if (pTimerQueue == NULL)
    {
        //
        //  This should not happen in ZCF code..
        //
        
        ASSERT(0);        
        return FALSE;
    }

    EnterCriticalSection(&pTimerQueue->csTimerQueue);

    pTimerQueueTimer =  FindTimerQueueTimer(
                            pTimerQueue, 
                            (PTIMER_QUEUE_TIMER)Timer);

    if (pTimerQueueTimer == NULL)
    {
        DEBUGMSG (ZONE_TIMER,
            (TEXT("ZCF:: CE_DeleteTimerQueueTimer() invalid TQT[0x%x]\r\n"),
            Timer));

        //
        //  This should not happen in IPv6 code..
        //        
        ASSERT(0);
        
        LeaveCriticalSection(&pTimerQueue->csTimerQueue);
        TQ_DELREF(pTimerQueue); //  Taken in FindAndRefTimerQueue()
        return FALSE;
    }

    //
    //  Remove it from TimerQueueTimerList list.
    //

    RemoveEntryList((PLIST_ENTRY)pTimerQueueTimer);

    LeaveCriticalSection(&pTimerQueue->csTimerQueue);

    TQ_DELREF(pTimerQueue);     //  Taken in FindAndRefTimerQueue()
    TQ_DELREF(pTimerQueue);     //  Taken in CE_CreateTimerQueueTimer()


    //
    //  By now pTimerQueueTimer is a stand alone cell..
    //

    EnterCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);

    pTimerQueueTimer->hFinishEvent = CompletionEvent;
    pTimerQueueTimer->DueTime      = 0x00;
    pTimerQueueTimer->Period       = 0x00;
 
    if (pTimerQueueTimer->bTimerRunning == TRUE)        
    {   
        //
        //  For the timer still running case, completion event will be
        //  set by the callback function.  If caller asks to be blocked
        //  do it.
        //  
        
        pTimerQueueTimer->bTimerRunning = FALSE;
        
        if (!CTEStopTimer(&(pTimerQueueTimer->hTimer)))
        {                            
            DEBUGMSG(ZONE_TIMER,
                (TEXT("ZCF:: CE_DeleteTimerQueueTimer().  TQT[0x%x] pending.\r\n"),
                pTimerQueueTimer));

            //
            //  Potentially we may get here from the callback itself.
            //  So, don't block if that's the case.
            //            
            
            if (CompletionEvent == INVALID_HANDLE_VALUE  &&
                pTimerQueueTimer->bTimerInCallBack == FALSE)
            {                
                LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
                CTEBlock(&pTimerQueueTimer->TimerBlockStruc);
    			ResetEvent(&pTimerQueueTimer->TimerBlockStruc.cbs_event);
                EnterCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
            }

            //
            //  Do not need to deref TQT because the PerformCallBack() must have done 
            //  or will be doing that.
            //
        }
        else
        {
            DEBUGMSG(ZONE_TIMER,
                (TEXT("ZCF:: CE_DeleteTimerQueueTimer().  Timer successfully stopped.\r\n")));            
            
            TQT_DELREF(pTimerQueueTimer);       //  Taken in CE_CreateTimerQueueTimer() for completion.
        }
    }   
    else
    {
        DEBUGMSG(ZONE_TIMER,
            (TEXT("ZCF:: CE_DeleteTimerQueueTimer().  Timer was not running.\r\n")));
        
        //
        //  Ditto here..
        //  Do not need to deref TQT because the PerformCallBack() must have
        //  done that.
        //
    }

    LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
    TQT_DELREF(pTimerQueueTimer);   // Taken in CE_CreateTimerQueueTimer() for deletion.    
    return TRUE;

}   //  CE_DeleteTimerQueueTimer()



///////////////////////////////////////////////////////////////////////////////
//  CE_ChangeTimerQueueTimer()
//
//  Routine Description:
//
//      Implement the ChangeTimerQueueTimer() Win32 API.
//
//  Return Value:
//
//      TRUE if successful, FALSE otherwise..
//

BOOL
CE_ChangeTimerQueueTimer(
    HANDLE  TimerQueue,     // handle to timer queue
    HANDLE  Timer,          // handle to timer
    ULONG   DueTime,        // timer due time
    ULONG   Period)         // timer period
{

    PTIMER_QUEUE_TIMER  pTimerQueueTimer;
    PTIMER_QUEUE        pTimerQueue;
    BOOL                bRestartTimer = TRUE;


    DEBUGMSG (ZONE_TIMER,
        (TEXT("ZCF:: CE_ChangeTimerQueueTimer() TQT[0x%x] TQ[0x%x] Due[%d]s Period[%d]s\r\n"),
        Timer,
        TimerQueue,
        DueTime/1000,
        Period/1000));

    //
    //  This will hold REF for TIMER_QUEUE during in this function.
    //

    if (TimerQueue == NULL)
    {
        if (g_hDefaultTimerQueue == NULL)
        {
            DEBUGMSG (ZONE_TIMER,
                (TEXT("ZCF:: CE_ChangeTimerQueueTimer() Default Timer not started.\r\n")));

            return FALSE;
        }

        TimerQueue = g_hDefaultTimerQueue;
    }

    //
    //  TimerQueue is REFed once here.
    //
    
    pTimerQueue =  FindAndRefTimerQueue(TimerQueue);

    if (pTimerQueue == NULL)
    {
        //
        //  This should not happen in ZCF code.
        //
        
        ASSERT(0);
        return FALSE;
    }

    EnterCriticalSection(&pTimerQueue->csTimerQueue);

    pTimerQueueTimer =  FindTimerQueueTimer(
                            pTimerQueue, 
                            (PTIMER_QUEUE_TIMER)Timer);

    if (pTimerQueueTimer == NULL)
    {
        DEBUGMSG (ZONE_TIMER,
            (TEXT("ZCF:: CE_ChangeTimerQueueTimer() invalid TQT[0x%x]\r\n"),
            Timer));

        //
        //  Should not happen in ZCF code.
        //
        ASSERT(0);
        
        LeaveCriticalSection(&pTimerQueue->csTimerQueue);
        TQ_DELREF(pTimerQueue); //  Taken in FindAndRefTimerQueue()
        return FALSE;
    }

    //
    //  REF hold during this function only..
    //
    
    TQT_ADDREF(pTimerQueueTimer);

    LeaveCriticalSection(&pTimerQueue->csTimerQueue);


    EnterCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);

    //
    //  Attempt to stop the timer if it is currently ticking..
    // 
    
    if (pTimerQueueTimer->bTimerRunning == TRUE)
    {
        if (!CTEStopTimer(&(pTimerQueueTimer->hTimer)))
        {
            if (pTimerQueueTimer->bTimerInCallBack)
            {
                bRestartTimer = FALSE;
            }
            else
            {
                //
                //  Timer must have fired..   
                //  And the call back is waiting to get in while we are holding
                //  the CS.
                //  Tell it to go away..
                //           

                pTimerQueueTimer->bTimerRunning = FALSE;

                LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);

                //
                //  Wait for it to tell us that it has gone away..
                //

                CTEBlock(&pTimerQueueTimer->TimerBlockStruc);
                ResetEvent(&pTimerQueueTimer->TimerBlockStruc.cbs_event);

                //
                //  Cool, all done we are clear to go..
                //

                EnterCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
                
            }
        }
        else
        {
            TQT_DELREF(pTimerQueueTimer);   //  Taken in CE_CreateTimerQueueTimer() for completion.
                                            //  Since we now cancel it.

        }
    }
    
    //
    //  By now the timer has successfully been stopped.
    //  Per MSDN, 
    //  If you call ChangeTimerQueueTimer on a one-shot timer (its period is 
    //  zero) that has already expired, the timer is not updated.     
    //
    
    if (pTimerQueueTimer->Period)
    {
        pTimerQueueTimer->DueTime       = DueTime;
        pTimerQueueTimer->Period        = Period;         

        if (bRestartTimer)
        {
            pTimerQueueTimer->bTimerRunning = TRUE;        

            TQT_ADDREF(pTimerQueueTimer);

            CTEStartTimer(
                &(pTimerQueueTimer->hTimer),
                pTimerQueueTimer->DueTime,
                (CTEEventRtn)PerformCallback,
                pTimerQueueTimer);            

            pTimerQueueTimer->DueTime = 0x00;

        }
    }

    LeaveCriticalSection(&pTimerQueueTimer->csTimerQueueTimer);
    
    TQT_DELREF(pTimerQueueTimer);       //  REF hold in this function.
    TQ_DELREF(pTimerQueue);             //  REF hold in this function.
    return TRUE;

}   //  CE_ChangeTimerQueueTimer()


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -