📄 msgque.c
字号:
//File Name: MsgQue.cpp: implementation of the MsgQue and SafeMsgQue structure.
//References: None
//Purpose: To implement a Safe Message Queue and some essential functions about it.
//History
//*Data *Name *comments.
//2008-Feb-23 Rock Li Initialization
//////////////////////////////////////////////////////////////////////
//#include "stdafx.h" only for windows
#include "MsgQue.h"
//////////////////////////////////////////////////////////////////////
//Purpose: To initialize the the pSafeQue message queue
//Arguments description:
//hProExit --> program exit flag
//pSafeQue --> the point to safe message queue
//return value: true for success and false for failure
int SafeMsgQueInit( pSafeMsgQue pSafeQue)
{
pthread_mutex_init(&pSafeQue->hOpLock, NULL);
sem_init(&pSafeQue->hMsgSem, 0, 0);
pSafeQue->pHead = NULL;
pSafeQue->pTail = NULL;
return 0;
}
//Purpose: To Insert a message into the safe message queue
//Arguments description:
//msg --> the message to be inserted into the safe message queue
//pSafeQue --> the pointer to the safe message queue
//return value: 0 for success and others for failure
//Notice: only one node should be in the Pmsg. pMsg should be heap.
int InsertOneMsg(pMsgQue pMsg, pSafeMsgQue pSafeQue)
{
if(LockQue(pSafeQue) != 0) // safe operation; To get the right to use the resurece
{
return -1;
}
if(pSafeQue->pHead == NULL)
{
pSafeQue->pHead = pMsg;
pMsg->next =NULL;
}
if(pSafeQue->pTail == NULL)
{
pSafeQue->pTail = pMsg;
pMsg->next =NULL;
}
else
{
pSafeQue->pTail->next = pMsg;
pMsg->next =NULL;
}
UnlockQue(pSafeQue);// safe operation; To give up the right to use the resurece to let another to use it.
//Maybe , I will use this variable later.
sem_post(&pSafeQue->hMsgSem);
return 0;
}
//Purpose: To Wait the data in the queue. this function will return until program exits
// or there is one or more data in the queue
//Arguments description:
//pSafeQue --> the pointer to the safe message queue that contains two important semaphores.
//return value: 0 for success and other values for failure
int WaitDataInQue(pSafeMsgQue pSafeQue, unsigned int nTimeout)
{
/*
HANDLE hArr[2] ={
pSafeQue->hProExitEvn, //the flag of the program exit
pSafeQue->hMsgSem //semaphore for operation.
};
DWORD dResult = WaitForMultipleObjects( 2, //we have two semaphores
hArr, // the semaphore array
false, //we do not need to wait all the semaphore
INFINITE //wait the semaphore forever until the flag of the semaphore is true;
);
if (dResult - WAIT_OBJECT_0 == 0)
{
return false; //program exits;
}
else if (dResult - WAIT_OBJECT_0 == 1 )
{
return true;
}
else
{
return false;
}
return true;
*/
struct timespec ts;
ts.tv_sec = time(NULL)+ nTimeout; //VIP
ts.tv_nsec = 1;
int retVal = -1;
while( (retVal =sem_timedwait(&pSafeQue->hMsgSem, &ts)) == -1 && errno == EINTR);
#if DEBUG
if(retVal == -1) //There is some data in the queue.
{
if(errno == ETIMEDOUT)
{
printf("wait data time our.\n");
return -1;
}
else
{
printf("an error in wair for data.\n");
}
}
#endif
return retVal; //0 for success
}
//Purpose: To read and remove a message from the safe message queue
//Arguments description:
//msg --> the message to be gotten from the safe message queue
//pSafeQue --> the pointer to the safe message queue
//return value: 0 for success and other values for failure
int ReadOneMsg(pMsgQue* pMsg, pSafeMsgQue pSafeQue, unsigned int nTimeout)
{
if(pSafeQue == NULL ) //safe check
{
return -1;
}
else
{
*pMsg = NULL;
}
if(WaitDataInQue(pSafeQue, nTimeout) != 0)//safe opreation; To get the right to use the resurece
{
return -2;
}
if(LockQue(pSafeQue) != 0) // safe opreation; To get the right to use the resurece
{
return -3;
}
//check whether there is any data in the queue.
if(pSafeQue != NULL && pSafeQue->pHead != NULL)
{
*pMsg = pSafeQue->pHead;
pMsgQue pTempMsg = pSafeQue->pHead;
pSafeQue->pHead = pTempMsg->next;
pTempMsg->next = NULL;
}
else
{
*pMsg == NULL;
}
if(pSafeQue->pHead == NULL)
{
pSafeQue->pTail = NULL;
}
UnlockQue(pSafeQue);// safe operation; To give up the right to use the resurece to let another to use it.
if(*pMsg == NULL)
{
return -1;
}
return 0;
}
//Purpose: To get the right to use the resource of the safe message queue
//Arguments description:
//pSafeQue --> the pointer to the safe message queue that contains two important semaphores.
//return value: zero for success and other value for failure
int LockQue(pSafeMsgQue pSafeQue)
{
/*
HANDLE hArr[2] ={
pSafeQue->hProExitEvn, //the flag of the program exit
pSafeQue->hOpSem //semaphore for operation.
};
DWORD dResult = WaitForMultipleObjects( 2, //we have two semaphores
hArr, // the semaphore array
false, //we do not need to wait all the semaphore
INFINITE //wait the semaphore forever until the flag of the semaphore is true;
);
if (dResult - WAIT_OBJECT_0 == 0)
{
return false; //program exits;
}
else if (dResult - WAIT_OBJECT_0 == 1 )
{
return true;
}
else
{
return false;
}
return true;
*/
return pthread_mutex_lock(&pSafeQue->hOpLock);
}
//Purpose: To give up the right to use the resource of the safe message queue
//Arguments description:
//pSafeQue --> the pointer to the safe message queue that contains two important semaphores.
//return value: 0 for success and other values for failure
int UnlockQue(pSafeMsgQue pSafeQue)
{
// Increment the count of the semaphore.
/*
if (!ReleaseSemaphore(
pSafeQue->hOpSem, // handle to semaphore
1, // increase count by one
NULL) ) // not interested in previous count
{
return false;
}
return true;
*/
return pthread_mutex_unlock(&pSafeQue->hOpLock);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -