summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarc-André Lureau <marcandre.lureau@gmail.com>2012-05-17 18:18:20 +0200
committerMarc-André Lureau <marcandre.lureau@gmail.com>2012-05-17 19:12:35 +0200
commit0341125ca4dd77b58de0d0a580a0bc4515a59332 (patch)
tree5b13c88b95483f77e52635de85c14a454ab803c5
parent163b6853323780042a5486bc0ebb46945a4ab9a0 (diff)
spice: use weak references to display channel
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.
-rw-r--r--src/virt-viewer-display-spice.c17
-rw-r--r--src/virt-viewer-display-spice.h4
-rw-r--r--src/virt-viewer-session-spice.c10
3 files changed, 15 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..4a8c9cf 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,9 @@ 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);
}
if (SPICE_IS_PLAYBACK_CHANNEL(channel) && self->priv->audio) {