[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