diff options
author | Anthony Liguori <aliguori@us.ibm.com> | 2012-07-09 12:35:06 -0500 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2012-07-09 12:35:06 -0500 |
commit | 23797df3d9f08031d19aaaa1d2863d5feebe3d8b (patch) | |
tree | f5d64b0378d44db24d18dd5e869fdfa2253b6b45 /qemu-coroutine-io.c | |
parent | 3f6e9a5fad982713440c636f5f7b786e1cc86ca2 (diff) | |
parent | 25e5e4c7e9d5ec3e95c9526d1abaca40ada50ab0 (diff) |
Merge remote-tracking branch 'mjt/mjt-iov2' into staging
* mjt/mjt-iov2:
rewrite iov_send_recv() and move it to iov.c
cleanup qemu_co_sendv(), qemu_co_recvv() and friends
export iov_send_recv() and use it in iov_send() and iov_recv()
rename qemu_sendv to iov_send, change proto and move declarations to iov.h
change qemu_iovec_to_buf() to match other to,from_buf functions
consolidate qemu_iovec_copy() and qemu_iovec_concat() and make them consistent
allow qemu_iovec_from_buffer() to specify offset from which to start copying
consolidate qemu_iovec_memset{,_skip}() into single function and use existing iov_memset()
rewrite iov_* functions
change iov_* function prototypes to be more appropriate
virtio-serial-bus: use correct lengths in control_out() message
Conflicts:
tests/Makefile
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'qemu-coroutine-io.c')
-rw-r--r-- | qemu-coroutine-io.c | 83 |
1 files changed, 26 insertions, 57 deletions
diff --git a/qemu-coroutine-io.c b/qemu-coroutine-io.c index 40fd514395..5734965003 100644 --- a/qemu-coroutine-io.c +++ b/qemu-coroutine-io.c @@ -25,72 +25,41 @@ #include "qemu-common.h" #include "qemu_socket.h" #include "qemu-coroutine.h" +#include "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 = qemu_recvv(sockfd, iov, len, iov_offset + total); - 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 = qemu_sendv(sockfd, iov, len, iov_offset + total); - 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); } |