예제 #1
0
/////////////////////////////////////////////////////////////////////////
// WritePos 에 데이타 넣음.
//
// Parameters: (char *)데이타 포인터. (int)크기. 
// Return: (int)넣은 크기.
/////////////////////////////////////////////////////////////////////////
int	CAyaStreamSQ::Put(char *chpData, int iSize)
{
	if (GetFreeSize() < iSize)
		iSize = GetFreeSize();
	if (GetNotBrokenPutSize() < iSize && m_iWritePos < m_iReadPos)
		iSize = GetNotBrokenPutSize();

	for (int iCnt = 0; iCnt < iSize; iCnt++)
	{
		m_chpBuffer[m_iWritePos++] = chpData[iCnt];
		if (m_iWritePos >= m_iBufferSize)	m_iWritePos = 0;
	}
	
	return iSize;
}
예제 #2
0
int	CAyaStreamSQ::GetNotBrokenPutSize(void)
{
	if (m_iWritePos < m_iReadPos)
		return GetBufferSize() - m_iWritePos;
	else
		return GetFreeSize();
}
void  CPs_CircleBuffer::Write(const void* _pSourceBuffer, const unsigned int _iNumBytes)
{
	unsigned int iBytesToWrite = _iNumBytes;
	unsigned char* pSourceReadCursor = (unsigned char*)_pSourceBuffer;

	//CP_ASSERT(iBytesToWrite <= GetFreeSize());//修改为没有足够空间就返回,write前一定要加GetFreeSize判断,否则进入到这里相当于丢掉数据,         // long120817
	if (iBytesToWrite > GetFreeSize())
	{
		return;
	}
	//_ASSERT(m_bComplete == false);

	m_csCircleBuffer.Lock();

	if (m_iWriteCursor >= m_iReadCursor)
	{
		//              0                                            m_iBufferSize
		//              |-----------------|===========|--------------|
		//                                pR->        pW-> 
		// 计算尾部可写空间iChunkSize,long120817
		unsigned int iChunkSize = m_iBufferSize - m_iWriteCursor;

		if (iChunkSize > iBytesToWrite)
		{
			iChunkSize = iBytesToWrite;
		}

		// Copy the data
		memcpy(m_pBuffer + m_iWriteCursor,pSourceReadCursor, iChunkSize);

		pSourceReadCursor += iChunkSize;

		iBytesToWrite -= iChunkSize;

		// 更新m_iWriteCursor
		m_iWriteCursor += iChunkSize;

		if (m_iWriteCursor >= m_iBufferSize)//如果m_iWriteCursor已经到达末尾
			m_iWriteCursor -= m_iBufferSize;//返回到起点0位置,long120817

	}

	//剩余数据从Buffer起始位置开始写
	if (iBytesToWrite)
	{
		memcpy(m_pBuffer + m_iWriteCursor,pSourceReadCursor, iBytesToWrite);
		m_iWriteCursor += iBytesToWrite;
		//_ASSERT(m_iWriteCursor < m_iBufferSize);//这个断言没什么意思,应该_ASSERT(m_iWriteCursor <= m_iReadCursor);long20120817
	}

	SetEvent(m_evtDataAvailable);//设置数据写好信号量

	m_csCircleBuffer.UnLock();
}
예제 #4
0
/////////////////////////////////////////////////////////////////////////
// Write 의 위치를 이동하는 함수.
//
// Parameters: 없음.
// Return: (int)Write 이동 사이즈
/////////////////////////////////////////////////////////////////////////
int	CAyaStreamSQ::MoveWritePos(int iSize)
{
	if (GetFreeSize() < iSize)
		return 0;
	else
	{
		if (m_iWritePos + iSize >= GetBufferSize())
			m_iWritePos = (m_iWritePos + iSize) % GetBufferSize();
		else
			m_iWritePos += iSize;
	}

	return iSize;
}
예제 #5
0
/***********************************************
Write
	Writes data to the write pointer and adjusts
	the write pointer.
PARAM:
	pbBuffer - pointer to the buffer to receive
			   write data
	count    - the number of bytes to write
RETURN:
	The actual number of bytes written
************************************************/
int CUT_FIFO_Queue::Write(LPBYTE pbBuffer, unsigned int count) {

	int nNumToWrite = min(GetFreeSize(), (int)count);
	int nNumWritten = 0;

	if(m_iWritePointer + nNumToWrite > m_cbBuffer) {

		int nNumAtEnd = m_cbBuffer - m_iWritePointer;

		memcpy(m_pbBuffer + m_iWritePointer, pbBuffer, nNumAtEnd);
		nNumWritten += nNumAtEnd;
		nNumToWrite -= nNumAtEnd;
		m_iWritePointer = 0 ;
	}

	memcpy(m_pbBuffer + m_iWritePointer, pbBuffer + nNumWritten, nNumToWrite);

	nNumWritten += nNumToWrite;
	m_iWritePointer += nNumToWrite;

	return nNumWritten;
}
예제 #6
0
bool CRingBuffer::WriteBytes(void *pData, long nBytes)
{
    long p1len, p2len;
    if(nBytes > GetFreeSize())
    {
        return false;
    }
    
    p1len = min(nBytes, m_nTotalBytes - m_nInPtr);
    p2len = nBytes - p1len;
    // copy first bit (up to the end of the buffer, or end of source data, whichever comes first)
    RtlCopyMemory(m_pBase + m_nInPtr, pData, p1len);
    if(p2len)
    {
        // if there was an overlap, copy the rest as well
        RtlCopyMemory(m_pBase, (unsigned char *)pData + p1len, p2len);
    }
    m_nInPtr += nBytes;
    m_nInPtr = MYMOD(m_nInPtr, m_nTotalBytes);
    
    InterlockedExchangeAdd(&m_nBytes, nBytes);
    
    return true;
}
//获取已经写的内存
unsigned int CPs_CircleBuffer::GetUsedSize()
{
	return m_iBufferSize - GetFreeSize();

}
예제 #8
0
        bool TMdbNtcMessageQueue::Send(MDB_UINT16 uiType, const void* pBuffer, MDB_UINT32 uiLength /* = -1 */, bool bAllowOverlap /* = false */)
        {
            MDB_NTC_ZF_ASSERT(m_pMgrInfo);            
            if (uiLength == (MDB_UINT32)-1)
            {
                uiLength = pBuffer?  (MDB_UINT32)strlen((const char*)pBuffer):0;
            }
            if(GetFreeSize() < uiLength && !bAllowOverlap)
            {
                return false;
            }
            MDB_UINT32 uiMsgLen = ms_uiMsgHeadLen + uiLength;
            bool bRet = false;
            if(!m_pPushLock->Lock())
            {
                return false;
            }
            MDB_UINT32 uiPopCursor  = m_pMgrInfo->uiPopCursor;
            MDB_UINT32 uiNewPushCursor = m_pMgrInfo->uiPushCursor;
            bool bNotify = false; //是否需要通知等待Receive的线程
            do
            {
                if (uiNewPushCursor > uiPopCursor)
                {
                    if (uiNewPushCursor > m_uiShmSize-uiMsgLen)//末端不够存放
                    {
                        uiNewPushCursor = 0; //将Push游标移到共享内存前段
                        if (uiPopCursor >= uiMsgLen)//前端够存放
                        {
                            bRet = true;
                            break;
                        }
                    }
                    else//末端够存放
                    {
                        bRet = true;
                        break;
                    }
                }
                else if(uiNewPushCursor == uiPopCursor)
                {
                    if(m_pMgrInfo->uiPushTimes == m_pMgrInfo->uiPopTimes)
                    {
                        uiNewPushCursor = 0;//说明无数据,将游标移到头部
                        if(!m_pPopLock->Lock())
                        {
                            m_pPushLock->Unlock();
                            return false;
                        }
                        m_pMgrInfo->uiPopCursor = 0;
                        m_pPopLock->Unlock();
                        bRet = true;
                        break;
                    }
                }
                else if (uiPopCursor-uiNewPushCursor >= uiMsgLen)//说明之间的区域是够存放
                {
                    bRet = true;
                    break;
                }
                //如果之间区域不够存放,且push到末尾的区域也不够存放,则需要将push移到头位置
                else if(m_uiShmSize-uiNewPushCursor < uiMsgLen)
                {
                    uiNewPushCursor = 0;
                }
                //下面是针对不够存放的情况,做覆盖处理
                if(bAllowOverlap && m_uiShmSize >= uiMsgLen)
                {
                    bRet = true;//做覆盖
                    if(!m_pPopLock->Lock())
                    {
                        bRet = false;
                        break;
                    }
                    MDB_UINT32& uiPopCursor  = m_pMgrInfo->uiPopCursor;//重新赋值一次,得到最新的
                    MDB_UINT32 uiCurMsgLen = 0, iValidLength = uiPopCursor-uiNewPushCursor;
                    while(iValidLength < uiMsgLen)
                    {
                        if(uiPopCursor == m_pMgrInfo->uiPushCursor
                            && m_pMgrInfo->uiPushTimes == m_pMgrInfo->uiPopTimes)//说明已经全部取完,故可以从头开始存放
                        {
                            uiPopCursor = 0;
                            uiNewPushCursor = 0;
                            break;
                        }
                        else if(uiPopCursor <= m_uiShmSize-ms_uiMsgHeadLen)
                        {
                            memcpy(&uiCurMsgLen, m_pContentAddr + uiPopCursor + sizeof(uiType), sizeof(uiCurMsgLen));
                        }
                        else//末尾不够存放
                        {
                            uiCurMsgLen = (MDB_UINT32)-1;                            
                        }
                        if(uiCurMsgLen == (MDB_UINT32)-1)
                        {
                            uiPopCursor = 0;//从头开始
                            uiNewPushCursor = 0;//必须从头开始连续存放
                            iValidLength = 0;
                        }
                        else
                        {
                            /*
                            printf("now[%u] pop %u vs %u\nused_size[%u], pop_cursor[%u], push_cursor[%u], newpush_cursor[%u]\n",
                                m_uiShmSize,
                                m_pMgrInfo->uiPushTimes, m_pMgrInfo->uiPopTimes,
                                GetUsedSize(),
                                m_pMgrInfo->uiPopCursor, m_pMgrInfo->uiPushCursor, uiNewPushCursor); 
                                */
                            if(m_fnMsgOverlappedCallback)
                            {
                                m_fnMsgOverlappedCallback(this, *(MDB_UINT16*)(m_pContentAddr + uiPopCursor),
                                    m_pContentAddr + uiPopCursor+ms_uiMsgHeadLen, uiCurMsgLen, m_pMsgOverlappedArg);
                            }
                            uiPopCursor += uiCurMsgLen+ms_uiMsgHeadLen;
                            ++m_pMgrInfo->uiPopTimes;
                            iValidLength += uiCurMsgLen+ms_uiMsgHeadLen;
                        }
                    }
                    m_pPopLock->Unlock();
                }
            } while (0);
            if(bRet)
            {
                if(m_pMgrInfo->uiPushCursor != uiNewPushCursor)
                {
                    if(m_pMgrInfo->uiPushCursor <= m_uiShmSize-ms_uiMsgHeadLen)//需要将上一次push开始的位置置为0xFF,这样不至于被pop到
                    {
                        memset(m_pContentAddr+m_pMgrInfo->uiPushCursor, 0xFF, ms_uiMsgHeadLen); //写消息头长度信息为-1
                    }
                    m_pMgrInfo->uiPushCursor = uiNewPushCursor;
                }
                SetMsgHead(uiType, uiLength); //写消息头长度信息
                if(pBuffer && uiLength > 0)
                {
                    memcpy(m_pContentAddr + uiNewPushCursor + ms_uiMsgHeadLen, pBuffer, uiLength); //写消息体
                }
                m_pMgrInfo->uiPushCursor += uiMsgLen;
                m_pMgrInfo->uiPushTimes++;
                m_pMgrInfo->uiLastPushTime = (MDB_UINT32)time(NULL);
                bNotify = MDB_ABS(m_pMgrInfo->uiPushTimes-m_pMgrInfo->uiPopTimes)==1;
            }
            m_pPushLock->Unlock();
            if (bNotify)
            {
                m_pEvent->SetEvent();
            }

            return bRet;
        }