void IOCPPool::HandleRecv(Session& ikey) { if(ikey.m_nPendingRecv.get()==0) { return; } for(;;) { TempOlapPtr q=ikey.lkfq_recv.getq(); if(!q) { break; } if(q->type==MyOverLapped::ACTION_WAIT_RECV) { ikey.m_nPendingRecv--; ikey.OnRecvReady(); break; } if(q->type==MyOverLapped::ACTION_UDP_RECV) { int bRet=ikey.sk_local.sock.recv(q->dbuf[0].buf,q->dbuf[0].len,q->peer); if(bRet>0) { q->size=bRet; accounter.nRecvBytes.fetch_add(bRet); accounter.nSendCount++; ikey.m_nPendingRecv--; ikey.OnRecvCompleted(q); break; } else if(bRet<0) { ikey.m_nPendingRecv--; ikey.Disconnect(); break; } else { ikey.m_nPendingRecv--; this_logger().LogMessage("recv udp failed"); } break; } q->size=0; for(;;) { int bRet=ikey.sk_local.sock.recv(q->dbuf[0].buf+q->size,q->dbuf[0].len-q->size); if(bRet<0) { if(errno==EAGAIN) { break; } if(errno==EINTR) { continue; } ikey.Disconnect(); break; } else if(bRet==0) { break; } q->size+=bRet; break; } if(q->size>0) { accounter.nRecvCount++; accounter.nRecvBytes.fetch_add(q->size); ikey.m_nPendingRecv--; ikey.OnRecvCompleted(q); } else { ikey.m_nPendingRecv--; } break; } }