summaryrefslogtreecommitdiffstats
path: root/auto-virtserial.c
diff options
context:
space:
mode:
Diffstat (limited to 'auto-virtserial.c')
-rw-r--r--auto-virtserial.c62
1 files changed, 61 insertions, 1 deletions
diff --git a/auto-virtserial.c b/auto-virtserial.c
index 4b346f6..df0efd6 100644
--- a/auto-virtserial.c
+++ b/auto-virtserial.c
@@ -568,9 +568,69 @@ out:
return err;
}
+/*
+ * Similar to test_nonblocking_write(): open guest port, write
+ * lots of data. We should be put to sleep once the host
+ * can't accept any more data. Then read some data from host,
+ * we should be writable again.
+ */
static int test_blocking_write(int nr)
{
- return 0;
+ void *buf;
+ unsigned int i;
+ int err, ret;
+
+ ret = guest_open_port(nr);
+ err = result(__func__, true, "guest open", ret, -1, -1, OP_GT, false);
+ if (err)
+ return err;
+
+ host_connect_chardev(nr);
+
+ /*
+ * We currently have 128 buffers in a virtqueue --
+ * hw/virtio-serial-bus.c, so this while loop should stop when
+ * i is 128. However, the loop actually stops when i is 158
+ * -- the qemu chardev itself can buffer some data.
+ */
+ for (i = 0; i < 200; i++) {
+ ret = guest_poll(nr, 0, 0);
+ if (i && ret == 0) {
+ /* vq full. Next write will block. */
+ break;
+ }
+ err = result(__func__, true, "guest poll", ret,
+ POLLOUT, POLLOUT, OP_EQ, false);
+ if (err)
+ goto out;
+
+ ret = guest_write(nr, BUF_LENGTH);
+ err = result(__func__, true, "guest write",
+ ret, BUF_LENGTH, BUF_LENGTH, OP_EQ, false);
+ if (err)
+ goto out;
+ }
+
+ buf = malloc(BUF_LENGTH);
+ for (i = 0; i < 32; i++) {
+ /*
+ * One last thing: read out some buffers from host
+ * (more than the qemu-chardev buffer limit). See if
+ * guest gets POLLOUT set.
+ */
+ read(chardevs[nr].sock, buf, BUF_LENGTH);
+ }
+ free(buf);
+
+ sleep(2);
+
+ ret = guest_poll(nr, 0, 0);
+ err = result(__func__, true, "read-poll",
+ ret, POLLOUT, POLLOUT, OP_EQ, true);
+out:
+ host_close_chardev(nr);
+ guest_close_port(nr);
+ return err;
}
static int test_nonblocking_write(int nr)