X-Git-Url: https://repo.jachan.dev/qemu.git/blobdiff_plain/09f06a6c603ce64284287d32f6ffadaaa5064850..26a8c353bf0ffb485f4a68bea97efcef7d2bbaa3:/qemu-coroutine-io.c diff --git a/qemu-coroutine-io.c b/qemu-coroutine-io.c index 5734965003..d4049260da 100644 --- a/qemu-coroutine-io.c +++ b/qemu-coroutine-io.c @@ -23,9 +23,10 @@ * 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" +#include "qemu/main-loop.h" ssize_t coroutine_fn qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, @@ -33,13 +34,15 @@ qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt, { size_t done = 0; ssize_t ret; + int err; 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) { + err = socket_error(); + if (err == EAGAIN || err == EWOULDBLOCK) { qemu_coroutine_yield(); } else if (done == 0) { return -1; @@ -63,3 +66,26 @@ qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send) struct iovec iov = { .iov_base = buf, .iov_len = bytes }; return qemu_co_sendv_recvv(sockfd, &iov, 1, 0, bytes, do_send); } + +typedef struct { + Coroutine *co; + int fd; +} FDYieldUntilData; + +static void fd_coroutine_enter(void *opaque) +{ + FDYieldUntilData *data = opaque; + qemu_set_fd_handler(data->fd, NULL, NULL, NULL); + qemu_coroutine_enter(data->co, NULL); +} + +void coroutine_fn yield_until_fd_readable(int fd) +{ + FDYieldUntilData data; + + assert(qemu_in_coroutine()); + data.co = qemu_coroutine_self(); + data.fd = fd; + qemu_set_fd_handler(fd, fd_coroutine_enter, NULL, &data); + qemu_coroutine_yield(); +}