bool SessionUDP::AsyncRecv(TempOlapPtr& q) { if(!q) { return false; } MyOverLappedEx &idat(*q); idat.type=MyOverLapped::ACTION_UDP_RECV; idat.dbuf[0].buf=idat.buffer; idat.dbuf[0].len=4096; return DoAsyncRecv(q); }
bool SessionUDP::AsyncSend(TempOlapPtr& q) { if(!q) { return false; } MyOverLappedEx &idat(*q); idat.type=MyOverLapped::ACTION_UDP_SEND; idat.dbuf[0].buf=idat.buffer; idat.dbuf[0].len=idat.size; return DoAsyncSend(q); }
void SessionUDP::DoAsyncRecv() { #ifdef VHWD_WINDOWS TempPtrT<MyOverLappedEx> q=lkfq_recv.getq(); if(!q) { return; } MyOverLappedEx &idat(*q); int bRet=WSARecvFrom(sk_local.sock, &idat.dbuf[0], idat.dbuf[1].buf?2:1, &idat.size, &iocp_flag_recv, idat.peer, idat.peer, &idat.olap, NULL); if(bRet!=0 && WSAGetLastError()!=WSA_IO_PENDING) { --m_nPendingRecv; Disconnect(); return; } else { q.release(); } #else ep_ctl(EPOLLIN); #endif }
void SessionUDP::DoAsyncSend() { #ifdef VHWD_WINDOWS TempPtrT<MyOverLappedEx> q=lkfq_send.getq(); if(!q) { return; } MyOverLappedEx &idat(*q); int bRet=WSASendTo(sk_local.sock, &idat.dbuf[0], idat.dbuf[1].buf?2:1, &idat.size, 0, idat.peer, idat.peer.v4size(), &idat.olap, NULL); if(bRet!=0 && WSAGetLastError()!=WSA_IO_PENDING) { System::CheckError("WSASend Error"); Disconnect(); --m_nPendingSend; return; } else { q.release(); } #else ep_ctl(EPOLLOUT); #endif }
inline void IOCPPool::ccc_handle_iocp(Session* pkey,MyOverLapped* pdat) { Session& ikey(*pkey); MyOverLapped& idat(*pdat); switch(idat.type) { case MyOverLapped::ACTION_UDP_SEND: { TempPtrT<MyOverLappedEx> q(static_cast<MyOverLappedEx*>(&idat)); if(idat.size<=0) { ikey.Disconnect(); } else if(!ikey.IsError()) { accounter.nSendBytes.fetch_add(idat.size); accounter.nSendCount++; ikey.OnSendCompleted(q); static_cast<SessionUDP&>(ikey).DoAsyncSend(); } --ikey.m_nPendingSend; } break; case MyOverLapped::ACTION_TCP_SEND: { TempPtrT<MyOverLappedEx> q(static_cast<MyOverLappedEx*>(&idat)); if(idat.size<=0) { ikey.Disconnect(); } else if(!ikey.IsError()) { accounter.nSendBytes.fetch_add(idat.size); accounter.nSendCount++; ikey.OnSendCompleted(q); static_cast<SessionTCP&>(ikey).DoAsyncSend(); } --ikey.m_nPendingSend; } break; case MyOverLapped::ACTION_UDP_RECV: { ikey.tpLast=accounter.tTimeStamp; TempPtrT<MyOverLappedEx> q(static_cast<MyOverLappedEx*>(&idat)); if(idat.size<=0) { ikey.Disconnect(); } else if(!ikey.IsError()) { accounter.nRecvBytes.fetch_add(idat.size); accounter.nRecvCount++; ikey.OnRecvCompleted(q); static_cast<SessionUDP&>(ikey).DoAsyncRecv(); } --ikey.m_nPendingRecv; } break; case MyOverLapped::ACTION_TCP_RECV: { ikey.tpLast=accounter.tTimeStamp; TempPtrT<MyOverLappedEx> q(static_cast<MyOverLappedEx*>(&idat)); if(idat.size<=0) { ikey.Disconnect(); } else if(!ikey.IsError()) { accounter.nRecvBytes.fetch_add(idat.size); accounter.nRecvCount++; ikey.OnRecvCompleted(q); static_cast<SessionTCP&>(ikey).DoAsyncRecv(); } --ikey.m_nPendingRecv; } break; case MyOverLapped::ACTION_ACCEPT: case MyOverLapped::ACTION_WAIT_RECV: { ikey.tpLast=accounter.tTimeStamp; if(idat.size<0) { ikey.Disconnect(); } else if(!ikey.IsError()) { accounter.nRecvCount++; ikey.OnRecvReady(); static_cast<SessionTCP&>(ikey).DoAsyncRecv(); } --ikey.m_nPendingRecv; } break; case MyOverLapped::ACTION_WAIT_SEND: { if(idat.size<0) { ikey.Disconnect(); } else if(!ikey.IsError()) { accounter.nSendCount++; ikey.OnSendReady(); static_cast<SessionTCP&>(ikey).DoAsyncSend(); } --ikey.m_nPendingSend; } break; default: System::LogTrace("Invalid pdat_type %d",idat.type); ikey.Disconnect(); break; } }