Flushes packet until first error. sentPackets is always updated, failedPacket is only set on non-SEND_BUFFER_OVERFLOW error. Failed packet will be skipped on next call.
| 478 | // sentPackets is always updated, failedPacket is only set on non-SEND_BUFFER_OVERFLOW error. |
| 479 | // Failed packet will be skipped on next call. |
| 480 | TUdpSocket::ESendError TUdpSocket::FlushPackets(size_t* numSentPackets, TVector<std::pair<char*, size_t>>* failedPackets) { |
| 481 | Y_ASSERT(!LastReturnedPacketBuffer); |
| 482 | |
| 483 | *numSentPackets = 0; |
| 484 | failedPackets->clear(); |
| 485 | ESendError err = SEND_OK; |
| 486 | |
| 487 | const size_t totalUdpPackets = GetNumUdpPacketsInQueue(); |
| 488 | size_t sentUdpPackets = 0; |
| 489 | |
| 490 | while (sentUdpPackets < totalUdpPackets) { |
| 491 | TMMsgHdr* udpPackets = &UdpPacketsHeaders[UdpPacketsHeadersBegin + sentUdpPackets]; |
| 492 | int sent = 0; |
| 493 | |
| 494 | if (S->IsSendMMsgSupported()) { |
| 495 | const unsigned int udpPacketsLeft(totalUdpPackets - sentUdpPackets); |
| 496 | sent = S->SendMMsg(udpPackets, udpPacketsLeft, 0); |
| 497 | if (sent > 0 && (ui32)sent != udpPacketsLeft) { |
| 498 | // printf("sendmmsg ate %d of %u packets\n", sent, udpPacketsLeft); |
| 499 | } |
| 500 | } else { |
| 501 | const ssize_t rv = S->SendMsg(&udpPackets->msg_hdr, 0, FF_ALLOW_FRAG); |
| 502 | sent = rv < 0 ? -1 : 1; |
| 503 | } |
| 504 | #ifdef SIMULATE_NO_ROUTE_TO_HOST |
| 505 | if (RandomNumber<size_t>() % 997 == 0) { |
| 506 | err = TUdpSocket::SEND_NO_ROUTE_TO_HOST; |
| 507 | break; |
| 508 | } |
| 509 | #endif |
| 510 | |
| 511 | if (sent < 0) { |
| 512 | err = GetSendErrorFromErrno(LastSystemError()); |
| 513 | break; |
| 514 | } |
| 515 | |
| 516 | sentUdpPackets += (size_t)sent; |
| 517 | } |
| 518 | |
| 519 | if (sentUdpPackets > 0 && UseSmallPacketsOptimization) { |
| 520 | const TMMsgHdr* udpPackets = &UdpPacketsHeaders[UdpPacketsHeadersBegin]; |
| 521 | *numSentPackets = Accumulate(udpPackets, udpPackets + sentUdpPackets, 0, TPacketsCountAdder()); |
| 522 | } else { |
| 523 | *numSentPackets = sentUdpPackets; |
| 524 | } |
| 525 | |
| 526 | if (sentUdpPackets == totalUdpPackets) { |
| 527 | ClearPacketsQueue(); |
| 528 | |
| 529 | } else { |
| 530 | ForgetHeadUdpPackets(sentUdpPackets); |
| 531 | |
| 532 | if (err == SEND_NO_ROUTE_TO_HOST || err == SEND_EINVAL) { |
| 533 | AddPacketsFromUdpPacket(UdpPacketsHeaders[UdpPacketsHeadersBegin].msg_hdr, failedPackets); |
| 534 | ForgetHeadUdpPackets(1); |
| 535 | |
| 536 | } else if (err == SEND_BUFFER_OVERFLOW) { |
| 537 | if (!S->IncreaseSendBuff()) { |
nothing calls this directly
no test coverage detected