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

📄 natevttimer.c

📁 VXWORKS NAT 部分源代码3 有兴趣朋友可以参考下
💻 C
📖 第 1 页 / 共 2 页
字号:

/*****************************************************************************
*
* natTaskDelete - delete the 'tNAT' task and free associated resources
*
* Call this routine to send a "delete" message to the message queue processed 
* by the 'tNAT' task.  Upon processing this message, the task frees all 
* resources associated with its message queue and then shuts itself down.  
* 
* RETURNS: OK, upon success; or ERROR, upon failure.
*
* NOMANUAL
* 
*/

STATUS natTaskDelete (void)
 {
	SHUTDOWN_EVENT_DESC * pEvt;

	if (!timerInitCount)
		return ERROR;

	timerInitCount--;

	if (timerInitCount)
		return OK;   

	/* Only delete the timer when the number of calling this function matches
	* the ones of calling natTimerInit. This timer will likely be used
	* by both Firewall and NAT components.
	*/

	if ((pEvt = (SHUTDOWN_EVENT_DESC *)malloc(sizeof(SHUTDOWN_EVENT_DESC)))== NULL)
	{
		printf("Fail to allocate the memory for shutdown event\n");
		return ERROR;
	}

	pEvt->msgId    = TYPE_SHUTDOWN_EVENT;

	/* send an shutdown event to let the NAT task delete itself and cleanup */

	if (msgQSend(natDispatcher.msgQId,(char *)&pEvt,sizeof(void *),
	sysClkRateGet() >> 2, /*wait for 0.5 sec, not to hang forever in case */
	MSG_PRI_URGENT) != OK)
	{
		free((void *)pEvt);
		return ERROR;
	}

	/* give NAT task some time to do the deletion job */

	taskDelay(4);
	return (OK);
}

/*****************************************************************************
*
* natTimerResolutionSet - set the timer resolution in vxWorks ticks
*
* Use this function to specify how often the NAT timer facility checks 
* for expired timers and events, such as a create timer event, a delete 
* timer event, or an activate timer event.  The default resolution is 
* 5 ticks. 
* 
*/

int natTimerResolutionSet 
    (
    int ticks
    )
    {
    if (ticks)
        natDispatcher.msgQTimeOutTicks = ticks;
          
    return (natDispatcher.msgQTimeOutTicks);
    }

/******************************************************************************
*
* dispatchTask - run as the dispatch task for NAT component
*
* This function defines the event-processing loop for the message queue.  
* 
* NOMANUAL
* 
*/

LOCAL void dispatchTask 
    (
    EVT_DISPATCHER_DESC * pDesc
    )
    {
    EVT_NODE * pEvtNode;
    int   numOfBytes;

    /* record the last system tick */

    pDesc->lastTick = tickGet();

    for (;;)
        {
        numOfBytes = msgQReceive(pDesc->msgQId,
                                 (char *)&pEvtNode, 
				  sizeof(EVT_NODE *), 
				  pDesc->msgQTimeOutTicks);

        /* check if there is a message */

        if ((numOfBytes != ERROR) && (numOfBytes >= sizeof(EVT_NODE *)) ) 
            {
            /* handle the message */

            switch (pEvtNode->msgId)
                {
                case TYPE_TIMER_EVENT:

		    /* enqueue the timer event */

                    dllAdd(&pDesc->timerEvtList,&pEvtNode->node);
                    break;

                case TYPE_ACTIVATE_EVENT:
                    {
                    ACTIVATE_EVENT_DESC *pEvt = (ACTIVATE_EVENT_DESC *)pEvtNode;

		    /* retrive the event to be actiavated */

                    EVT_NODE * pEventIdNode = (EVT_NODE *)pEvt->eventId;

                    if (pEventIdNode->msgId == TYPE_TIMER_EVENT)
                        {

			/* locate the timer event in the list */

                        if (nodeSearch(&pDesc->timerEvtList,
                                       &pEventIdNode->node) == TRUE)
                            {
                            TIMER_EVENT_DESC * pTimerEvt;

			    /* load the timer interval and turn it on */

			    pTimerEvt = (TIMER_EVENT_DESC *)pEventIdNode;
                            pTimerEvt->state = TIMER_START;
                            pTimerEvt->expireInterval = pTimerEvt->duration;
                            }
                        } 

                    free ((void *)pEvtNode);
                    }
                    break;

                case TYPE_REMOVE_EVENT:
                    {
                    DL_NODE * pNode = (DL_NODE *)
			  (((REMOVE_EVENT_DESC *)pEvtNode)->eventId);

                    if (nodeSearch(&pDesc->timerEvtList,pNode) == TRUE)
			{
                        dllRemove(&pDesc->timerEvtList,pNode);
                        free((void *)pNode);
			}
                    free ((void *)pEvtNode);
		    }
                    break;
 
                case TYPE_SHUTDOWN_EVENT:
                    /* terminate the NAT task itself and cleanup */
                    {
                    EVT_NODE * pNextEvtNode;

                    /* first dump and free all queued events */

                    while (msgQReceive (pDesc->msgQId, (char *)&pNextEvtNode,
                                        sizeof(EVT_NODE *), NO_WAIT) != ERROR)
                        {
                        free((void *)pNextEvtNode);
                        } 

                    /* remove all events in the list */

                    freeList(&pDesc->timerEvtList);

                    /* free the current event */

                    free ((void *)pEvtNode);

                    /* delete the message queue */

                    msgQDelete(pDesc->msgQId);

                    /* Now delete the task ifself */

                    taskDelete(0);

                    /* should never come to here, unreachable */
                    }
                    break; 

                default:
                    break;
                } /* end switch statement */

            } /* end if (numOfBytes) */

        /* check if there is more message */

        if (msgQNumMsgs(pDesc->msgQId) <= 0)
            {
            /* no more messages in the Q, check the timer */

            timerUpdateAndEvtFuncExec(pDesc);
            }
        }
    }

/******************************************************************************
*
* timerUpdateAndEvtFuncExec - update timers and execute the event functions
*
* This updates timers and executes the event functions.
* 
* NOMANUAL
*/
LOCAL void timerUpdateAndEvtFuncExec 
    (
    EVT_DISPATCHER_DESC * pDesc
    )
    {
    ULONG curTime;
    ULONG timeDelta;
    TIMER_EVENT_DESC * pTimeEvt;
    DL_NODE * pRmNode = NULL;

    /* the current system tick */

    curTime = tickGet();

    /* the time difference between now and the last recorded system tick */

    timeDelta = curTime >= pDesc->lastTick?   /* tick counter wrap around? */
                curTime - pDesc->lastTick:    /* no */
                (UINT32)0xffffffff - pDesc->lastTick + curTime;  /* yes */

    /* update the last tick counter */

    pDesc->lastTick = curTime;

    /* update the running timer interval */

    pTimeEvt = (TIMER_EVENT_DESC *)DLL_FIRST(&pDesc->timerEvtList);

    while (pTimeEvt)
        {
        if (pTimeEvt->state == TIMER_START)
            {
            if (pTimeEvt->expireInterval > timeDelta)
		
		/* decrement the timer interval */

                pTimeEvt->expireInterval -= timeDelta;
            else
                {
		/* timer expired, execute the event function */

                pTimeEvt->pEvtFunc(pTimeEvt->evtFuncContext);

                if (pTimeEvt->option & OPTION_ONE_SHOT)
                    {
		    /* the node to be removed */

                    pRmNode = &pTimeEvt->evtNode.node;
                    }
                else
                    /* reload the timer duration contant */

                    pTimeEvt->expireInterval = pTimeEvt->duration;

                }
            }
        pTimeEvt = (TIMER_EVENT_DESC *)DLL_NEXT(&pTimeEvt->evtNode.node);

	if (pRmNode != NULL)
	    {
	    dllRemove(&pDesc->timerEvtList,pRmNode);
	    free((void *)pRmNode);
	    pRmNode = NULL;
	    }

        }
    }

/******************************************************************************
*
* nodeSearch - Match the given node in the list
*
* This function matches the given node against the list.
* 
* NOMANUAL 
*/

LOCAL BOOL nodeSearch
    (
    DL_LIST * pList,
    DL_NODE * pMatchNode
    )
    {
    DL_NODE * pNode;

    pNode = DLL_FIRST(pList);

    while (pNode)
        {
        if (pNode == pMatchNode)
            return TRUE;

        pNode = DLL_NEXT(pNode);
        }

    return FALSE;
    }

/***************************************************************************
*
* freeList - Free a link list
*
* Free a link list.
*
* NOMANUAL
*/

LOCAL void freeList
    (
    DL_LIST * pList
    )
    {
    DL_NODE * pNode;
    DL_NODE * pPrevNode;

    pNode = DLL_FIRST(pList);

    while (pNode)
        {
        pPrevNode = pNode;
        pNode = DLL_NEXT(pNode);
        free((void *)pPrevNode);
        }

    dllInit(pList);
    }


⌨️ 快捷键说明

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