void IOCPPool::HandleSend(Session& ikey) { if(ikey.m_nPendingSend.get()==0) { return; } TempOlapPtr q=ikey.tmp_send; for(;; q.reset(NULL)) { if(!q) { q=ikey.lkfq_send.getq(); if(!q) break; q->size=0; if(q->type==MyOverLapped::ACTION_WAIT_SEND) { ikey.m_nPendingSend--; ikey.OnSendReady(); ikey.lkfq_free.putq(q); continue; } } if(q->type==MyOverLapped::ACTION_UDP_SEND) { int bRet=ikey.sk_local.sock.send(q->dbuf[0].buf,q->dbuf[0].len,q->peer); if(bRet>0) { q->size=bRet; accounter.nSendBytes.fetch_add(q->size); accounter.nSendCount++; ikey.m_nPendingSend--; ikey.OnSendCompleted(q); continue; } else if(bRet==0) { ikey.tmp_send=q; break; } else { ikey.Disconnect(); break; } } for(;;) { int bRet=ikey.sk_local.sock.send(q->dbuf[0].buf+q->size,q->dbuf[0].len-q->size); if(bRet<0) { if(errno==EAGAIN) { ikey.tmp_send=q; break; } if(errno==EINTR) { continue; } ikey.Disconnect(); break; } else if(bRet==0) { ikey.tmp_send=q; return; } q->size+=bRet; if(q->size==q->dbuf[0].len) { accounter.nSendCount++; accounter.nSendBytes.fetch_add(q->size); ikey.m_nPendingSend--; ikey.OnSendCompleted(q); break; } } } }