[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[virt-tools-list] [PATCH 08/11] session-spice: Delay the disconnected signal till all channels are closed

Before this patch session-spice would emit the disconnected signal as soon
as the main channel is closed, but other channels may still be open at
that time and raising the disconnected signal usally leads to the app class
calling gtk_main_quit, at which point the other channels never get properly
finalized (as there co-routines still hold a reference to them).

This is esp. bad for usbredir channels as these re-attach the kernel driver
for redirected devices when finalized. So exiting without properly finalizing
them leads to the formerly redirected devices not being usuable until the
driver is manually reloaded or the device is unplugged and re-plugged
(the kernel does not automatically re-bind kernel drivers when userspace
 closes a usbfs node).

This patch fixes this by delaying the emitting of the disconnect signal
until the last channel has been destroyed.

Signed-off-by: Hans de Goede <hdegoede redhat com>
 src/virt-viewer-session-spice.c |   17 +++++++++++++----
 1 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index 3250abd..a4b3a1f 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -48,6 +48,7 @@ struct _VirtViewerSessionSpicePrivate {
     SpiceGtkSession *gtk_session;
     SpiceMainChannel *main_channel;
     SpiceAudio *audio;
+    int channel_count;
@@ -301,7 +302,10 @@ virt_viewer_session_spice_main_channel_event(SpiceChannel *channel G_GNUC_UNUSED
         DEBUG_LOG("main channel: closed");
-        g_signal_emit_by_name(session, "session-disconnected");
+        /* Ensure the other channels get closed too */
+        virt_viewer_session_clear_displays(session);
+        if (self->priv->session)
+            spice_session_disconnect(self->priv->session);
         DEBUG_LOG("main channel: failed to connect");
@@ -436,10 +440,11 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
     if (SPICE_IS_PLAYBACK_CHANNEL(channel)) {
         DEBUG_LOG("new audio channel");
-        if (self->priv->audio != NULL)
-            return;
-        self->priv->audio = spice_audio_new(s, NULL, NULL);
+        if (self->priv->audio == NULL)
+            self->priv->audio = spice_audio_new(s, NULL, NULL);
+    self->priv->channel_count++;
 static void
@@ -468,6 +473,10 @@ virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s,
         self->priv->audio = NULL;
+    self->priv->channel_count--;
+    if (self->priv->channel_count == 0)
+        g_signal_emit_by_name(self, "session-disconnected");
 VirtViewerSession *

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]