[Spice-commits] server/stream-device.c
Frediano Ziglio
fziglio at kemper.freedesktop.org
Fri Feb 16 22:19:05 UTC 2018
server/stream-device.c | 29 ++++++++++++++++++++++++-----
1 file changed, 24 insertions(+), 5 deletions(-)
New commits:
commit ebdda84dc145d7c6815a19d6b554bddabb6a0dfd
Author: Frediano Ziglio <fziglio at redhat.com>
Date: Thu Jan 11 11:41:49 2018 +0000
stream-device: Avoid device to get stuck if multiple messages are batched
If messages are sent together by the agent the device is reading
only part of the data. This cause Qemu to not poll for new data and
stream_device_read_msg_from_dev won't be called again.
This can cause a stall. To avoid this continue handling data
after a full message was processed.
Signed-off-by: Frediano Ziglio <fziglio at redhat.com>
Acked-by: Jonathon Jongsma <jjongsma at redhat.com>
diff --git a/server/stream-device.c b/server/stream-device.c
index 4eaa959b..3a7cb306 100644
--- a/server/stream-device.c
+++ b/server/stream-device.c
@@ -71,16 +71,15 @@ static StreamMsgHandler handle_msg_format, handle_msg_data;
static bool handle_msg_invalid(StreamDevice *dev, SpiceCharDeviceInstance *sin,
const char *error_msg) SPICE_GNUC_WARN_UNUSED_RESULT;
-static RedPipeItem *
-stream_device_read_msg_from_dev(RedCharDevice *self, SpiceCharDeviceInstance *sin)
+static bool
+stream_device_partial_read(StreamDevice *dev, SpiceCharDeviceInstance *sin)
{
- StreamDevice *dev = STREAM_DEVICE(self);
SpiceCharDeviceInterface *sif;
int n;
bool handled = false;
if (dev->has_error || dev->flow_stopped || !dev->stream_channel) {
- return NULL;
+ return false;
}
sif = spice_char_device_get_interface(sin);
@@ -89,7 +88,7 @@ stream_device_read_msg_from_dev(RedCharDevice *self, SpiceCharDeviceInstance *si
while (dev->hdr_pos < sizeof(dev->hdr)) {
n = sif->read(sin, (uint8_t *) &dev->hdr + dev->hdr_pos, sizeof(dev->hdr) - dev->hdr_pos);
if (n <= 0) {
- return NULL;
+ return false;
}
dev->hdr_pos += n;
if (dev->hdr_pos >= sizeof(dev->hdr)) {
@@ -123,6 +122,26 @@ stream_device_read_msg_from_dev(RedCharDevice *self, SpiceCharDeviceInstance *si
dev->hdr_pos = 0;
}
+ if (handled || dev->has_error) {
+ // Qemu put the device on blocking state if we don't read all data
+ // so schedule another read.
+ // We arrive here if we processed that entire message or we
+ // got an error, try to read another message or discard the
+ // wrong data
+ return true;
+ }
+
+ return false;
+}
+
+static RedPipeItem *
+stream_device_read_msg_from_dev(RedCharDevice *self, SpiceCharDeviceInstance *sin)
+{
+ StreamDevice *dev = STREAM_DEVICE(self);
+
+ while (stream_device_partial_read(dev, sin)) {
+ continue;
+ }
return NULL;
}
More information about the Spice-commits
mailing list