summaryrefslogtreecommitdiffstats
path: root/qemu-coroutine-io.c
diff options
context:
space:
mode:
authorAnthony Liguori <aliguori@us.ibm.com>2012-07-09 12:35:06 -0500
committerAnthony Liguori <aliguori@us.ibm.com>2012-07-09 12:35:06 -0500
commit23797df3d9f08031d19aaaa1d2863d5feebe3d8b (patch)
treef5d64b0378d44db24d18dd5e869fdfa2253b6b45 /qemu-coroutine-io.c
parent3f6e9a5fad982713440c636f5f7b786e1cc86ca2 (diff)
parent25e5e4c7e9d5ec3e95c9526d1abaca40ada50ab0 (diff)
downloadhqemu-23797df3d9f08031d19aaaa1d2863d5feebe3d8b.zip
hqemu-23797df3d9f08031d19aaaa1d2863d5feebe3d8b.tar.gz
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.c83
1 files changed, 26 insertions, 57 deletions
diff --git a/qemu-coroutine-io.c b/qemu-coroutine-io.c
index 40fd514..5734965 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);
}
OpenPOWER on IntegriCloud