summaryrefslogtreecommitdiffstats
path: root/server/reds.c
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-03-04 13:15:26 +0200
committerAlon Levy <alevy@redhat.com>2011-03-08 21:49:21 +0200
commit5315888a706e9eea30046139cb1054ae63e1cc0e (patch)
treedb5d26746707b16afd97514a977da9d9ead83b9d /server/reds.c
parente1ec222e8bdf4b02f511666656ce1d6bd60d0988 (diff)
downloadspice-5315888a706e9eea30046139cb1054ae63e1cc0e.tar.gz
spice-5315888a706e9eea30046139cb1054ae63e1cc0e.tar.xz
spice-5315888a706e9eea30046139cb1054ae63e1cc0e.zip
server/reds: allow call to reds_agent_remove even if it is gone
The current assert(reds->agent_state.connected) tiggers if when the agent disconnected there was still data waiting to be sent (for instance if there is a bug in the client handling clipboard and it is killed while a large clipboard transfer is in progress). So first call to reds_agent_remove happens from spice_server_char_device_remove_interface, and then it is called again (triggering the assert) from free_item_data from read_from_vdi_port because of the channel destruction. Other option would be to not call it from one of the paths - but that is suboptimal: * if there is no data in the pipe, the second call never happens. * the second call has to be there anyway, because it may fail during parsing data from the agent. This patch fixes a segfault on this assert when a client starts passing from guest agent to client a large clipboard and dies in the middle. There is still another assert happening occasionally at marshaller which I don't have a fix for (but it doesn't seem to be related).
Diffstat (limited to 'server/reds.c')
-rw-r--r--server/reds.c8
1 files changed, 4 insertions, 4 deletions
diff --git a/server/reds.c b/server/reds.c
index 7845ebe7..508c8ff9 100644
--- a/server/reds.c
+++ b/server/reds.c
@@ -1095,16 +1095,17 @@ static void reds_agent_remove()
SpiceCharDeviceInstance *sin = vdagent;
SpiceCharDeviceInterface *sif;
+ if (!reds->agent_state.connected) {
+ return;
+ }
+ reds->agent_state.connected = 0;
vdagent = NULL;
reds_update_mouse_mode();
if (!reds->peer || !sin) {
return;
}
-
- ASSERT(reds->agent_state.connected)
sif = SPICE_CONTAINEROF(sin->base.sif, SpiceCharDeviceInterface, base);
- reds->agent_state.connected = 0;
if (sif->state) {
sif->state(sin, reds->agent_state.connected);
}
@@ -1112,7 +1113,6 @@ static void reds_agent_remove()
if (reds->mig_target) {
return;
}
-
reds_reset_vdp();
reds_send_agent_disconnected();
}