X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/3e80bf9351f8fec9085c46df6da075efd5e71003..bc7d0e66741724216cc104034838eb34f0e94b8d:/qemu-coroutine-io.c diff --git a/qemu-coroutine-io.c b/qemu-coroutine-io.c index 0461a9aae6..e8ad1a4011 100644 --- a/qemu-coroutine-io.c +++ b/qemu-coroutine-io.c @@ -23,75 +23,43 @@ * THE SOFTWARE. */ #include "qemu-common.h" -#include "qemu_socket.h" -#include "qemu-coroutine.h" -#include "iov.h" +#include "qemu/sockets.h" +#include "block/coroutine.h" +#include "qemu/iov.h" -int coroutine_fn qemu_co_recvv(int sockfd, struct iovec *iov, - int len, int iov_offset) +ssize_t coroutine_fn +qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, + size_t offset, size_t bytes, bool do_send) { - int total = 0; - int ret; - while (len) { - ret = iov_recv(sockfd, iov, iov_offset + total, len); - if (ret < 0) { + size_t done = 0; + ssize_t ret; + while (done < bytes) { + ret = iov_send_recv(sockfd, iov, iov_cnt, + offset + done, bytes - done, do_send); + if (ret > 0) { + done += ret; + } else if (ret < 0) { if (errno == EAGAIN) { qemu_coroutine_yield(); - continue; - } - if (total == 0) { - total = -1; - } - break; - } - if (ret == 0) { - break; - } - total += ret, len -= ret; - } - - return total; -} - -int coroutine_fn qemu_co_sendv(int sockfd, struct iovec *iov, - int len, int iov_offset) -{ - int total = 0; - int ret; - while (len) { - ret = iov_send(sockfd, iov, iov_offset + total, len); - if (ret < 0) { - if (errno == EAGAIN) { - qemu_coroutine_yield(); - continue; - } - if (total == 0) { - total = -1; + } else if (done == 0) { + return -1; + } else { + break; } + } else if (ret == 0 && !do_send) { + /* write (send) should never return 0. + * read (recv) returns 0 for end-of-file (-data). + * In both cases there's little point retrying, + * but we do for write anyway, just in case */ break; } - total += ret, len -= ret; } - - return total; + return done; } -int coroutine_fn qemu_co_recv(int sockfd, void *buf, int len) +ssize_t coroutine_fn +qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send) { - struct iovec iov; - - iov.iov_base = buf; - iov.iov_len = len; - - return qemu_co_recvv(sockfd, &iov, len, 0); -} - -int coroutine_fn qemu_co_send(int sockfd, void *buf, int len) -{ - struct iovec iov; - - iov.iov_base = buf; - iov.iov_len = len; - - return qemu_co_sendv(sockfd, &iov, len, 0); + struct iovec iov = { .iov_base = buf, .iov_len = bytes }; + return qemu_co_sendv_recvv(sockfd, &iov, 1, 0, bytes, do_send); }