///////////////////////////////////////////////////////////////////////// // 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; }
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(); }
///////////////////////////////////////////////////////////////////////// // 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; }
/*********************************************** 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; }
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(); }
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; }