* Prepare the next send request, if we need to. If one is already pending, * or if we're a sink and we don't need to do sends, then there's nothing * to do. * * Return 1 if another send completion is expected, 0 if not. */
| 1450 | * Return 1 if another send completion is expected, 0 if not. |
| 1451 | */ |
| 1452 | static int prep_next_send(struct io_uring *ring, struct conn *c, |
| 1453 | struct conn_dir *cd, int fd) |
| 1454 | { |
| 1455 | int bid; |
| 1456 | |
| 1457 | if (cd->pending_send || is_sink) |
| 1458 | return 0; |
| 1459 | if (!cd->out_buffers) |
| 1460 | return 0; |
| 1461 | |
| 1462 | bid = cd->snd_next_bid; |
| 1463 | if (bid == -1) |
| 1464 | bid = 0; |
| 1465 | |
| 1466 | if (send_ring) { |
| 1467 | /* |
| 1468 | * send_ring mode is easy, there's nothing to do but submit |
| 1469 | * our next send request. That will empty the entire outgoing |
| 1470 | * queue. |
| 1471 | */ |
| 1472 | submit_send(ring, c, cd, fd, NULL, 0, bid, 0); |
| 1473 | return 1; |
| 1474 | } else if (snd_msg) { |
| 1475 | /* |
| 1476 | * For sendmsg mode, submit our currently prepared iovec, if |
| 1477 | * we have one, and swap our iovecs so that any further |
| 1478 | * receives will start preparing that one. |
| 1479 | */ |
| 1480 | struct io_msg *imsg = &cd->io_snd_msg; |
| 1481 | |
| 1482 | if (!msg_vec(imsg)->iov_len) |
| 1483 | return 0; |
| 1484 | imsg->msg.msg_iov = msg_vec(imsg)->iov; |
| 1485 | imsg->msg.msg_iovlen = msg_vec(imsg)->iov_len; |
| 1486 | msg_vec(imsg)->iov_len = 0; |
| 1487 | imsg->vec_index = !imsg->vec_index; |
| 1488 | submit_send(ring, c, cd, fd, NULL, 0, bid, 0); |
| 1489 | return 1; |
| 1490 | } else { |
| 1491 | /* |
| 1492 | * send without send_ring - submit the next available vec, |
| 1493 | * if any. If this vec is the last one in the current series, |
| 1494 | * then swap to the next vec. We flag each send with MSG_MORE, |
| 1495 | * unless this is the last part of the current vec. |
| 1496 | */ |
| 1497 | struct io_msg *imsg = &cd->io_snd_msg; |
| 1498 | struct msg_vec *mvec = msg_vec(imsg); |
| 1499 | int flags = !snd_zc ? MSG_MORE : 0; |
| 1500 | struct iovec *iov; |
| 1501 | |
| 1502 | if (mvec->iov_len == mvec->cur_iov) |
| 1503 | return 0; |
| 1504 | imsg->msg.msg_iov = msg_vec(imsg)->iov; |
| 1505 | iov = &mvec->iov[mvec->cur_iov]; |
| 1506 | mvec->cur_iov++; |
| 1507 | if (mvec->cur_iov == mvec->iov_len) { |
| 1508 | mvec->iov_len = 0; |
| 1509 | mvec->cur_iov = 0; |
no test coverage detected