aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorMORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp>2012-06-27 07:26:19 +0900
committerKevin Wolf <kwolf@redhat.com>2012-07-09 15:53:01 +0200
commit2dfcca3b6828052cadd30c66a1a840bf0fc6670c (patch)
tree36dfce66ee8d618a1969a53f78b0236a451b67d2 /block
parent1b6ac9985aba27142d7dd6460bf20fc6ade92c00 (diff)
downloadqemu-2dfcca3b6828052cadd30c66a1a840bf0fc6670c.zip
qemu-2dfcca3b6828052cadd30c66a1a840bf0fc6670c.tar.gz
qemu-2dfcca3b6828052cadd30c66a1a840bf0fc6670c.tar.bz2
sheepdog: restart I/O when socket becomes ready in do_co_req()
Currently, no one reenters the yielded coroutine. This fixes it. Signed-off-by: MORITA Kazutaka <morita.kazutaka@lab.ntt.co.jp> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/sheepdog.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/block/sheepdog.c b/block/sheepdog.c
index afd06aa..0b49c6d 100644
--- a/block/sheepdog.c
+++ b/block/sheepdog.c
@@ -577,10 +577,21 @@ out:
return ret;
}
+static void restart_co_req(void *opaque)
+{
+ Coroutine *co = opaque;
+
+ qemu_coroutine_enter(co, NULL);
+}
+
static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
unsigned int *wlen, unsigned int *rlen)
{
int ret;
+ Coroutine *co;
+
+ co = qemu_coroutine_self();
+ qemu_aio_set_fd_handler(sockfd, NULL, restart_co_req, NULL, co);
socket_set_block(sockfd);
ret = send_co_req(sockfd, hdr, data, wlen);
@@ -588,6 +599,8 @@ static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
goto out;
}
+ qemu_aio_set_fd_handler(sockfd, restart_co_req, NULL, NULL, co);
+
ret = qemu_co_recv(sockfd, hdr, sizeof(*hdr));
if (ret < sizeof(*hdr)) {
error_report("failed to get a rsp, %s", strerror(errno));
@@ -609,6 +622,7 @@ static coroutine_fn int do_co_req(int sockfd, SheepdogReq *hdr, void *data,
}
ret = 0;
out:
+ qemu_aio_set_fd_handler(sockfd, NULL, NULL, NULL, NULL);
socket_set_nonblock(sockfd);
return ret;
}