typedef struct tagONLY_CIRCLE_MEM
{
UINT32 nMemSize;
UINT8 *pBuf;
UINT8 *pWrite;
UINT8 *pRead;
BOOL bTag; //是否pWrite是在pRead之后
#ifdef WIN32
HMUTEX hBufMutex;
#elif _LINUX
pthread_mutex_t hBufMutex;
#endif
}ONLY_CIRCLE_MEM PACKED;
typedef void* HOCM
HOM ocmAlloc(UINT32 nMemSize)
{
ONLY_CIRCLE_MEM *pOCM = malloc(sizeof(ONLY_CIRCLE_MEM));
if(pOCM==NULL)
return NULL;
pOCM->pBuf = malloc(nMemSize);
if(pOCM->pBuf==NULL)
{
free(pOCM);
return NULL;
}
pOCM->pWrite = pOCM->pBuf;
pOCM->pRead = pOCM->pBuf;
pOCM->nMemSize = nMemSize;
pOCM->bTag = TRUE;
#ifdef WIN32
pOCM->hBufMutex=CreateMutex(NULL, FALSE, NULL);
#elif _LINUX
pOCM->hBufMutex = (pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
#endif
return pOCM;
}
void ocmFree(HOCM hocm)
{
ONLY_CIRCLE_MEM *pOCM =(ONLY_CIRCLE_MEM*)hocm;
if(pOCM==NULL)
return;
#ifdef WIN32
CloseHandle(pOCM->hBufMutex);
#elif _LINUX
pthread_mutex_destroy(&pOCM->hBufMutex);
#endif
if(pOCM->pBuf!=NULL)
{
free(pOCM->pBuf);
}
pOCM->pRead = NULL;
pOCM->pWrite = NULL;
free(pOCM);
}
UINT32 ocmPut(HOCM hocm, void *pBuf, UINT32 nBufLen)
{
ONLY_CIRCLE_MEM *pOCM = (ONLY_CIRCLE_MEM*)hocm;
UINT32 nLeftLen=nBufLen;
INT32 rc;
if(pOCM==NULL || pOCM->pBuf ==NULL)
{
return 0;
}
#ifdef WIN32
WaitForSingleObject(pOCM->hBufMutex, INFINITE);
#elif _LINUX
rc = pthread_mutex_lock(&pOCM->hBufMutex);
if(rc)
{
printf("Cannot lock the thread mutex\n");
pthread_exit(NULL);
}
#endif
while(nLeftLen>0)
{
if(pOCM->bTag)
{
if( pOCM ->pBuf+pOCM->nMemSize-pOCM->pWrite>nLeftLen)
{
memcpy(pOCM->pWrite, (UINT8*)pBuf+(nBufLen-nLeftLen), nLeftLen);
pOCM->pWrite += nLeftLen;
nLeftLen = 0;
}
else
{
memcpy(pOCM->pWrite, (UINT8*)pBuf+(nBufLen-nLeftLen), pOCM->pBuf+pOCM->nMemSize-pOCM->pWrite);
nLeftLen -= pOCM->pBuf+pOCM->nMemSize-pOCM->pWrite;
pOCM->pWrite = pOCM->pBuf;
pOCM->bTag = FALSE;
}
}
else
{
if(pOCM->pRead-pOCM->pWrite>nLeftLen)
{
memcpy(pOCM->pWrite, (UINT8*)pBuf+(nBufLen-nLeftLen), nLeftLen);
pOCM->pWrite += nLeftLen;
nLeftLen=0;
}
else
{
memcpy(pOCM->pWrite, (UINT8*)pBuf+(nBufLen-nLeftLen), pOCM->pRead-pOCM->pWrite);
nLeftLen -= pOCM->pRead-pOCM->pWrite;
pOCM->pWrite = pOCM->pRead;
break;
}
}
}
#ifdef WIN32
ReleaseMutex(pOCM->hBufMutex);
#elif _LINUX
rc = pthread_mutex_unlock(&pOCM->hBufMutex);
if(rc)
{
printf("Cannot unlock the thread mutex\n");
pthread_exit(NULL);
}
#endif
return nBufLen-nLeftLen;
}
UINT32 ocmGet(HOM hocm, void *pBuf, UINT32 nDataLen)
{
ONLY_CIRCLE_MEM *pOCM = (ONLY_CIRCLE_MEM*)hocm;
UINT32 nLeftLen=nDataLen;
INT32 rc;
if(pOCM==NULL ||pOCM->pBuf==NULL)
{
return 0;
}
#ifdef WIN32
WaitForSingleObject(pOCM->hBufMutex, INFINITE);
#elif _LINUX
rc = pthread_mutex_lock(&pOCM->hBufMutex);
if(rc)
{
printf("Cannot lock the thread mutex\n");
pthread_exit(NULL);
}
#endif
while(nLeftLen>0)
{
if(pOCM->bTag)
{
if(pOCM->pWrite-pOCM->pRead >nLeftLen)
{
memcpy((UINT8*)pBuf+(nDataLen-nLeftLen), pOCM->pRead, nLeftLen);
pOCM->pRead += nLeftLen;
nLeftLen = 0;
}
else
{
memcpy((UINT8*)pBuf+(nDataLen-nLeftLen), pOCM->pRead, pOCM->pWrite-pOCM->pRead);
nLeftLen -= (pOCM->pWrite-pOCM->pRead);
pOCM->pRead = pOCM->pWrite;
break;
}
}
else
{
if(pOCM->pBuf+pOCM->nMemSize-pOCM->pRead>nLeftLen)
{
memcpy((UINT8*)pBuf+(nDataLen-nLeftLen), pOCM->pRead, nLeftLen);
pOCM->pRead+=nLeftLen;
nLeftLen=0;
}
else
{
memcpy((UINT8*)pBuf+(nDataLen-nLeftLen), pOCM->pRead, pOCM->pBuf+pOCM->nMemSize-pOCM->pRead);
nLeftLen -= pOCM->pBuf+pOCM->nMemSize-pOCM->pRead;
pOCM->pRead = pOCM->pBuf;
pOCM->bTag = TRUE;
}
}
}
#ifdef WIN32
ReleaseMutex(pOCM->hBufMutex);
#elif _LINUX
rc = pthread_mutex_unlock(&pOCM->hBufMutex);
if(rc)
{
printf("Cannot unlock the thread mutex\n");
pthread_exit(NULL);
}
#endif
return nDataLen-nLeftLen;
}