@@ -296,23 +296,52 @@ struct qemu_work_item {
* Receives data into a (part of) iovec from a socket,
* yielding when there is no data in the socket.
* The same interface as qemu_sendv_recvv(), with added yielding.
- * XXX should mark these as coroutine_fn
*/
-ssize_t qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
- size_t offset, size_t bytes, bool do_send);
+#define qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, do_send) \
+ qemu_co_sendv_recvv_timeout(sockfd, iov, iov_cnt, offset, bytes, do_send, \
+ -1)
#define qemu_co_recvv(sockfd, iov, iov_cnt, offset, bytes) \
- qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, false)
+ qemu_co_sendv_recvv_timeout(sockfd, iov, iov_cnt, offset, bytes, false, -1)
#define qemu_co_sendv(sockfd, iov, iov_cnt, offset, bytes) \
- qemu_co_sendv_recvv(sockfd, iov, iov_cnt, offset, bytes, true)
+ qemu_co_sendv_recvv_timeout(sockfd, iov, iov_cnt, offset, bytes, true, -1)
/**
* The same as above, but with just a single buffer
*/
-ssize_t qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send);
+#define qemu_co_send_recv(sockfd, buf, bytes, do_send) \
+ qemu_co_send_recv_timeout(sockfd, buf, bytes, do_send, -1)
#define qemu_co_recv(sockfd, buf, bytes) \
- qemu_co_send_recv(sockfd, buf, bytes, false)
+ qemu_co_send_recv_timeout(sockfd, buf, bytes, false, -1)
#define qemu_co_send(sockfd, buf, bytes) \
- qemu_co_send_recv(sockfd, buf, bytes, true)
+ qemu_co_send_recv_timeout(sockfd, buf, bytes, true, -1)
+
+/**
+ * The same as qemu_co_sendv_recvv(), but allows you to specify a timeout in
+ * nanoseconds.
+ * XXX should mark these as coroutine_fn
+ */
+ssize_t qemu_co_sendv_recvv_timeout(int sockfd, struct iovec *iov,
+ unsigned iov_cnt, size_t offset,
+ size_t bytes, bool do_send,
+ int64_t timeout);
+#define qemu_co_recvv_timeout(sockfd, iov, iov_cnt, offset, bytes, timeout) \
+ qemu_co_sendv_recvv_timeout(sockfd, iov, iov_cnt, offset, bytes, false, \
+ timeout)
+#define qemu_co_sendv_timeout(sockfd, iov, iov_cnt, offset, bytes, timeout) \
+ qemu_co_sendv_recvv_timeout(sockfd, iov, iov_cnt, offset, bytes, true, \
+ timeout)
+
+/**
+ * The same as qemu_co_send_recv(), but allows you to specify a timeout in
+ * nanoseconds.
+ */
+ssize_t qemu_co_send_recv_timeout(int sockfd, void *buf, size_t bytes,
+ bool do_send, int64_t timeout);
+#define qemu_co_recv_timeout(sockfd, buf, bytes, timeout) \
+ qemu_co_send_recv_timeout(sockfd, buf, bytes, false, timeout)
+#define qemu_co_send_timeout(sockfd, buf, bytes, timeout) \
+ qemu_co_send_recv_timeout(sockfd, buf, bytes, true, timeout)
+
typedef struct QEMUIOVector {
struct iovec *iov;
@@ -28,9 +28,10 @@
#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,
- size_t offset, size_t bytes, bool do_send)
+ssize_t coroutine_fn qemu_co_sendv_recvv_timeout(int sockfd, struct iovec *iov,
+ unsigned iov_cnt,
+ size_t offset, size_t bytes,
+ bool do_send, int64_t timeout)
{
size_t done = 0;
ssize_t ret;
@@ -43,7 +44,13 @@ qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
} else if (ret < 0) {
err = socket_error();
if (err == EAGAIN || err == EWOULDBLOCK) {
- qemu_coroutine_yield();
+ if (timeout < 0) {
+ qemu_coroutine_yield();
+ } else {
+ if (co_yield_timeout(QEMU_CLOCK_REALTIME, timeout)) {
+ return -ETIMEDOUT;
+ }
+ }
} else if (done == 0) {
return -err;
} else {
@@ -60,11 +67,13 @@ qemu_co_sendv_recvv(int sockfd, struct iovec *iov, unsigned iov_cnt,
return done;
}
-ssize_t coroutine_fn
-qemu_co_send_recv(int sockfd, void *buf, size_t bytes, bool do_send)
+ssize_t coroutine_fn qemu_co_send_recv_timeout(int sockfd, void *buf,
+ size_t bytes, bool do_send,
+ int64_t timeout)
{
struct iovec iov = { .iov_base = buf, .iov_len = bytes };
- return qemu_co_sendv_recvv(sockfd, &iov, 1, 0, bytes, do_send);
+ return qemu_co_sendv_recvv_timeout(sockfd, &iov, 1, 0, bytes, do_send,
+ timeout);
}
typedef struct {
Signed-off-by: Max Reitz <mreitz@redhat.com> --- include/qemu-common.h | 45 +++++++++++++++++++++++++++++++++++++-------- qemu-coroutine-io.c | 23 ++++++++++++++++------- 2 files changed, 53 insertions(+), 15 deletions(-)