[virt-tools-list] [PATCH virt-viewer] spice: use weak references to display channel

Marc-André Lureau marcandre.lureau at gmail.com
Thu May 17 17:04:26 UTC 2012


Fix switch-host migration with Spice.

spice-gtk doesn't like channels staying around when they should be
destroyed/finalized, ie removed from session.

spice-gtk should probably learned to handle better the case of non
cooperating clients, and be able to dissociate a channel from a
session without waiting for it to be disposed, but for now, the
relation is quite tight.
---
 src/virt-viewer-display-spice.c |   17 +++++++++--------
 src/virt-viewer-display-spice.h |    4 +---
 src/virt-viewer-session-spice.c |   11 ++++++-----
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/src/virt-viewer-display-spice.c b/src/virt-viewer-display-spice.c
index f7bb26d..0b6949b 100644
--- a/src/virt-viewer-display-spice.c
+++ b/src/virt-viewer-display-spice.c
@@ -35,7 +35,7 @@
 G_DEFINE_TYPE (VirtViewerDisplaySpice, virt_viewer_display_spice, VIRT_VIEWER_TYPE_DISPLAY)
 
 struct _VirtViewerDisplaySpicePrivate {
-    SpiceChannel *channel;
+    SpiceChannel *channel; /* weak reference */
     SpiceDisplay *display;
 };
 
@@ -54,7 +54,6 @@ virt_viewer_display_spice_finalize(GObject *obj)
     VirtViewerDisplaySpice *spice = VIRT_VIEWER_DISPLAY_SPICE(obj);
 
     g_object_unref(spice->priv->display);
-    g_object_unref(spice->priv->channel);
 
     G_OBJECT_CLASS(virt_viewer_display_spice_parent_class)->finalize(obj);
 }
@@ -199,15 +198,14 @@ enable_accel_changed(VirtViewerApp *app,
 
 GtkWidget *
 virt_viewer_display_spice_new(VirtViewerSessionSpice *session,
-                              SpiceChannel *channel,
-                              SpiceDisplay *display)
+                              SpiceChannel *channel)
 {
     VirtViewerDisplaySpice *self;
     VirtViewerApp *app;
     gint channelid;
+    SpiceSession *s;
 
     g_return_val_if_fail(SPICE_IS_DISPLAY_CHANNEL(channel), NULL);
-    g_return_val_if_fail(SPICE_IS_DISPLAY(display), NULL);
 
     g_object_get(channel, "channel-id", &channelid, NULL);
 
@@ -215,15 +213,18 @@ virt_viewer_display_spice_new(VirtViewerSessionSpice *session,
                         "session", session,
                         "nth-display", channelid,
                         NULL);
-    self->priv->channel = g_object_ref(channel);
-    self->priv->display = g_object_ref(display);
+    self->priv->channel = channel;
+
+    g_object_get(session, "spice-session", &s, NULL);
+    self->priv->display = spice_display_new(s, channelid);
+    g_object_unref(s);
 
     g_signal_connect(channel, "display-primary-create",
                      G_CALLBACK(primary_create), self);
     g_signal_connect(channel, "display-mark",
                      G_CALLBACK(display_mark), self);
 
-    gtk_container_add(GTK_CONTAINER(self), GTK_WIDGET(self->priv->display));
+    gtk_container_add(GTK_CONTAINER(self), g_object_ref(self->priv->display));
     gtk_widget_show(GTK_WIDGET(self->priv->display));
     g_object_set(self->priv->display,
                  "grab-keyboard", TRUE,
diff --git a/src/virt-viewer-display-spice.h b/src/virt-viewer-display-spice.h
index eecc03e..701ed85 100644
--- a/src/virt-viewer-display-spice.h
+++ b/src/virt-viewer-display-spice.h
@@ -66,9 +66,7 @@ struct _VirtViewerDisplaySpiceClass {
 
 GType virt_viewer_display_spice_get_type(void);
 
-GtkWidget* virt_viewer_display_spice_new(VirtViewerSessionSpice *session,
-                                         SpiceChannel *channel,
-                                         SpiceDisplay *display);
+GtkWidget* virt_viewer_display_spice_new(VirtViewerSessionSpice *session, SpiceChannel *channel);
 
 G_END_DECLS
 
diff --git a/src/virt-viewer-session-spice.c b/src/virt-viewer-session-spice.c
index d11d7a1..c9ba9e2 100644
--- a/src/virt-viewer-session-spice.c
+++ b/src/virt-viewer-session-spice.c
@@ -448,10 +448,8 @@ virt_viewer_session_spice_channel_new(SpiceSession *s,
         g_signal_emit_by_name(session, "session-connected");
 
         DEBUG_LOG("new display channel (#%d)", id);
-        display = virt_viewer_display_spice_new(self,
-                                                channel,
-                                                spice_display_new(s, id));
-
+        display = virt_viewer_display_spice_new(self, channel);
+        g_object_set_data(G_OBJECT(channel), "virt-viewer-display", display);
         virt_viewer_session_add_display(VIRT_VIEWER_SESSION(session),
                                         VIRT_VIEWER_DISPLAY(display));
 
@@ -533,7 +531,10 @@ virt_viewer_session_spice_channel_destroy(G_GNUC_UNUSED SpiceSession *s,
     }
 
     if (SPICE_IS_DISPLAY_CHANNEL(channel)) {
-        DEBUG_LOG("zap session channel (#%d)", id);
+        VirtViewerDisplay *display = g_object_get_data(G_OBJECT(channel), "virt-viewer-display");
+        DEBUG_LOG("zap display channel (#%d, %p)", id, display);
+        virt_viewer_session_remove_display(session, display);
+        G_BREAKPOINT();
     }
 
     if (SPICE_IS_PLAYBACK_CHANNEL(channel) && self->priv->audio) {
-- 
1.7.10.1




More information about the virt-tools-list mailing list