📄 natevttimer.c
字号:
/*****************************************************************************
*
* 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 + -