int CUdpCast::SendInternal(const BYTE* pBuffer, int iLength) { int result = NO_ERROR; if(HasStarted()) { CCriSecLock locallock(m_csSend); if(HasStarted()) { ASSERT(m_iPending >= 0); BOOL isPending = m_iPending > 0; TItem* pItem = m_itPool.PickFreeItem(); pItem->Cat(pBuffer, iLength); m_lsSend.PushBack(pItem); m_iPending += iLength; if(!isPending) m_evBuffer.Set(); } else result = ERROR_INVALID_STATE; } else result = ERROR_INVALID_STATE; return result; }
TItem* CItemPool::PickFreeItem() { TItem* pItem = nullptr; if(m_lsFreeItem.TryGet(&pItem)) pItem->Reset(); else pItem = TItem::Construct(m_heap, m_dwItemCapacity); return pItem; }
int CUdpServer::CatAndPost(TUdpSocketObj* pSocketObj, const BYTE* pBuffer, int iLength, BOOL isPostSend) { int result = NO_ERROR; TItem* pItem = m_itPool.PickFreeItem(); pItem->Cat(pBuffer, iLength); pSocketObj->sndBuff.PushBack(pItem); pSocketObj->pending += iLength; if(isPostSend && !::PostIocpSend(m_hCompletePort, pSocketObj->connID)) result = ::GetLastError(); return result; }
int TItemList::Reduce(int length) { int remain = length; while(remain > 0 && Size() > 0) { TItem* pItem = Front(); remain -= pItem->Reduce(remain); if(pItem->IsEmpty()) itPool.PutFreeItem(PopFront()); } return length - remain; }
int TItemList::Peek(BYTE* pData, int length) { int remain = length; TItem* pItem = Front(); while(remain > 0 && pItem != nullptr) { int peek = pItem->Peek(pData, remain); pData += peek; remain -= peek; pItem = pItem->next; } return length - remain; }
int TItemList::Fetch(BYTE* pData, int length) { int remain = length; while(remain > 0 && Size() > 0) { TItem* pItem = Front(); int fetch = pItem->Fetch(pData, remain); pData += fetch; remain -= fetch; if(pItem->IsEmpty()) itPool.PutFreeItem(PopFront()); } return length - remain; }
TItem* CItemPool::PickFreeItem() { TItem* pItem = nullptr; if(m_lsFreeItem.Size() > 0) { CCriSecLock locallock(m_csFreeItem); if(m_lsFreeItem.Size() > 0) pItem = m_lsFreeItem.PopFront(); } if(pItem == nullptr) pItem = TItem::Construct(m_heap, m_dwItemCapacity); else pItem->Reset(); return pItem; }
int TItemList::Cat(const BYTE* pData, int length) { int remain = length; while(remain > 0) { TItem* pItem = Back(); if(pItem == nullptr || pItem->IsFull()) pItem = PushBack(itPool.PickFreeItem()); int cat = pItem->Cat(pData, remain); pData += cat; remain -= cat; } return length; }
BOOL CUdpServer::Send(CONNID dwConnID, const BYTE* pBuffer, int iLength, int iOffset) { ASSERT(pBuffer && iLength > 0 && iLength <= (int)m_dwMaxDatagramSize); if(iOffset != 0) pBuffer += iOffset; if(!pBuffer || iLength <= 0 || iLength > (int)m_dwMaxDatagramSize) { ::SetLastError(ERROR_INVALID_PARAMETER); return FALSE; } int result = NO_ERROR; TUdpSocketObj* pSocketObj = FindSocketObj(dwConnID); if(!TUdpSocketObj::IsValid(pSocketObj)) result = ERROR_OBJECT_NOT_FOUND; else { CCriSecLock locallock(pSocketObj->crisec); if(!TUdpSocketObj::IsValid(pSocketObj)) result = ERROR_OBJECT_NOT_FOUND; else { BOOL isPending = TUdpSocketObj::IsPending(pSocketObj); TItem* pItem = m_itPool.PickFreeItem(); pItem->Cat(pBuffer, iLength); pSocketObj->sndBuff.PushBack(pItem); pSocketObj->pending += iLength; if(!isPending && !::PostIocpSend(m_hCompletePort, dwConnID)) result = ::GetLastError(); } } if(result != NO_ERROR) ::SetLastError(result); return (result == NO_ERROR); }
virtual TItem* pop() { TItem* item = 0; if ((item = first_)) { TItem* next = 0; if ((next = item->next())) next->set_prev(0); else last_ = 0; first_ = next; item->set_next(0); item->set_prev(0); } return item; }
virtual TItem* pull() { TItem* item = 0; if ((item = last_)) { TItem* prev = 0; if ((prev = item->prev())) prev->set_next(0); else first_ = 0; last_ = prev; item->set_next(0); item->set_prev(0); } return item; }
inline int TItem::Cat(const TItem& other) { ASSERT(this != &other); return Cat(other.Ptr(), other.Size()); }